服务器初始化时须先配置系统时区与硬件时间同步,再在my.cnf中一次性设好utf8mb4字符集、utf8mb4_0900_ai_ci校对规则、default-time-zone='+08:00'及init_connect='SET NAMES utf8mb4',并分三层验证生效。

服务器初始化时,系统字符集和时区不是MySQL专属问题,而是整个Linux环境的基础支撑。真正要“设对”,得从操作系统层开始理清逻辑:系统时间与时区决定MySQL的server_time_zone初始值,而系统默认语言环境(locale)虽不直接影响MySQL,却关系到日志、脚本、终端显示的一致性。这两项配置若留到MySQL装完再补,容易出现时间漂移、中文路径乱码、服务启动失败等隐性问题。
先搞定系统时区与硬件时间同步
Linux系统启动时读取硬件时钟(RTC),再结合时区规则生成系统时间。只改date命令是临时的,重启即丢。
- 用
timedatectl set-timezone Asia/Shanghai永久设置时区,它会自动重建/etc/localtime软链接 - 执行
timedatectl set-ntp true启用chrony或systemd-timesyncd自动校时 - 运行
hwclock --systohc --utc或--localtime将当前系统时间写入硬件时钟——CentOS 7默认用UTC存硬件时间,但部分云平台要求本地时间,需按实际环境选择
MySQL字符集必须在my.cnf里一次性配齐
MySQL 8.0不会自动升级旧配置,安装或升级后若没显式写utf8mb4,character_set_server仍可能是utf8(即utf8mb3),导致emoji和部分生僻汉字存不进去。
- 在
/etc/my.cnf的[mysqld]段写:character-set-server = utf8mb4collation-server = utf8mb4_0900_ai_cidefault-time-zone = '+08:00' - 在
[client]和[mysql]段加:default-character-set = utf8mb4 - 加上
init_connect = 'SET NAMES utf8mb4'(注意:root用户不触发该语句,管理操作建议用普通账号)
Docker环境要额外处理时区与配置挂载
容器内MySQL默认读宿主机/etc/localtime,但若挂载了自定义my.cnf却没同步时区文件,就会出现default-time-zone设了却无效的情况。
- 启动容器时加
-v /etc/localtime:/etc/localtime:ro确保时区一致 - 把定制好的
my.cnf挂载到/etc/mysql/my.cnf,权限设为644 - 避免依赖环境变量传字符集——MySQL 8.0不认
MYSQL_CHARSET这类变量,只认配置文件
验证是否真正生效
别只看SELECT NOW(),要分三层确认:
- 系统层:
timedatectl status | grep "Time zone"和date - MySQL全局层:
SELECT @@global.time_zone, @@global.character_set_server, @@global.collation_server; - 连接层:
SELECT @@session.time_zone, @@session.character_set_client, @@session.collation_connection;

















