萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

mysqldump 導致 datetime 時間偏移 8 小時:--tz-utc 參數陷阱

故障現象

執行 mysqldump 備份後,應用新插入 DATETIME/TIMESTAMP 欄位的時間比實際時間**多 8 小時**(北京時區 UTC+8)。

根因分析

mysqldump 預設啟用 --tz-utc 參數:

  • 將**當前連線時區設為 UTC(SET TIME_ZONE='+00:00')
  • 導出檔案開頭會包含 SET TIME_ZONE='+00:00';
  • 若使用**長連線/連線池**(如 Maya、Druid、HikariCP),此連線被歸還池中繼續複用
  • 後續業務複用該連線時,Session 時區仍為 UTC,導致寫入時間偏移

官方文檔說明

--tz-utc:確保 TIMESTAMP 欄位在不同時區伺服器間正確遷移。預設開啟。使用 --skip-tz-utc 關閉。MySQL 5.1.2+ 引入。

解決方案

方案一:mysqldump 關閉 tz-utc(推薦)

mysqldump --skip-tz-utc -u root -p mydb > backup.sql

導出檔不再包含 SET TIME_ZONE,連線時區保持系統預設(如 SYSTEM / +08:00)。

方案二:應用層連線池重置 Session 時區

在連線歸還池前執行:

SET time_zone = SYSTEM;  -- 或 '+08:00'

連線池配置 connectionInitSqls(HikariCP)或 initSQL(Druid)自動執行。

方案三:應用層指定時區(JDBC URL)

jdbc:mysql://host:3306/db?serverTimezone=Asia/Shanghai&useTimezone=true

驗證方法

-- 備份檔檢查
head -30 backup.sql | grep TIME_ZONE

-- 連線池連線檢查
SHOW VARIABLES LIKE 'time_zone';
SELECT NOW();  -- 對比系統時間

最佳實踐總結

場景建議
同時區遷移/備份--skip-tz-utc 簡單安全
跨時區遷移保留 --tz-utc,目標端同步執行 SET TIME_ZONE
長連線池環境必須關閉 --tz-utc 或連線歸還時重置時區
應用層統一時區JDBC URL 指定 serverTimezone,資料庫層存 UTC

延伸:TIMESTAMP vs DATETIME

  • TIMESTAMP:儲存 UTC,讀取時按 Session 時區轉換,**受時區影響**
  • DATETIME:儲存原始值,**不受時區影響**
  • 新專案建議用 DATETIME + 應用層統一 UTC 存儲
copyright © 萬盛學電腦網 all rights reserved