对时区的设置主要是设置时区变量和填充时区表。
系统变量
system_time_zone
- 系统时区。
-
服务器启动时,会根据主机时区,自动设置该变量。此后该值不变
-
设置系统时区这种设置只适用于 mysqld_safe 启动,mysqld 没有 –timezone 选项。
需要在启动时,指定环境变量 TZ或 mysqld_safe 中使用 –timezone 选项
time_zone
- 服务器端当前时区
-
有效值格式
- SYSTEM
- 初始值,表示与系统时区相同
- 如果设置为 SYSTEM ,则每个需要时区计算的 MySQL 函数都会进行系统库调用以确定当前系统时区。
- 该调用可能受到全局互斥锁的保护,从而导致争用。
- UTC 的偏移量
- 时区偏移量必须在 ‘-14:00’ to ‘+14:00’ 之间,包括该范围
- 举例
- ‘+08:00’、’-6:00′ 或 ‘+05:30’
- 时区名
- 举例
- ‘Europe/Helsinki’, ‘US/Eastern’, ‘MET’ 或 ‘UTC’
- 填充时区表后,才可以使用时区名设置
- 举例
- SYSTEM
-
配置方法
timezone 的值不区分大小写。
- 修改配置文件
[mysqld] ... # 时区 default_time_zone = "+08:00"
- 动态设置
mysql> set global time_zone='+08:00'; -- 全局设置 mysql> set time_zone='+08:00'; -- 会话级设置
- 修改配置文件
- 查看
SELECT @@GLOBAL.time_zone, @@SESSION.time_zone;
填充时区表
MySQL 的安装过程中创建了时区表,但是未填充内容。加载时区信息不是一次性操作,因为该信息会偶尔更改。
MySQL 服务器的时区信息要与时区变化保持同步。当时区规则更改时,使用旧规则的应用程序将过时。
时区表
- mysql.time_zone_name
mysql> select * from mysql.time_zone_name; +----------------------------------------+--------------+ | Name | Time_zone_id | +----------------------------------------+--------------+ | Africa/Abidjan | 1 | | Africa/Accra | 2 | | Africa/Addis_Ababa | 3 | ...
时区文件
- /usr/share/zoneinfo
填充方法
- 如果系统有时区信息库,可以使用 mysql_tzinfo_to_sql 加载
运行 mysql_tzinfo_to_sql 之后,需要重启 MySQL 服务器使其避免使用缓存的旧时区数据。
- 加载所有时区文件
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
Note: /usr/share/zoneinfo 是系统的时区信息库路径,包含所有的时区文件。
-
加载单个时区文件
mysql_tzinfo_to_sql tz_file tz_name | mysql -u root -p mysql # 语法 mysql_tzinfo_to_sql /usr/share/zoneinfo/Asia/Shanghai Asia/Shanghai | mysql -uroot -p -S /tmp/mysql.sock mysql # 示例
- 当考虑 leap 跳秒时
mysql_tzinfo_to_sql --leap tz_file | mysql -u root -p mysql
- 时区表加载之后需要重启服务
- 加载所有时区文件
-
如果系统没有时区信息库,可以下载时区包 https://dev.mysql.com/downloads/timezones.html
- 如果系统有时区信息库,一定要用系统的,不要使用下载的,避免和系统上其他应用造成差异
-
将下载的时区包解压后加载到时区表
mysql -u root -p mysql < file_name
时区跳秒 (leap) 支持
时区跳秒修正
- 时间部分以 :59:59 结尾,那么函数 now() 在连续的 2-3 秒内返回的值相同
- 时间部分以 :59:60 和 :59:61 结尾被认为是无效的