• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

MySQL时区问题知晓

MySQL 彭东稳 7年前 (2017-03-29) 28274次浏览 已收录 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)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。

关于时区分布图,大家可以参考http://www.timedate.cn/time/timezone.htm,我们国家跨越了东五区、东六区、东七区、东八区、东九区五个时区,一般都统一采用东八区计时时间。

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

上面命令输出了+0800表示东八区,也就是我们国家的时间。相反,如果是-0800表示美国旧金山所在的时区,西八区。

我们在安装系统的时候,如果地区选择了Asia/Shanghai,那么系统的时区就是东八区。

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

方法一:使用tzselect设置时区

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

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

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

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

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

MySQL时区问题?

当MySQL的二进制日志格式为statement时,主从复制会因为时区的问题而造成数据不一致的的情况,具体可以参考一下这篇文章:故障案例–binlog_format不为row模式下关于时区设置的一个坑

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

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

在线修改时区。

配置修改时区

修改完了记得记得重启MySQL。

关于时区的调优?

网上有两篇文章是说在默认time_zone=system下,使用timestamp字段在大量请求时引发的CPU SYS高的问题。

MySQL timestamp字段引发的一个系统BUG

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自身转换,大大提高了性能。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (3)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!