之前也遇到过一次这种情况,正好最近看到这篇博客 https://www.cnblogs.com/zhoujinyi/archive/2012/12/14/2818552.html
可能其他人也会遇到,这里顺手记录下。
mysql版本:不限,我下面演示用的是8.0.x版本。
数据库的时区是东八区,tb表里面有3个字段,表里只有一行记录,都是表示 2024-11-03 16:33:24
执行如下的4个mysqldump命令,结果如下截图所示:
> mysqldump test tb --where='e="2024-11-03 16:33:24"' --set-gtid-purged=OFF | grep 'INSERT INTO'
> mysqldump test tb --where='c="2024-11-03 16:33:24"' --set-gtid-purged=OFF | grep 'INSERT INTO'
> mysqldump test tb --where='c="2024-11-03 16:33:24"' --set-gtid-purged=OFF --tz-utc=0 | grep 'INSERT INTO'
> mysqldump test tb --where='d=1730622804' --set-gtid-purged=OFF | grep 'INSERT INTO'
可以看到 第二个mysqldump命令导出的数据是空白的,从常理说应该是有符合where条件的数据的。
why ??
仔细看下mysqldump的日志,可以看到它会在命令开始的时候默认设置时区为UTC时区
这个 /*!40103 SET TIME_ZONE='+00:00' */;
会有啥影响?
可以看下面的例子:
在会话级别设置了time_zone为utc时区后,查询的数据中的timestamp列的数据就会跟着发生变化。
这也就导致mysqldump中的where条件数据范围发生了变化,可能出现导出的数据和期望的不一致的情况。
1 首先,从大小上你可以看出来,它不是个字符串,实际上是一个整型。所以当我们执行 where c='xxxx-xx-xx xx:xx:xx' 的时候,需要将其转换为整型。这就涉及到转换规则。也就是说,对于相同的时间戳,在不同的时区显示的结果是不一样的。反过来也一样,相同的字符串,在不同的时区解释下,会得到不同的时间戳。
2 为什么mysqldump的开发者不把—tz-utc=0作为默认行为呢?也就是说哦这样做有什么风险?
实际上是因为要防止跨时区导数据。假设你把中国一个机器上的数据导入到美国的一个mysqld(想起@plinux 说的b2b就有这种情况),若不显式地设置一个时区,在导入时就会出错了。因为都用系统默认的时区,相同的字符串值会得到不同的时间戳。如我们前面说的, 时间戳是以整型方式存储的。
如何规避或解决此类问题?
1、在mysqldump的时候加上参数 --tz-utc=0 即可
2、不要用timestamp的列了,改用datetime类型
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。