IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

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

火丁笔记 2010-11-21 19:47:30 累计浏览 4,318 次
本机暂存

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

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

mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+

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

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),所以应该改为:

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已经激活了二进制日志:

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+

然后创建表:

mysql> user test;
mysql> create table foo ( id int ) engine=innodb;

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

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

mysql> reset master;

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

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

mysql> use test;
mysql> begin;
mysql> insert into foo values (1);

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

mysql> use test;
mysql> insert into foo values (2);

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

mysql> commit;

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

shell> mysqlbinlog /path/to/mysql/bin/log

# at 174
#101120 21:53:48 server id 1  end_log_pos 263   Query   thread_id=92
use test/*!*/;
SET TIMESTAMP=1290261228/*!*/;
insert into foo values (2)
/*!*/;

# at 290
#101120 21:53:53 server id 1  end_log_pos 358   Query   thread_id=73
SET TIMESTAMP=1290261233/*!*/;
BEGIN
/*!*/;

# at 358
#101120 21:53:36 server id 1  end_log_pos 447   Query   thread_id=73
SET TIMESTAMP=1290261216/*!*/;
insert into foo values (1)
/*!*/;

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

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

正好佐证了二进制日志是按照提交时间的先后顺序来记录的。

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

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

而如果以22010-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的数据:

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

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

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

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,252)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,401)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  4. Mysql监控指南 (累计阅读 21,352)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,523)
  6. 在Apache2.2.XX下安装Mod-myvhost模块 (累计阅读 13,058)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  8. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,909)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,709)
  10. 深入浅出INNODB MVCC机制与原理 (累计阅读 9,693)