前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >mysqldump根据时间字段where条件导出会导致数据缺失?

mysqldump根据时间字段where条件导出会导致数据缺失?

原创
作者头像
保持热爱奔赴山海
发布2024-11-03 19:10:13
发布2024-11-03 19:10:13
940
举报
文章被收录于专栏:数据库相关数据库相关

之前也遇到过一次这种情况,正好最近看到这篇博客 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命令,结果如下截图所示:

代码语言:txt
复制
> 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条件数据范围发生了变化,可能出现导出的数据和期望的不一致的情况。

关于timestamp这个字段类型的一些说明( https://www.iteye.com/blog/dinglin-1747685):

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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于timestamp这个字段类型的一些说明( https://www.iteye.com/blog/dinglin-1747685):
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档