使用mysqlbinlog按时间查询二进制日志时,会用到start-datetime和stop-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 0" \ --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 0" \ --stop-datetime="2010-11-21 0" \ /path/to/mysql/bin/log可惜还有问题,因为二进制日志是按照提交时间的先后顺序来记录的,而start-datetime和stop-datetime表示的时间是请求时间,所以从请求时间的角度看,有时会发生错乱。
为了演示此种情况,我们来做个实验:
首先确保MySQL已经激活了二进制日志:
mysql> SHOW VARIABLES LIKE 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+然后创建表:
mysql> USE 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 #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/*!*/;二进制日志对应的时间分别是:
2010-11-20 21:53:48 (INSERT) 2010-11-20 21:53:53 (BEGIN) 2010-11-20 21:53:36 (INSERT) 2010-11-20 21:53:53 (COMMIT)注意:BEGIN和COMMIT的时间是一样的,并且大于等于中间语句的时间,如此一来,确保BEGIN和COMMIT在按stop-datetime查询时是一个整体。如果使用stop-position,并在事务中间某位置停止,结果如何留给大家自己测试。
此时,不管以两个INSERT时间中的哪一个为stop-datetime,都查询不到INSERT数据:
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的数据:
shell> mysqlbinlog \ --stop-datetime="2010-11-20 21:53:49" \ /path/to/mysql/bin/log这是因为查询到2010-11-20 21:53:53的时候,mysqlbinlog就停止了。
以上就是使用mysqlbinlog按时间查询二进制日志时易疏忽的地方。
查看更多关于MySQLBinlog按时间查询二进制日志时易疏忽的地方的详细内容...