linux修改服务器时区
在 Ubuntu 服务器上,MySQL 配置中的 time_zone = SYSTEM 意味着 MySQL 数据库的时区设置将直接跟随操作系统的系统时区。
具体来说,它的含义和工作机制如下:
1. 核心含义
- 动态同步操作系统:当
time_zone设置为SYSTEM(这是 MySQL 的默认值)时,MySQL 不会使用自己独立的时区定义,而是读取 Ubuntu 操作系统当前的时区配置。 - 依赖
/etc/localtime:MySQL 会依据 Ubuntu 系统中的/etc/localtime文件或TZ环境变量来确定当前时间。如果 Ubuntu 的系统时区是Asia/Shanghai,那么 MySQL 中的NOW()、CURDATE()等函数返回的时间就是北京时间;如果 Ubuntu 系统是UTC,MySQL 返回的就是 UTC 时间。
2. 相关变量区别
在 MySQL 中,有两个容易混淆的时区变量:
-
system_time_zone:- 这是一个只读变量。
- 它在 MySQL 服务启动瞬间从 Ubuntu 操作系统获取一次时区信息并固定下来。
- 即使后续你修改了 Ubuntu 的系统时区,只要不重启 MySQL,这个变量的值通常保持不变(取决于具体版本,但通常视为静态快照)。
-
time_zone:- 这是一个可修改变量(可以全局或会话级修改)。
- 默认值为
SYSTEM。 - 它决定了当前会话中时间函数的行为以及
TIMESTAMP类型的转换逻辑。 - 当它为
SYSTEM时,它实际上是指向当前操作系统的实时时区配置(在某些实现中,它会重新读取系统设置,而不仅仅是启动时的快照)。
3. 对数据和时间函数的影响
A. 时间函数
所有基于当前时间的函数都受此设置影响:
NOW(),CURDATE(),CURTIME(),CURRENT_TIMESTAMP():返回的时间值将反映 Ubuntu 系统当前的时区时间。UNIX_TIMESTAMP():将传入的时间视为当前时区(即 Ubuntu 系统时区)的时间,并转换为 UTC 时间戳。FROM_UNIXTIME():将 UTC 时间戳转换回当前时区(即 Ubuntu 系统时区)的时间格式。
B. 数据存储类型
-
TIMESTAMP类型:- 存储时:MySQL 会将客户端传入的时间从当前时区(SYSTEM/Ubuntu 时区)转换为 UTC 存入磁盘。
- 查询时:MySQL 将存储的 UTC 时间转换回当前时区(SYSTEM/Ubuntu 时区)显示给用户。
- 风险:如果你修改了 Ubuntu 的系统时区(例如从 UTC 改为 Asia/Shanghai),之前存入的
TIMESTAMP数据在查询时显示的值会发生变化(因为转换基准变了),这可能导致数据逻辑错误。
-
DATETIME类型:- 存储时:原样存储,不进行任何时区转换。
- 查询时:原样返回。
- 特点:不受
time_zone设置影响,无论 Ubuntu 时区如何变化,存进去是什么,取出来就是什么。
4. Ubuntu 环境下的常见问题与解决
常见问题
-
时区不一致导致时间差8小时:
- 如果 Ubuntu 系统默认时区是
UTC,而你的业务期望是北京时间(CST/UTC+8),那么SELECT NOW();查出的时间会比预期少8小时。 - Java 应用连接数据库时,如果 JDBC URL 未指定
serverTimezone,也可能出现类似偏差。
- 如果 Ubuntu 系统默认时区是
-
修改系统时区后 MySQL 未生效:
- 如果在 Ubuntu 上执行
timedatectl set-timezone Asia/Shanghai修改了系统时区,但 MySQL 仍然显示旧时区,可能是因为 MySQL 进程缓存了旧的时区信息,或者system_time_zone是在启动时固定的。
- 如果在 Ubuntu 上执行
解决方案
方案一:修改 Ubuntu 系统时区(推荐用于单机简单场景)
确保操作系统时区正确,MySQL 会自动跟随。
# 1. 查看当前系统时区 timedatectl # 2. 设置为上海时区 sudo timedatectl set-timezone Asia/Shanghai # 3. 重启 MySQL 服务以确保完全同步(特别是 system_time_zone 变量) sudo systemctl restart mysql
方案二:在 MySQL 中显式设置时区(推荐用于生产环境)
不依赖操作系统,直接在 MySQL 配置中指定时区,更加稳定可控。
-
临时生效(无需重启):
-- 设置全局时区为东八区 SET GLOBAL time_zone = '+8:00'; -- 刷新权限(部分版本需要) FLUSH PRIVILEGES;
永久生效(需重启 MySQL):
编辑 MySQL 配置文件(通常是 /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf),在 [mysqld] 节点下添加:
[mysqld] default-time-zone = '+8:00'
保存后重启 MySQL:
bash
sudo systemctl restart mysql
方案三:JDBC 连接层指定(针对 Java 应用)
如果数据库时区是 UTC,但希望应用层处理为北京时间,可以在 JDBC URL 中指定:
jdbc:mysql://localhost:3306/your_db?serverTimezone=Asia/Shanghai
总结
在 Ubuntu 上,time_zone = SYSTEM 表示 MySQL “偷懒”直接使用 Ubuntu 服务器的系统时间配置。虽然配置简单,但在生产环境中缺乏稳定性(如运维修改系统时区会影响数据库)。建议显式设置为具体的时区偏移量(如 +8:00)或命名时区(如 Asia/Shanghai),以确保时间处理的一致性,避免因地缘政治导致的时区规则变更(如夏令时)带来潜在问题。
个人学习笔记,记录日常学习,便于查阅及加深,仅为方便个人使用。

浙公网安备 33010602011771号