必须同时设置TZ=Asia/Shanghai和MYSQL_TIME_ZONE='+08:00',因为TZ仅影响系统时区(如date命令、system_time_zone),而MYSQL_TIME_ZONE才真正设置MySQL的@@global.time_zone为+08:00,二者缺一不可,否则NOW()与系统时间偏差8小时。

直接在 docker run 时用 TZ=Asia/Shanghai 和 MYSQL_TIME_ZONE='+08:00' 两个环境变量,就能让 MySQL 容器的 NOW()、SYSDATE()、@@global.time_zone、system_time_zone 四者全部对齐北京时间——这是最稳、最省事、无需重启的方式。
为什么只设 TZ=Asia/Shanghai 不够?
因为 TZ 只影响容器系统级时间(比如 date 命令、system_time_zone),但 MySQL 自己的 time_zone 默认仍为 SYSTEM,而官方镜像中 SYSTEM 实际指向的是 UTC,不是容器的 TZ。结果就是:date 显示北京时间,NOW() 还是慢 8 小时。
必须同时告诉 MySQL:“你该用东八区”,靠 MYSQL_TIME_ZONE='+08:00'(MySQL 5.7+ 官方镜像才识别)或通过配置文件写死 default-time-zone。
-
MYSQL_TIME_ZONE是官方镜像的“快捷键”:启动时自动注入到my.cnf并设为全局time_zone - 只设
TZ不设MYSQL_TIME_ZONE→@@global.time_zone仍是SYSTEM,实际值还是 UTC - 只设
MYSQL_TIME_ZONE不设TZ→system_time_zone仍为 UTC,部分日志/监控工具可能误判
docker run 启动时一步到位的命令怎么写?
用下面这行命令,不进容器、不改配置、不重启,时区从启动那一刻就生效:
docker run -d \ --name mysql-bj \ -e MYSQL_ROOT_PASSWORD=123456 \ -e TZ=Asia/Shanghai \ -e MYSQL_TIME_ZONE='+08:00' \ -p 3306:3306 \ -v /data/mysql:/var/lib/mysql \ mysql:8.0
注意点:
-
MYSQL_TIME_ZONE='+08:00'必须带引号,避免 shell 解析错误;用+08:00比Asia/Shanghai更稳妥(后者依赖容器内 tzdata 是否完整) - 挂载
/etc/localtime(如-v /etc/localtime:/etc/localtime:ro)效果等同于TZ,但不如TZ明确、可移植 - 如果用了自定义
my.cnf挂载,MYSQL_TIME_ZONE会被忽略——它只在无配置文件时起作用
容器已运行,怎么补救?
执行以下 SQL 可临时修正(重启后失效):
用于设计、审查、生成或重构使用Effector、effector-react、Farfetched、AtomicRouter、@effector/next等库的React应用。
SET GLOBAL time_zone = '+08:00';<br>SET time_zone = '+08:00';
但这只是改了 MySQL 内部变量,system_time_zone 仍是 UTC,且下次容器重启就回退。适合测试或紧急排查,别当生产方案。
真正想“永久”生效,得进容器改配置:
- 编辑
/etc/mysql/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf - 在
[mysqld]下加一行:default-time-zone='+08:00' - 然后
docker restart mysql-bj——注意:必须重启容器,mysqladmin reload不生效
验证时区是否真对齐了?
别只看 NOW(),四个值必须一致才算真正搞定:
docker exec mysql-bj mysql -uroot -p123456 -e "SELECT NOW(), SYSDATE(), @@global.time_zone, @@global.system_time_zone"
正确输出应类似:
NOW(): 2026-09-03 02:17:22<br>SYSDATE(): 2026-09-03 02:17:22<br>@@global.time_zone: +08:00<br>@@global.system_time_zone: CST
其中 system_time_zone 显示 CST 是正常现象(Linux 系统对东八区的简写),只要不是 UTC 就说明 TZ=Asia/Shanghai 生效了。
最容易被忽略的是:default-time-zone 配置项在 [mysqld] 段落外无效,漏写段落名会导致整个配置被跳过;另外,MySQL 8.0.22+ 对 default-time-zone 的值校验更严,用 'Asia/Shanghai' 而非 '+08:00' 时,务必确认容器内已安装 tzdata 包。

















