mysql启动时未读取my.cnf中的default-time-zone,根本原因是配置文件未被加载或路径错误;需用mysqld --verbose --help | grep "default options"确认实际加载路径,在对应[mysqld]段下正确配置default-time-zone='+08:00',并确保docker环境同步宿主机时区或设置tz变量。

MySQL启动时没读取my.cnf里的default-time-zone
很多用户改完/etc/my.cnf或/etc/mysql/my.cnf,加了default-time-zone = '+08:00',重启mysqld后SELECT @@time_zone;还是SYSTEM,查询时间仍差8小时——根本原因是MySQL没加载你改的配置文件。
- 用
mysqld --verbose --help | grep "Default options"确认它实际读取的配置路径(常见有/etc/my.cnf、/etc/mysql/my.cnf、/usr/etc/my.cnf、~/.my.cnf) - 在正确路径的
[mysqld]段下添加:default-time-zone = '+08:00'
- 不要写成
timezone或time_zone,必须是default-time-zone - 改完后用
sudo systemctl restart mysql(或mysqld),别只kill进程再手动启
SET time_zone = '+08:00'只对当前会话生效
执行SET time_zone = '+08:00'确实能让当前连接查出来的时间“看起来对”,但新连接、应用重连、定时任务都会回到SYSTEM,治标不治本。
-
@@time_zone返回SYSTEM时,MySQL直接用系统时区(Linux上通常是/etc/localtime指向的时区) - 如果系统时区本身是UTC(比如Docker默认、某些云主机),即使MySQL设了
+08:00,SYSTEM也还是UTC → 差8小时 - 验证方式:
SELECT NOW(), UTC_TIMESTAMP(), @@time_zone;,三者应一致(都显示东八区时间)
Docker环境里MySQL容器时区错位更隐蔽
Docker镜像(如mysql:8.0)默认系统时区是UTC,即使你在my.cnf里写了default-time-zone,如果容器没挂载宿主机时区或没设TZ环境变量,SYSTEM仍为UTC,导致default-time-zone被忽略。
- 启动容器时加:
-e TZ=Asia/Shanghai -v /etc/localtime:/etc/localtime:ro - 或在
Dockerfile里加:RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
- 务必检查容器内
date命令输出是否为CST时间,不是就说明系统时区没生效
应用层用CONVERT_TZ()硬转换是临时补救
当无法立刻改服务端配置(比如生产库权限受限),可在SQL里显式转换:
-
SELECT CONVERT_TZ(NOW(), '+00:00', '+08:00');—— 把UTC转为东八区 - 但要注意:
CONVERT_TZ()依赖MySQL时区表(mysql.time_zone_*),首次使用前需运行mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql - 不推荐长期用,每次查询都调用函数影响性能,且容易漏写,尤其ORM生成的SQL不受控
my.cnf、容器里/etc/localtime到底指向哪、以及SYSTEM这个值背后绑定的是宿主机还是容器自己的时钟。查的时候盯紧SELECT @@global.time_zone, @@session.time_zone;和date命令输出,比反复改配置更省时间。











