必须用 default-time-zone = 'asia/shanghai'(iana规范),重启mysql后生效;set global time_zone需super权限且不持久;客户端连接须显式指定servertimezone;系统时区也需同步设置。

my.cnf 里 timezone 配置写 default-time-zone,不是 timezone
MySQL 不认 timezone 这个配置项,写进去完全无效。必须用 default-time-zone,且值要符合 IANA 时区名规范(比如 'Asia/Shanghai'),不能写 '+08:00' —— 后者在 my.cnf 中会启动失败。
常见错误现象:mysqld 启动报错 Unknown variable 'timezone=+08:00' 或静默忽略配置,查 SELECT @@global.time_zone; 仍是 SYSTEM。
-
my.cnf的[mysqld]段下加:default-time-zone = 'Asia/Shanghai' - 改完必须重启 MySQL:
systemctl restart mysqld(或对应服务名) - 验证是否生效:
SELECT @@global.time_zone;应返回Asia/Shanghai,不是SYSTEM - 注意:该设置只影响新连接的会话时区,已存在的连接不受影响
SET time_zone 只改当前会话,SET GLOBAL 需 SUPER 权限且不持久
SET time_zone = '+08:00' 或 SET time_zone = 'Asia/Shanghai' 只作用于当前连接,断开就丢。想全局临时改(所有新连接都用),得用 SET GLOBAL time_zone,但有两个硬限制:
- 执行用户必须有
SUPER权限(普通应用账号通常没有) - 改完不写入配置文件,MySQL 重启后还原为 my.cnf 中的值
-
SET GLOBAL time_zone = '+08:00'和SET GLOBAL time_zone = 'Asia/Shanghai'效果不同:前者是固定偏移,后者会随夏令时变化(但中国不用夏令时,实际没区别)
时区设置不等于时间显示正确,还要看客户端与连接参数
即使服务端时区设对了,NOW() 返回的时间仍可能“看起来不对”,因为客户端可能自行转换。关键点在于连接时是否带 timeZone 参数。
- JDBC 连接串必须显式加:
?serverTimezone=Asia/Shanghai,否则驱动默认用 JVM 本地时区反向换算 - Python 的 pymysql 默认不处理时区,需手动设
init_command="SET time_zone = '+08:00'"或在连接后执行一次SET time_zone -
SELECT NOW()返回的是服务端时区时间;SELECT CONVERT_TZ(NOW(), '+00:00', '+08:00')才是强制转换,别依赖它做业务逻辑
SYSTEM 时区依赖系统时间,改 MySQL 时区前先确认系统时区
当 @@global.time_zone 是 SYSTEM 时,MySQL 直接读系统 /etc/localtime。如果系统时区本身没设对(比如服务器是 UTC,但业务要东八区),只改 MySQL 配置没用。
- 查系统时区:
timedatectl | grep "Time zone" - 改系统时区(以 CentOS/Ubuntu 为例):
sudo timedatectl set-timezone Asia/Shanghai - 改完建议同步硬件时钟:
sudo hwclock --systohc - 如果系统时区和 MySQL
default-time-zone不一致,SYSDATE()和NOW()在某些版本里可能返回不同结果(尤其配合复制或日志时)
真正麻烦的从来不是改哪一行配置,而是改完之后——连接、驱动、系统、日志解析,四个地方的时区逻辑全得对齐,漏一个就出现“时间差8小时”又查不出原因。











