做者:王向python
愛可生 DBA 團隊成員,負責公司 DMP 產品的運維和客戶 MySQL 問題的處理。擅長數據庫故障處理。對數據庫技術和 python 有着濃厚的興趣。mysql
本文來源:原創投稿sql
*愛可生開源社區出品,原創內容未經受權不得隨意使用,轉載請聯繫小編並註明來源。數據庫
本文目錄:運維
前言函數
什麼是「Unix千年蟲」測試
實驗2038年時 MySQL 會不會受到千年蟲影響?this
實驗結果spa
問題緣由操作系統
影響範圍
解決方案
筆者在五一假期間,閒來無事刷了刷論壇博客;看到不少人在討論2038年「Unix千年蟲」危機!。來了興趣因而測試了下 MySQL 會不會受到「Unix千年蟲「的影響而去世
古時候,「千年蟲」bug曾經引起了很大的恐慌,甚至很多影視劇中都有誇大的描寫。不過在緊急磋商和「打補丁」以後,軟硬件「沒法正確處理2000年問題」的千年蟲危機算是平穩度過了。但……事實真的如此嗎?對於 Unix 類操做系統來講,它們其實還面臨着一樣的問題,那就是——2038年危機!(又稱「Unix千年蟲」)!!
截圖來自度娘百科:
啓動測試 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年都會自動中止。
期待 MySQL 官方後續儘快開發徹底支持 my_time_t 64位的版本,在2038年以前升級到該版本便可。
今天是2021.06.22,距離2038還有17年,目前全部在用的 MySQL 版本在2038年到來前,都須要進行升級。