作者:王向
爱可生 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 server
shutdown process.
2038-10-20T00:01:01.976465+08:00 2 [Warning] Iteration 1: Current time obtained
from system is greater than 2038
2038-10-20T00:01:01.976484+08:00 2 [Warning] Iteration 2: Current time obtained
from system is greater than 2038
2038-10-20T00:01:01.976538+08:00 2 [Warning] Iteration 3: Current time obtained
from system is greater than 2038
2038-10-20T00:01:01.976560+08:00 2 [Warning] Iteration 4: Current time obtained
from system is greater than 2038
2038-10-20T00:01:01.976580+08:00 2 [Warning] Iteration 5: Current time obtained
from system is greater than 2038
2038-10-20T00:01:01.976634+08:00 2 [ERROR] This MySQL server doesn't support
dates 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. But
there is possibility of getting invalid time value on some platforms.
For example, gettimeofday() might return incorrect value on solaris
platform. Hence validating the current time with 5 iterations before
initiating the normal server shutdown process because of time getting
past 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 we
have enough privileges to shut the server down
TODO: 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 年到来前,都须要进行降级。