通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操

1.binlog日志基本知识

MySQL的二进制日志binlog可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句(除了数据查询语句select),以事件形式记录,还包含语句所执行的消耗的时间。

binlog有三种格式:Statement、Row以及Mixed。分别是:基于SQL语句的复制(statement-based replication,SBR)、 基于行的复制(row-based replication,RBR)和混合模式复制(mixed-based replication,MBR)。

格式   说明   优点   缺点  
Statement模式   每一条会修改数据的sql语句都会记录到binlog中。   不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。   缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数,last_insert_id(),以及user-defined functions(udf)等会出现问题)。  
Row模式  

不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。

而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。

新版本的MySQL中对row level模式也被做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么会记录所有行的变更。

 

任何情况都可以被复制,这对复制来说是最安全可靠的。多数情况下,从服务器上的表如果有主键的话,复制就会快了很多。
复制以下几种语句时的行锁更少:(1)INSERT ... SELECT;(2)包含 AUTO_INCREMENT 字段的 INSERT;(3)没有附带条件或者并没有修改很多记录的 UPDATE 或 DELETE 语句
执行INSERT,UPDATE,DELETE 语句时锁更少。从服务器上采用多线程来执行复制成为可能。

  binlog 大了很多
复杂的回滚时 binlog 中会包含大量的数据
主服务器上执行 UPDATE 语句时,所有发生变化的记录都会写到 binlog 中,这会导致频繁发生 binlog 的并发写问题
UDF 产生的大 BLOB 值会导致复制变慢
无法从 binlog 中看到都复制了写什么语句
 
MIXED模式   实际上就是前两种模式的结合,在mixed模式下,mysql会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在statement和row之间选一种。   在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。  
2.查看Row模式和Statement模式的binlog

为了加深印象,下面我们看看两者模式下的binlog到底长什么样子。

2.1 测试案例

分别在Row模式 和 Statement模式 下执行以下语句。

创建一张表

CREATE TABLE IF NOT EXISTS `tt` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(16) NOT NULL, `sex` enum('m','w') NOT NULL DEFAULT 'm', `age` tinyint(3) unsigned NOT NULL, `classid` char(6) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

向表中insert 5笔数据

insert into zyyshop.tt(`name`,`sex`,`age`,`classid`) values('yiyi','w',20,'cls1'),('xiaoer','m',22,'cls3'),('zhangsan','w',21,'cls5'),('lisi','m',20,'cls4'),('wangwu','w',26,'cls6');

用一条SQL语句修改前两笔数据

update tt set name ='XXX' where id in (1,2);

在Row模式下形成的binlog文件为:mysql3306_bin.000011

在Statement模式下生成的binlog文件为:mysql3306_bin.000012。

2.2 用 show binlog events in 命令去查看分析2各个文件

查询Row模式记录如下:

通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操

查询Statement模式记录如下:

通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操

通过这个命令查看log,两者差距不大。

2.3 通过mysqlbinlog命令解析

执行的命令分别如下

指定路径/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v 指定路径/mysql_log/mysql3306_bin.000011

指定路径/bin/mysqlbinlog --no-defaults --base64-output=decode-rows -v 指定路径/mysql_log/mysql3306_bin.000012

我们可以看到Row模式下的binlog记录丰富的多,例如针对update的那条语句。

Row模式记录如下:

通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操

Statement模式记录如下:

通过 mysqlbinlog 和 grep 命令定位binlog文件中指定操

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f4f417a10d1f5003bc825d0de1da81df.html