• 欢迎访问DBA的辛酸事儿,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站
  • 欢迎大家关注博主公众号:DBA的辛酸事儿
  • 博文中若有错误的地方,请大家指正,大家的指正是我前进的动力

聊聊Linux和MYSQL的时区问题

Linux SEian.G 6年前 (2019-03-04) 3416次浏览 已收录 0个评论
文章目录[隐藏]

关于时区的概念,其实初中地理课已经涉及,很多人都多少了解一些;为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总比西边的早。东边时刻与西边时刻的差值不仅要以时计,而且还要以分和秒来计算。整个地球分为二十四时区,每个时区都有自己的本地时间。在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated)。UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地时相同。

关于时间的几个标准,如下所示,具体可以Google、Baidu搜索一下。

CST:中国标准时间(China Standard Time),这个解释可能是针对RedHat Linux

JST:日本标准时间(Japan Standard Time)。

UTC:协调世界时,又称世界标准时间,简称UTC,从英文国际时间/法文协调时间”Universal Time/Temps Cordonné”而来。中国大陆、香港、澳门、台湾、蒙古国、新加坡、马来西亚、菲律宾、澳洲西部的时间与UTC的时差均为+8,也就是UTC+8。

GMT:格林尼治标准时间(旧译格林威治平均时间或格林威治标准时间;英语:Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

我们国家跨越了东五区、东六区、东七区、东八区、东九区五个时区,一般都统一采用东八区计时时间。

Linux时区问题

Linux系统如何查看设置所在的时区呢?

[root@VM_54_118_centos ~]# date
Sun Mar  3 15:52:50 CST 2019

[root@VM_54_118_centos ~]# date -R
Sun, 03 Mar 2019 15:52:55 +0800

上面命令输出了+0800表示东八区,也就是我们国家的时间。相反,如果是-0800表示美国旧金山所在的时区,西八区。
我们在安装Linux操作系统的时候,如果地区选择了Asia/Shanghai,那么系统的时区就是东八区。

聊聊Linux和MYSQL的时区问题

Linux系统如何设置系统所在的时区呢?
方法一:使用tzselect设置时区

[root@VM_54_118_centos ~]# tzselect 
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
 1) Africa
 2) Americas
 3) Antarctica
 4) Arctic Ocean
 5) Asia
 6) Atlantic Ocean
 7) Australia
 8) Europe
 9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5
Please select a country.
 1) Afghanistan           18) Israel                35) Palestine
 2) Armenia               19) Japan                 36) Philippines
 3) Azerbaijan            20) Jordan                37) Qatar
 4) Bahrain               21) Kazakhstan            38) Russia
 5) Bangladesh            22) Korea (North)         39) Saudi Arabia
 6) Bhutan                23) Korea (South)         40) Singapore
 7) Brunei                24) Kuwait                41) Sri Lanka
 8) Cambodia              25) Kyrgyzstan            42) Syria
 9) China                 26) Laos                  43) Taiwan
10) Cyprus                27) Lebanon               44) Tajikistan
11) East Timor            28) Macau                 45) Thailand
12) Georgia               29) Malaysia              46) Turkmenistan
13) Hong Kong             30) Mongolia              47) United Arab Emirates
14) India                 31) Myanmar (Burma)       48) Uzbekistan
15) Indonesia             32) Nepal                 49) Vietnam
16) Iran                  33) Oman                  50) Yemen
17) Iraq                  34) Pakistan
#? 9
Please select one of the following time zone regions.
1) Beijing Time
2) Xinjiang Time
#? 1

The following information has been given:

        China
        Beijing Time

Therefore TZ='Asia/Shanghai' will be used.
Local time is now:      Sun Mar  3 15:53:32 CST 2019.
Universal Time is now:  Sun Mar  3 07:53:32 UTC 2019.
Is the above information OK?
1) Yes
2) No
#? 1

You can make this change permanent for yourself by appending the line
        TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.

Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai

注意:tzselect命令只告诉你选择的时区的写法,并不会生效。你可以在.profile、.bash_profile或者/etc/profile中设置正确的TZ环境变量并导出。 例如在.bash_profile里面设置 TZ=’Asia/Shanghai’; export TZ并使其生效。

示例:将系统时区设置为东九区(日本时间)

[root@VM_54_118_centos ~]# export TZ='Asia/Tokyo'

[root@VM_54_118_centos ~]# date
Sun Mar  3 16:55:47 JST 2019

[root@VM_54_118_centos ~]# date -R
Sun, 03 Mar 2019 16:55:52 +0900

方法二:复制相应的时区文件,替换系统时区文件或者创建链接文件

在/usr/share/zoneinfo/下面有很多时区文件(跟tzselect显示的一样),可以复制这些时区文件覆盖/etc/localtime文件,或修改符号链接/etc/locatime对应的文件。

[root@VM_54_118_centos ~]# ll /etc/localtime 
lrwxrwxrwx. 1 root root 35 Jan  9  2018 /etc/localtime -> ../usr/share/zoneinfo/Asia/Shanghai

注意:如果有时候,执行了上面命令后,使用date -R发现时区设置没有生效,有可能是因为你在profile或.bash_profile里面设置了TZ。

MySQL时区问题

当MySQL的二进制日志格式为statement时,主从复制会因为时区的问题而造成数据不一致的的情况;

具体可以参考一下这篇文章:故障案例–binlog_format不为row模式下关于时区设置的一个坑

通过在做主从同步或异地灾备的时候,一定要保证操作系统以及数据库时间要同步,否则就会出现一些异常的问题;

首先查看MySQL的当前时区,用time_zone参数。

root@localhost [wjq]>show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)

可以看出MySQL默认是根据系统时区来的。
在线修改时区。

root@localhost [wjq]>select now();
+---------------------+
| now()               |
+---------------------+
| 2019-03-03 16:00:07 |
+---------------------+
1 row in set (0.00 sec)

root@localhost [wjq]>set time_zone='+9:00';
Query OK, 0 rows affected (0.00 sec)

root@localhost [wjq]>show variables like '%time_zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | +09:00 |
+------------------+--------+
2 rows in set (0.00 sec)

root@localhost [wjq]>select now();
+---------------------+
| now()               |
+---------------------+
| 2019-03-03 17:00:50 |
+---------------------+
1 row in set (0.00 sec)

root@localhost [wjq]>set time_zone='+8:00';  
Query OK, 0 rows affected (0.00 sec)

root@localhost [wjq]>select now();
+---------------------+
| now()               |
+---------------------+
| 2019-03-03 16:01:15 |
+---------------------+
1 row in set (0.00 sec)

配置文件修改时区

default-time-zone = '+8:00'

修改完了重启MySQL生效;

关于时区的调优?
网上有两篇文章是说在默认time_zone=system下,使用timestamp字段在大量请求时引发的CPU SYS高的问题。
MySQL参数time_zone导致线上sys cpu高

大概意思就是讲,对于使用timestamp的场景,MySQL在访问timestamp字段时会做时区转换,当time_zone设置为system时(默认),MySQL访问每一行的timestamp字段时,都会通过libc的时区函数,获取Linux设置的时区,在这个函数中会持有mutex,当大量并发SQL需要访问timestamp字段时,会出现mutex竞争。MySQL访问每一行都会做这个时区转换,转换完后释放mutex,所有等待这个mutex的线程全部唤醒,结果又会只有一个线程会成功持有mutex,其余又会再次sleep,这样就会导致context switch非常高但qps很低,系统吞吐量急剧下降。

总结下文章:就是当参数设置time_zone=system的时候,查询timestamp字段,会调用系统的时区做时区转换,有全局锁__libc_lock_lock的保护,导致线程并发环境下,系统性能受限。如果将time_zone=’+8:00’则不会调用系统时区,则不会触发系统时区转换,使用mysql自身转换,大大提高了性能。

聊聊Linux和MYSQL的时区问题


如果您觉得本站对你有帮助,那么可以收藏和推荐本站,帮助本站更好地发展,在此谢过各位网友的支持。
转载请注明原文链接:聊聊Linux和MYSQL的时区问题
喜欢 (7)
SEian.G
关于作者:
用心去记录工作,用心去感受生活,用心去学着成长;座右铭:苦练七十二变,笑对八十一难
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址