圖片
在實(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ù)庫(kù)設(shè)置的時(shí)區(qū),還有服務(wù)端設(shè)置的時(shí)區(qū),還包括在使用數(shù)據(jù)庫(kù)配置時(shí)指定的時(shí)區(qū)。這些條件綜合發(fā)生時(shí)才會(huì)出現(xiàn)事故。
接下來,小傅哥就給大家分享下為啥是 8.0.22 版本才會(huì)引發(fā)時(shí)區(qū)錯(cuò)誤問題。
這是一條很普通的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語句;
圖片
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version></dependency>
jdbc:mysql://127.0.0.1:3306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true
show variables like '%time_zone%';+------------------+--------+| Variable_name | Value |+------------------+--------+| system_time_zone | CST || time_zone | SYSTEM |+------------------+--------+
美國(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
[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: yesNTP 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
在 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.23 版本以后,如果未配置時(shí)區(qū),調(diào)整為獲取客戶端時(shí)區(qū)。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version></dependency>
com.mysql.cj.protocol.a.NativeProtocol#configureTimezone
圖片
地址: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)
在使用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
本文鏈接:http://www.tebozhan.com/showinfo-26-112721-0.html是什么導(dǎo)致了,寫入MySQL庫(kù)表時(shí)間不正確?—— 官網(wǎng)也有Bug!
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: 什么是內(nèi)存溢出,Golang是如何解決內(nèi)存溢出的
下一篇: 盤點(diǎn)分頁查詢中遇到的坑!