作者:王向

爱可生 DBA 团队成员,负责公司 DMP 产品的运维和客户 MySQL 问题的解决。善于数据库故障解决。对数据库技术和 python 有着浓重的趣味。

本文起源:原创投稿

*爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


本文目录:

前言

什么是“Unix千年虫”

试验2038年时 MySQL 会不会受到千年虫影响?

试验后果

问题起因

影响范畴

解决方案

前言

笔者在五一假期间,闲来无事刷了刷论坛博客;看到很多人在探讨2038年“Unix千年虫”危机!。来了趣味于是测试了下 MySQL 会不会受到“Unix千年虫“的影响而逝世

什么是“Unix千年虫”

古时候,“千年虫”bug已经引发了很大的恐慌,甚至不少影视剧中都有夸张的刻画。不过在紧急商量和“打补丁”之后,软硬件“无奈正确处理2000年问题”的千年虫危机算是安稳度过了。但……事实真的如此吗?对于 Unix 类操作系统来说,它们其实还面临着同样的问题,那就是——2038年危机!(又称“Unix千年虫”)!!

截图来自度娘百科:

试验2038年时 MySQL 会不会受到千年虫影响?

启动测试 MySQL 并监控 error 日志

随便把零碎工夫调整到2038年

看到了什么?MySQL 它自闭了间接 shutdown

试验后果

如果工夫穿梭来到了2038年或将操作系统的 date 调整为2038年,比方2038-10-20,你会发现正在运行的 MySQL 会主动放弃医治,重启后同样会主动敞开,无奈应用,MySQL 不反对2038年之后的日期。

2038-10-20T00:01:01.976322+08:00 2 [Warning] Current time has got past year 2038.Validating current time with 5 iterations before initiating the normal servershutdown process.2038-10-20T00:01:01.976465+08:00 2 [Warning] Iteration 1: Current time obtainedfrom system is greater than 20382038-10-20T00:01:01.976484+08:00 2 [Warning] Iteration 2: Current time obtainedfrom system is greater than 20382038-10-20T00:01:01.976538+08:00 2 [Warning] Iteration 3: Current time obtainedfrom system is greater than 20382038-10-20T00:01:01.976560+08:00 2 [Warning] Iteration 4: Current time obtainedfrom system is greater than 20382038-10-20T00:01:01.976580+08:00 2 [Warning] Iteration 5: Current time obtainedfrom system is greater than 20382038-10-20T00:01:01.976634+08:00 2 [ERROR] This MySQL server doesn't supportdates later than 2038

问题起因

MySQL timestamp 反对的最大工夫范畴是 '1970-01-01 00:00:01.000000' 到 '2038-01-19 03:14:07.999999',在源码 sql/sql_parse.cc 的 dispatch_command() 函数里,有一段代码,检测以后工夫是否超过2038年,如果超过,则会立刻进行 MySQL。

/*If the time has gone past 2038 we need to shutdown the server. Butthere is possibility of getting invalid time value on some platforms.For example, gettimeofday() might return incorrect value on solarisplatform. Hence validating the current time with 5 iterations beforeinitiating the normal server shutdown process because of time gettingpast 2038.*//*If the time has got past 2038 we need to shut this server down.We do this by making sure every command is a shutdown and wehave enough privileges to shut the server downTODO: remove this when we have full 64 bit my_time_t support*/

从以上这两段正文来看,应该是 MySQL 外部变量 my_time_t 不反对 64 位,在达到2038年之后,
MySQL 无奈执行任何命令,间接敞开。

影响范畴

目前 5.7 以及 8.0 的最新版本,都蕴含这一段代码逻辑,也就是现有的版本都会受到影响,在2038年都会主动进行。

  • 5.7.34(以后 5.7 的最新版本)
  • 8.0.25(以后 8.0 的最新版本)

解决方案

期待 MySQL 官网后续尽快开发齐全反对 my_time_t 64位的版本,在2038年之前降级到该版本即可。

明天是2021.06.22,间隔2038还有17年,目前所有在用的 MySQL 版本在2038年到来前,都须要进行降级。