system_time_zone:MySQL 啟動時從作業系統讀取,**只讀**,不可修改。time_zone:服務器時區,默認 SYSTEM (跟隨作業系統)。可全局/會話動態修改。-- 查看當前 SELECT NOW(), @@time_zone, @@system_time_zone; -- 設置全局時區 (需 SUPER 權限,影響新連接) SET GLOBAL time_zone = '+08:00'; -- 北京時間 / 東八區 -- 或具名時區 (需加載時區表) SET GLOBAL time_zone = 'Asia/Shanghai'; -- 設置當前會話時區 (僅對當前連接有效) SET time_zone = '+08:00'; SET SESSION time_zone = '+08:00'; -- 立即生效 (刷新權限非必需,但建議) FLUSH PRIVILEGES;
優點: 無需重啟,運維變更極快。
缺點: 重啟後恢復默認 SYSTEM。
# /etc/my.cnf 或 /etc/mysql/my.cnf [mysqld] default-time-zone = '+08:00' # 或具名時區 (需確保系統已安裝 tzdata,MySQL 時區表已加載) # default-time-zone = 'Asia/Shanghai'
systemctl restart mysqld。SHOW VARIABLES LIKE 'time_zone'; 顯示 +08:00。優點: 永久生效,版本遷移配置文件即可。
缺點: 需重啟服務 (業務停機窗口)。
在應用建立數據庫連接後、執行業務 SQL 前,顯式執行:
-- Java (HikariCP/Druid connectionInitSqls)
SET time_zone = '+08:00';
-- Python (PyMySQL/SQLAlchemy)
cursor.execute("SET time_zone = '+08:00'")
-- PHP (PDO/MySQLi)
$pdo->exec("SET time_zone = '+08:00'");
-- Go (database/sql)
db.Exec("SET time_zone = '+08:00'")
適用場景: 無服務器配置權限、多時區應用共用實例、測試環境臨時驗證。
限制: NOW()、SYSDATE() 等系統函數仍按 system_time_zone 執行,僅影響 TIMESTAMP 與時區相關函數 (CONVERT_TZ) 的行為。
使用 'Asia/Shanghai' 等具名時區需加載時區表:
# Linux mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uroot -p mysql # Windows (需下載 zoneinfo 文件) mysql_tzinfo_to_sql C:\zoneinfo | mysql -uroot -p mysql
加載後 mysql.time_zone* 表將填充數據,方可使用具名時區 (自動處理夏令時/DST)。
+08:00 或 Asia/Shanghai,避免跨環境時間不一致 Bug。DATETIME 存儲 UTC 時間,應用層按用戶時區展示轉換,杜絕時區混亂。TIMESTAMP 陷阱:TIMESTAMP 存儲範圍 1970-2038,受時區影響自動轉換,**不建議用於業務時間存儲**,改用 DATETIME 或 BIGINT (毫秒時間戳)。SELECT NOW(), UTC_TIMESTAMP(); 確認偏移量符合預期。