前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用MySQLBinlog按时间查询二进制日志时易疏忽的地方

使用MySQLBinlog按时间查询二进制日志时易疏忽的地方

作者头像
LA0WAN9
发布2021-12-14 07:54:11
8090
发布2021-12-14 07:54:11
举报
文章被收录于专栏:火丁笔记

使用mysqlbinlog按时间查询二进制日志时,会用到start-datetimestop-datetime选项。

提示:MySQL二进制日志的名称缺省是HOSTNAME-bin,不过推荐通过log-bin设置,以防止HOSTNAME更改所带来的影响。二进制日志的目录可以使用如下方法得到:

代码语言:javascript
复制
mysql> SHOW VARIABLES LIKE 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+

假设要查询2010-11-20全天的二进制日志的话,很多人会这么写:

代码语言:javascript
复制
shell> mysqlbinlog \
    --start-datetime="2010-11-20 00:00:00" \
    --stop-datetime="2010-11-20 23:59:59" \
    /path/to/mysql/bin/log

不过这样写有问题,因为start-datetime是闭区间,stop-datetime是开区间,如果用数学表达式表示,类似:[start-datetime, stop-datetime),所以应该改为:

代码语言:javascript
复制
shell> mysqlbinlog \
    --start-datetime="2010-11-20 00:00:00" \
    --stop-datetime="2010-11-21 00:00:00" \
    /path/to/mysql/bin/log

可惜还有问题,因为二进制日志是按照提交时间的先后顺序来记录的,而start-datetime和stop-datetime表示的时间是请求时间,所以从请求时间的角度看,有时会发生错乱。

为了演示此种情况,我们来做个实验:

首先确保MySQL已经激活了二进制日志:

代码语言:javascript
复制
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

然后创建表:

代码语言:javascript
复制
mysql> USE test;
mysql> CREATE TABLE foo ( id INT ) ENGINE=InnoDB;

注意:本例中使用的是InnoDB表类型。

如果现有二进制日志数据可以删除的话,运行如下命令以减少对后面操作的影响:

代码语言:javascript
复制
mysql> RESET MASTER;

接下来打开两个MySQL命令行:

先在第一个MySQL命令行中执行:

代码语言:javascript
复制
mysql> USE test;
mysql> BEGIN;
mysql> INSERT INTO foo VALUES (1);

然后在第二个MySQL命令行中执行:

代码语言:javascript
复制
mysql> USE test;
mysql> INSERT INTO foo VALUES (2);

再回到第一个MySQL命令行中执行:

代码语言:javascript
复制
mysql> COMMIT;

此时使用mysqlbinlog查询二进制日志,部分结果如下:

代码语言:javascript
复制
shell> mysqlbinlog /path/to/mysql/bin/log

#101120 21:53:48
SET TIMESTAMP=1290261228/*!*/;
INSERT INTO foo VALUES (2)
/*!*/;

#101120 21:53:53
SET TIMESTAMP=1290261233/*!*/;
BEGIN
/*!*/;

#101120 21:53:36
SET TIMESTAMP=1290261216/*!*/;
INSERT INTO foo VALUES (1)
/*!*/;

#101120 21:53:53
COMMIT/*!*/;

二进制日志对应的时间分别是:

  1. 2010-11-20 21:53:48 (INSERT)
  2. 2010-11-20 21:53:53 (BEGIN)
  3. 2010-11-20 21:53:36 (INSERT)
  4. 2010-11-20 21:53:53 (COMMIT)

注意:BEGIN和COMMIT的时间是一样的,并且大于等于中间语句的时间,如此一来,确保BEGIN和COMMIT在按stop-datetime查询时是一个整体。如果使用stop-position,并在事务中间某位置停止,结果如何留给大家自己测试。

此时,不管以两个INSERT时间中的哪一个为stop-datetime,都查询不到INSERT数据:

代码语言:javascript
复制
shell> mysqlbinlog \
    --stop-datetime="22010-11-20 21:53:48" \
    /path/to/mysql/bin/log

shell> mysqlbinlog \
    --stop-datetime="2010-11-20 21:53:36" \
    /path/to/mysql/bin/log

这是因为stop-datetime是开区间的缘故。

而如果以2010-11-20 21:53:48加1秒得到的2010-11-20 21:53:49为stop-datetime,则能查到2010-11-20 21:53:48的数据,但查不到2010-11-20 21:53:36的数据:

代码语言:javascript
复制
shell> mysqlbinlog \
    --stop-datetime="2010-11-20 21:53:49" \
    /path/to/mysql/bin/log

这是因为查询到2010-11-20 21:53:53的时候,mysqlbinlog就停止了。

以上就是使用mysqlbinlog按时间查询二进制日志时易疏忽的地方。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2010-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档