前一阵子有一台服务器,mysql的时间比北京时间晚了8个小时。我知道是时区的问题,但是不知道为什么弄成这样,宿主机没有问题,后来一看mysql的docker,时区是错的。
mybatis-plus打印的sql脚本中,包含时间参数的,都被强制减掉了8个小时,我一开始还以为是java方面的问题,原来是docker时区没有设置正确。mybytis-plus也是等数据库执行了才把SQL语句打印出来的,问题根源在数据库的微服务中!
看了docker用了什么版本 cat /etc/issue,原来用的是debian 9,不熟悉,加上docker各种命令不安装,非常难弄。
查看时区 date -R,果然不是北京时间。
千辛万苦安装了ntpdate,却提示 Can't adjust the time of day: Operation not permitted,修改时间也没有权限。因为docker也算是虚拟机吧,不能修改。
最后发现用宿主机的时间配置文件复制到容器就好了,真是笨,摸索了一两个小时。。。
docker cp /usr/share/zoneinfo/Asia/Shanghai mysql:/etc/local
mysql时间正确了,但是查询的时候时间还是少了8个小时,这时候我才想到,另外一个微服务的容器里面的时区会不会也是错的?
2019-08-19 00:37:30
熬到半夜了,也不顾头发快掉光了,继续研究,打开神器 wireshark 然后输入tcp.port==3306进行过滤,请求就出来了。尴尬的是我抓包看到的SQL语句就是减少了8个小时的。我好纳闷,连别的mysql服务器没有问题啊,怎么连这个mysql服务器就有问题了呢?虽然我知道就是这台mysql服务器的问题,但我还不明确具体问题出在哪。后来看到wireshark捕获到的一堆请求,我才想到,在我的 Java 服务启动时,spring boot 会去和mysql数据库建立联系,这时候就会获取mysql的时区,所以最根本的问题就是mysql的时区设置了!
虽然mysql容器里面的操作系统时区改了,但是我忘记了修改mysql的时区,所以show variables like '%time_zone%'查询出来是这样的:
Variable_name Value
system_time_zone CST
time_zone SYSTEM
想想自己真是蠢货啊。容器里面改不了,只好在宿主机改了,再复制进去。
[root@localhost ~]# docker cp mysql:/etc/mysql/my.cnf ./my.cnf [root@localhost ~]# vim my.cnf [root@localhost ~]# docker cp my.cnf mysql:/etc/mysql/my.cnf [root@localhost ~]# docker restart mysql
[mysqld] pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql secure-file-priv= NULL # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Custom config should go here !includedir /etc/mysql/conf.d/ default-time-zone = '+8:00'
设置后,重启mysql容器,docker restart mysql,然后查询变量,show variables like '%time_zone%'查询出来是这样的:
Variable_name Value
system_time_zone CST
time_zone +08:00
后来再启动服务一看,终于好了。可以睡觉了,毕竟头发不多了。