当前位置:首页 > 科技  > 软件

是什么导致了,写入MySQL库表时间不正确?—— 官网也有Bug!

来源: 责编: 时间:2024-09-10 09:46:53 197观看
导读图片在实际的工作场景中有时候就是一个小小的问题,就可能引发出一个大大的bug。而且工作这么多年,看到的线上事故,往往也都是这些小的细节问题,所以学习这些具有实际经验的细节非常重要。有些事故隐藏的很深!其实很多时候

图片图片aVa28资讯网——每日最新资讯28at.com

在实际的工作场景中有时候就是一个小小的问题,就可能引发出一个大大的bug。而且工作这么多年,看到的线上事故,往往也都是这些小的细节问题,所以学习这些具有实际经验的细节非常重要。aVa28资讯网——每日最新资讯28at.com

有些事故隐藏的很深!aVa28资讯网——每日最新资讯28at.com

其实很多时候事故也不是一开始就有的,而是随着需求的迭代,达到某一个条件后触达到事故的发生条件了才出现的。就像 MySQL 的时区配置问题,它既有不同版本 JDBC 连接引擎的不同,又有数据库设置的时区,还有服务端设置的时区,还包括在使用数据库配置时指定的时区。这些条件综合发生时才会出现事故。aVa28资讯网——每日最新资讯28at.com

接下来,小傅哥就给大家分享下为啥是 8.0.22 版本才会引发时区错误问题。aVa28资讯网——每日最新资讯28at.com

一、问题场景

这是一条很普通的SQL语句;aVa28资讯网——每日最新资讯28at.com

<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语句;aVa28资讯网——每日最新资讯28at.com

<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>

接下来在执行插入SQL语句;aVa28资讯网——每日最新资讯28at.com

图片图片aVa28资讯网——每日最新资讯28at.com

  • 原本直接使用数据库语句 now() 的并没有问题,而改为由程序透传的时间 createTime 后,日期时间发生了错误。差了8个小时。
  • 通常一般我们操作数据库的时候,写入的时间,往往都是 now()。但有时候比如要外部透传用户下单时间做本系统做一个返利活动,在什么时间内才返利,要记录时间。这个时候发现写入数据库的时间就不对了。
  • 因为原本你的系统都是走的数据库时间,现在突然多了一个来自系统的透传时间,那么你可能是注意不到的。另外由于本机的开发环境与服务器配置不一样,所以最终直至上线开始跑数据了,才发现问题。这个就是一般出现事故的原因。

二、排查配置

1. mysql jdbc 版本

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

2. 链接参数配置

jdbc:mysql://127.0.0.1:3306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true
  • 注意首次没有配置时区。配置时区需要增加参数;&serverTimeznotallow=Asia/Shanghai

3. mysql time-zone 配置

show variables like '%time_zone%';+------------------+--------+| Variable_name    | Value  |+------------------+--------+| system_time_zone | CST    || time_zone        | SYSTEM |+------------------+--------+
  • 命令修改时区;SET time_zone = 'SYSTEM';
  • 命令修改时区;SET time_zone = '+8:00';
  • 注意CST配置,不是中国时区。默认是美国中部时间。

美国中部时间 Central Standard Time (USA) UTC-05:00 或 UTC-06:00aVa28资讯网——每日最新资讯28at.com

澳大利亚中部时间 Central Standard Time (Australia) UTC+09:30aVa28资讯网——每日最新资讯28at.com

中国标准时 China Standard Time UTC+08:00aVa28资讯网——每日最新资讯28at.com

古巴标准时 Cuba Standard Time UTC-04:00aVa28资讯网——每日最新资讯28at.com

4. linux 服务器时间

[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

命令修改时区;sudo timedatectl set-timezone Asia/ShanghaiaVa28资讯网——每日最新资讯28at.com

命令修改时区;sudo timedatectl set-timezone America/New_YorkaVa28资讯网——每日最新资讯28at.com

三、源码问题 - MySQL JDBC

1. 8.0.22 版本问题

在 8.0.0 ~ 8.0.22 版本中,如果未配置时区,serverTimeznotallow=Asia/Shanghai 则会取服务端时区,所以如果服务端配置的是 CST 时区,则会有问题。调试源码;aVa28资讯网——每日最新资讯28at.com

com.mysql.cj.protocol.a.NativeProtocol#configureTimezoneaVa28资讯网——每日最新资讯28at.com

图片图片aVa28资讯网——每日最新资讯28at.com

  • 在 8.0.22 版本中,获取时区的方法,如果本地为配置 jdbc 时区,则会获取服务端时区。也就是 CST 美国中部时间。
  • 所以,如果你要使用的是 8.0.22 就必须指定时区。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 版本以后,如果未配置时区,调整为获取客户端时区。aVa28资讯网——每日最新资讯28at.com

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

com.mysql.cj.protocol.a.NativeProtocol#configureTimezoneaVa28资讯网——每日最新资讯28at.com

图片图片aVa28资讯网——每日最新资讯28at.com

  • 在使用 8.0.23 TimeZone.getDefault() 注释 Gets the default TimeZone of the Java virtual machine. 获取 Java 虚拟机默认时区。这个方法也是 Java 本身代码的方法。
  • 你可以通过 Java Main 函数执行 System.*out*.println("Default Time Zone: " + TimeZone.getDefault().getID()); 获取默认时区。打印结果为 Default Time Zone: Asia/Shanghai

3. 官网说明

地址:https://dev.mysql.com/doc/relnotes/connector-j/en/news-8-0-23.htmlaVa28资讯网——每日最新资讯28at.com

Bugs FixedaVa28资讯网——每日最新资讯28at.com

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 升级到 8.0 后,保存和检索 DATETIME 和 TIMESTAMP 值的结果有时会有所不同。这是因为,虽然 Connector/J 5.1 默认不保留时间点,但 Connector/J 8.0.22 及更早版本尝试通过在将时间戳的值发送到服务器之前将其转换为服务器的会话时区来保留时间点。在此版本中,引入了用于控制时区转换的新机制 - 有关详细信息,请参阅保留时间点。在这种新机制下,通过设置连接属性 retainInstants=false 来保留 Connector/J 5.1 在这方面的默认行为。(错误 #30962953、错误 #98695、错误 #30573281、错误 #95644)aVa28资讯网——每日最新资讯28at.com

四、综上总结

在使用MySQL的时候,确保服务器时区、MySQL时区、Java应用链接MySQL JDBC的参数配置,都指定到具体的时区上。MySQL JDBC 使用 8.0.23+ 版本,不要使用 8.0.0 ~ 8.0.22 版本,尤其是5.1升级要升级到 8.0.23 以及往后的版本。aVa28资讯网——每日最新资讯28at.com

正确配置;url: jdbc:mysql://127.0.0.1:3306/road-map?useUnicode=true&characterEncoding=utf8&autoRecnotallow=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimeznotallow=Asia/ShanghaiaVa28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-112721-0.html是什么导致了,写入MySQL库表时间不正确?—— 官网也有Bug!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 什么是内存溢出,Golang是如何解决内存溢出的

下一篇: 盘点分页查询中遇到的坑!

标签:
  • 热门焦点
  • 影音体验是真的强 简单聊聊iQOO Pad

    大公司的好处就是产品线丰富,非常细分化的东西也能给你做出来,例如早先我们看到了新的vivo Pad2,之后我们又在iQOO Neo8 Pro的发布会上看到了iQOO的首款平板产品iQOO Pad。虽
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人员可能会涉及各种各样的安全任务,包括但不限于:开发某些安全工具的插件,满足自己特定的安全需求;自定义github搜索工具,快速查找所需的安全资料、漏洞poc、exp
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 梁柱接棒两年,腾讯音乐闯出新路子

    文丨田静 出品丨牛刀财经(niudaocaijing)7月5日,企鹅FM发布官方公告称由于业务调整,将于9月6日正式停止运营,这意味着腾讯音乐长音频业务走向消亡。腾讯在长音频领域还在摸索。为
  • 冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    来源:直播观察提起&ldquo;冯提莫&rdquo;这个名字,很多网友或许听过,但应该不记得她是哪位主播了。其实,作为曾经的&ldquo;斗鱼一姐&rdquo;,冯提莫在游戏直播的年代影响力不输于现
  • 造车两年股价跌六成,小米的估值逻辑变了吗?

    如果从小米官宣造车后的首个交易日起持有小米集团的股票,那么截至2023年上半年最后一个交易日,投资者将浮亏59.16%,同区间的恒生科技指数跌幅为52.78%
  • iQOO 11S屏幕细节公布:首发三星2K E6全感屏 安卓最好的直屏手机

    日前iQOO手机官方宣布,新一代电竞旗舰iQOO 11S将会在7月4日19:00正式与大家见面。随着发布时间的日益临近,官方关于该机的预热也更加密集,截至目前已
Top