Skip to content
blog.chrisyuan.me
Go back

MySQL 在 Y2K38 問題上的修正

Edit page

Table of contents

Open Table of contents

MySQL 在 Y2K38 問題上的修正

前言

最近瀏覽 Year 2038 problem 維基百科條目時,發現其中列出了各種作業系統和軟體的解決方案。特別注意到 MySQL 8.0.28(2022年1月釋出)終於修正了 FROM_UNIXTIME()UNIX_TIMESTAMP()CONVERT_TZ() 三個函式處理 64 位元數值的問題。

什麼是 Y2K38 問題?

背景說明

在 32 位元架構的時代,系統普遍使用 32 位元的 time_t 來儲存 UNIX Timestamp。UNIX 時間以 1970-01-01 00:00:00 UTC 為起點,用整數記錄經過的秒數:

問題核心

有號 32 位元整數的範圍是 -(2³¹) = -2,147,483,648 到 2³¹-1 = 2,147,483,647。當超過最大值時會發生整數溢位

Year 2038 problem demonstration

時間會從 2038-01-19 03:14:07 UTC 瞬間跳回 1901-12-13 20:45:52 UTC

解決方案

改用 64 位元儲存時間戳。若繼續以秒為單位,2⁶³-1 = 9,223,372,036,854,775,807 秒約可使用 2,920 億年——遠超過宇宙年齡。因此許多系統選擇提高時間精度(毫秒、微秒或奈秒)來善用空間。

MySQL 的處理歷程

問題發現(2005年)

早在 MySQL 4.1 時代,就有使用者回報 Bug #12654

實務影響

由於 MySQL 的 DATETIME 型態設計限制,許多開發者選擇直接用整數欄位儲存 UNIX Timestamp。原本期望只要將欄位從 4 Byte 的 INT 改為 8 Byte 的 BIGINT 就能解決,但關鍵的轉換函式仍有 32 位元限制。

修正時程

結語

從現在(2023年)到 Y2K38 問題爆發只剩不到 15 年。對比 MySQL 花了 16 年才修正這個問題,提醒我們必須及早準備系統升級和資料遷移計畫。


Edit page
Share this post on:

Previous Post
Thomas Wolf 談自學人工智慧/機器學習/自然語言背後的數學基礎
Next Post
用 brew 安裝 PostgreSQL client