成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

是什么導(dǎo)致了,寫入MySQL庫表時(shí)間不正確?—— 官網(wǎng)也有Bug!

開發(fā) 前端
在使用MySQL的時(shí)候,確保服務(wù)器時(shí)區(qū)、MySQL時(shí)區(qū)、Java應(yīng)用鏈接MySQL JDBC的參數(shù)配置,都指定到具體的時(shí)區(qū)上。MySQL JDBC 使用 8.0.23+ 版本,不要使用 8.0.0 ~ 8.0.22 版本,尤其是5.1升級(jí)要升級(jí)到 8.0.23 以及往后的版本。

圖片圖片

在實(shí)際的工作場(chǎng)景中有時(shí)候就是一個(gè)小小的問題,就可能引發(fā)出一個(gè)大大的bug。而且工作這么多年,看到的線上事故,往往也都是這些小的細(xì)節(jié)問題,所以學(xué)習(xí)這些具有實(shí)際經(jīng)驗(yàn)的細(xì)節(jié)非常重要。

有些事故隱藏的很深!

其實(shí)很多時(shí)候事故也不是一開始就有的,而是隨著需求的迭代,達(dá)到某一個(gè)條件后觸達(dá)到事故的發(fā)生條件了才出現(xiàn)的。就像 MySQL 的時(shí)區(qū)配置問題,它既有不同版本 JDBC 連接引擎的不同,又有數(shù)據(jù)庫設(shè)置的時(shí)區(qū),還有服務(wù)端設(shè)置的時(shí)區(qū),還包括在使用數(shù)據(jù)庫配置時(shí)指定的時(shí)區(qū)。這些條件綜合發(fā)生時(shí)才會(huì)出現(xiàn)事故。

接下來,小傅哥就給大家分享下為啥是 8.0.22 版本才會(huì)引發(fā)時(shí)區(qū)錯(cuò)誤問題。

一、問題場(chǎng)景

這是一條很普通的SQL語句;

<insert id="insert" parameterType="cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeePO">
    INSERT INTO employee(employee_number, employee_name, employee_level, employee_title, create_time, update_time)
    VALUES(#{employeeNumber}, #{employeeName}, #{employeeLevel}, #{employeeTitle}, now(), now())
</insert>

修改下這條普通的SQL語句;

<insert id="insert" parameterType="cn.bugstack.xfg.dev.tech.infrastructure.po.EmployeePO">
    INSERT INTO employee(employee_number, employee_name, employee_level, employee_title, create_time, update_time)
    VALUES(#{employeeNumber}, #{employeeName}, #{employeeLevel}, #{employeeTitle}, #{createTime}, now())
</insert>

接下來在執(zhí)行插入SQL語句;

圖片圖片

  • 原本直接使用數(shù)據(jù)庫語句 now() 的并沒有問題,而改為由程序透?jìng)鞯臅r(shí)間 createTime 后,日期時(shí)間發(fā)生了錯(cuò)誤。差了8個(gè)小時(shí)。
  • 通常一般我們操作數(shù)據(jù)庫的時(shí)候,寫入的時(shí)間,往往都是 now()。但有時(shí)候比如要外部透?jìng)饔脩粝聠螘r(shí)間做本系統(tǒng)做一個(gè)返利活動(dòng),在什么時(shí)間內(nèi)才返利,要記錄時(shí)間。這個(gè)時(shí)候發(fā)現(xiàn)寫入數(shù)據(jù)庫的時(shí)間就不對(duì)了。
  • 因?yàn)樵灸愕南到y(tǒng)都是走的數(shù)據(jù)庫時(shí)間,現(xiàn)在突然多了一個(gè)來自系統(tǒng)的透?jìng)鲿r(shí)間,那么你可能是注意不到的。另外由于本機(jī)的開發(fā)環(huán)境與服務(wù)器配置不一樣,所以最終直至上線開始跑數(shù)據(jù)了,才發(fā)現(xiàn)問題。這個(gè)就是一般出現(xiàn)事故的原因。

二、排查配置

1. mysql jdbc 版本

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.22</version>
</dependency>
  • 8.0.22 版本,官網(wǎng)提示有bug;https://dev.mysql.com/doc/relnotes/connector-j/en/news-8-0-23.html

2. 鏈接參數(shù)配置

jdbc:mysql://127.0.0.1:3306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true
  • 注意首次沒有配置時(shí)區(qū)。配置時(shí)區(qū)需要增加參數(shù);&serverTimeznotallow=Asia/Shanghai

3. mysql time-zone 配置

show variables like '%time_zone%';

+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
  • 命令修改時(shí)區(qū);SET time_zone = 'SYSTEM';
  • 命令修改時(shí)區(qū);SET time_zone = '+8:00';
  • 注意CST配置,不是中國(guó)時(shí)區(qū)。默認(rèn)是美國(guó)中部時(shí)間。

美國(guó)中部時(shí)間 Central Standard Time (USA) UTC-05:00 或 UTC-06:00

澳大利亞中部時(shí)間 Central Standard Time (Australia) UTC+09:30

中國(guó)標(biāo)準(zhǔn)時(shí) China Standard Time UTC+08:00

古巴標(biāo)準(zhǔn)時(shí) Cuba Standard Time UTC-04:00

4. linux 服務(wù)器時(shí)間

[root@lavm-aqhgp9nber ~]# timedatectl
      Local time: Sat 2024-08-31 13:57:07 CST
  Universal time: Sat 2024-08-31 05:57:07 UTC
        RTC time: Sat 2024-08-31 05:57:06
       Time zone: Asia/Shanghai (CST, +0800)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

命令修改時(shí)區(qū);sudo timedatectl set-timezone Asia/Shanghai

命令修改時(shí)區(qū);sudo timedatectl set-timezone America/New_York

三、源碼問題 - MySQL JDBC

1. 8.0.22 版本問題

在 8.0.0 ~ 8.0.22 版本中,如果未配置時(shí)區(qū),serverTimeznotallow=Asia/Shanghai 則會(huì)取服務(wù)端時(shí)區(qū),所以如果服務(wù)端配置的是 CST 時(shí)區(qū),則會(huì)有問題。調(diào)試源碼;

com.mysql.cj.protocol.a.NativeProtocol#configureTimezone

圖片圖片

  • 在 8.0.22 版本中,獲取時(shí)區(qū)的方法,如果本地為配置 jdbc 時(shí)區(qū),則會(huì)獲取服務(wù)端時(shí)區(qū)。也就是 CST 美國(guó)中部時(shí)間。
  • 所以,如果你要使用的是 8.0.22 就必須指定時(shí)區(qū)。jdbc:mysql://IP:13306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimeznotallow=Asia/Shanghai

2. 8.0.23 + 版本

在 8.0.23 版本以后,如果未配置時(shí)區(qū),調(diào)整為獲取客戶端時(shí)區(qū)。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>
  • 切換到 8.0.23 版本。

com.mysql.cj.protocol.a.NativeProtocol#configureTimezone

圖片圖片

  • 在使用 8.0.23 TimeZone.getDefault() 注釋 Gets the default TimeZone of the Java virtual machine. 獲取 Java 虛擬機(jī)默認(rèn)時(shí)區(qū)。這個(gè)方法也是 Java 本身代碼的方法。
  • 你可以通過 Java Main 函數(shù)執(zhí)行 System.*out*.println("Default Time Zone: " + TimeZone.getDefault().getID()); 獲取默認(rèn)時(shí)區(qū)。打印結(jié)果為 Default Time Zone: Asia/Shanghai

3. 官網(wǎng)說明

地址:https://dev.mysql.com/doc/relnotes/connector-j/en/news-8-0-23.html

Bugs Fixed

After upgrading from Connector/J 5.1 to 8.0, the results of saving and then retrieving DATETIME and TIMESTAMP values became different sometimes. It was because while Connector/J 5.1 does not preserve a time instant by default, Connector/J 8.0.22 and earlier tried to do so by converting a timestamp to the server's session time zone before sending its value to the server. In this release, new mechanisms for controlling timezone conversion has been introduced—see Preserving Time Instants for details. Under this new mechanism, the default behavior of Connector/J 5.1 in this respect is preserved by setting the connection property preserveInstants=false. (Bug #30962953, Bug #98695, Bug #30573281, Bug #95644)

從 Connector/J 5.1 升級(jí)到 8.0 后,保存和檢索 DATETIME 和 TIMESTAMP 值的結(jié)果有時(shí)會(huì)有所不同。這是因?yàn)椋m然 Connector/J 5.1 默認(rèn)不保留時(shí)間點(diǎn),但 Connector/J 8.0.22 及更早版本嘗試通過在將時(shí)間戳的值發(fā)送到服務(wù)器之前將其轉(zhuǎn)換為服務(wù)器的會(huì)話時(shí)區(qū)來保留時(shí)間點(diǎn)。在此版本中,引入了用于控制時(shí)區(qū)轉(zhuǎn)換的新機(jī)制 - 有關(guān)詳細(xì)信息,請(qǐng)參閱保留時(shí)間點(diǎn)。在這種新機(jī)制下,通過設(shè)置連接屬性 retainInstants=false 來保留 Connector/J 5.1 在這方面的默認(rèn)行為。(錯(cuò)誤 #30962953、錯(cuò)誤 #98695、錯(cuò)誤 #30573281、錯(cuò)誤 #95644)

四、綜上總結(jié)

在使用MySQL的時(shí)候,確保服務(wù)器時(shí)區(qū)、MySQL時(shí)區(qū)、Java應(yīng)用鏈接MySQL JDBC的參數(shù)配置,都指定到具體的時(shí)區(qū)上。MySQL JDBC 使用 8.0.23+ 版本,不要使用 8.0.0 ~ 8.0.22 版本,尤其是5.1升級(jí)要升級(jí)到 8.0.23 以及往后的版本。

正確配置;url: jdbc:mysql://127.0.0.1:3306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimeznotallow=Asia/Shanghai

責(zé)任編輯:武曉燕 來源: bugstack蟲洞棧
相關(guān)推薦

2013-09-09 10:51:07

CSSIE瀏覽器

2012-10-15 18:19:25

打印機(jī)打印機(jī)安裝

2023-03-16 23:54:19

服務(wù)器vmtoolsd組件

2022-04-28 11:12:15

芯片

2015-07-31 10:16:05

Windows 10Bug

2023-04-23 14:09:28

2018-04-09 09:04:59

固態(tài)硬盤映射表

2011-07-29 16:55:44

Java 7

2011-08-17 13:18:39

Oracle 10g配SID

2022-06-02 11:13:20

首席信息官數(shù)字化轉(zhuǎn)型企業(yè)

2009-12-28 08:54:58

ADO錯(cuò)誤

2017-09-05 14:59:34

2016-12-12 13:07:57

數(shù)據(jù)庫優(yōu)化SQL

2020-10-05 21:33:15

隱私數(shù)據(jù)匿名數(shù)據(jù)安全

2024-12-25 16:04:53

2020-09-02 07:05:56

手機(jī)支付

2010-12-28 15:58:46

Microsoft S

2024-03-26 09:29:27

MySQLDDL

2022-12-09 09:43:41

前端測(cè)試

2022-06-15 07:32:24

數(shù)據(jù)庫分庫分表
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 免费在线a视频 | 国产精品久久久久婷婷二区次 | av网站免费在线观看 | 成人av免费| 91麻豆精品国产91久久久更新资源速度超快 | 91人人看 | 成人一区二区视频 | 欧美日本在线 | 欧美一二三| 五月天国产在线 | 久色网| 国产成人自拍av | 五月婷婷激情网 | av网站在线免费观看 | 毛片99 | 亚洲视频一区二区三区 | 亚洲a人| 午夜久久久久 | 中文字幕亚洲视频 | 国产精品国产精品国产专区不卡 | 日韩视频一区二区在线 | 久久精品成人 | 天天草天天干 | 国产精品不卡一区 | 黄色毛片免费视频 | 日本一区二区不卡视频 | 色综合久 | 日韩图区| 国产一区二区欧美 | 一级一级一级毛片 | 99久热在线精品视频观看 | 99久久亚洲 | 欧美久久一区二区三区 | 免费久久久 | 欧美日韩国产高清视频 | 久久亚洲高清 | 成人毛片视频免费 | 国产一级特黄真人毛片 | 亚洲欧美国产精品久久 | 亚洲成人一区二区三区 | 国产成人高清 |