binlog从格式上有两种格式,statement和row,还有一种存储模式为mixed,前两者混合的。
如何设置binlog的格式?
通过参数binlog_format设置
假设有这张表
mysql> CREATE TABLE `t` (`id` int(11) NOT NULL,`a` int(11) DEFAULT NULL,`t_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `a` (`a`),KEY `t_modified`(`t_modified`)) ENGINE=InnoDB;insert into t values(1,1,'2018-11-13');insert into t values(2,2,'2018-11-12');insert into t values(3,3,'2018-11-11');insert into t values(4,4,'2018-11-10');insert into t values(5,5,'2018-11-09');
当执行以下删除语句时:
delete from t /*comment*/ where a>=4 and t_modified<='2018-11-10' limit 1;
statement
内容查看
可以使用show binlog events in 'master_binlog.000001'查看binlog的内容
- BEGIN和COMMIT对应,表示中间是一个事务
- use test这条命令是MySQL自动添加的,保证从库去执行的时候能知道要操作哪个库
- COMMT后面歇着xid,这个xid就是我们在MySQL日志系统文章中讲解的用来关联redo log和binlog的
问题
可能会导致主从数据不一致,因为statement格式是记录原来啊的SQL,从库也是去重放SQL,在这个语句中,
- 如果使用索引是a,那么会根据索引a找到第一个满足条件的行,也就是a=4
- 如果使用的索引是t_modified,那么删除的就是t_modified=’2018-11-09’也就是 a=5 这一行
因此从库重放会有风险。
row
内容查看

binlog中没有了原SQL,而是替换成了Table_map和Delete_rows:
- Table_map,用于说明接下来操作的表是test库的表t
-
详细内容查看
需要借助mysqlbinlog工具:
--start-position指定从这个位置的日志开始解析 mysqlbinlog -vv data/master.000001 --start-position=8900;
重要内容解析 server id 1,表示这个事务是在server_id=1的这个库上执行的
- 每个event都有CRC32,是因为把参数binlog_checksum设置成了CRC32
- @1、@2、@3表示的字段id、a、t_modified
- binlog_row_image默认值为FULL,因此Delete_event里面,包含了删掉的行的所有字段的值,如果把binlog_row_image设置为MINIMAL,则只会记录必要的信息,在这个例子里,就只会记录id=4这个信息
- 最后的Xid用于表示这个事务被正确地提交了
由于binlog记录了真实删除的行的主键id,这样binlog传到备库去的时候,就肯定会删除id=4这行,不会有主备删除行不一致的问题
mixed
由于row格式存储的内容过多,而statement又有可能会导致主从数据不一致,因此MySQL就取了一个折中的方案,MySQL自己会判断这条SQL语句是否可能引起主备不一致,如果有可能就用row格式,否则就用statement格式。
binlog_row_image
MySQL5.6新增的参数,默认值是FULL,binlog格式必须为row格式或者mixed格式
前镜像,即数据库表中修改前的内容。
后镜像,即数据库表中修改后的内容。
- FULL,binlog日志记录所有前镜像和后镜像。
- 如果数据出现误操作,可以通过flashback或者binlog2sql等快速闪回工具恢复数据
- 在数据列比较大的情况下,在大量的update、delete操作时,binlog盘增长会很快
- MINIMAL,binlog日志的前镜像只记录唯一识别列(唯一索引列、主键列),后镜像只记录修改列。
- 可以节省不少磁盘空间,节省一定的IO,
- 由于前镜像不记录修改列,只在后镜像记录修改列,如果数据出现误操作,必然不能通过flashback或者binlog2sql等快速闪回工具恢复数据
- NOBLOB,binlog记录所有的列,就像full格式一样。但对于BLOB或TEXT格式的列,如果他不是唯一识别列(唯一索引列、主键列),或者没有修改,那就不记录。
- 表中TEXT和BLOB等大字段如果不修改,就不记录前后的镜像了,其他小字段的列的修改依然记录前后镜像,一般大字段消耗的磁盘空间是非常大的,可以节省不少磁盘空间,如果表中没有大字段,NOBLOB和FULL格式并没有区别,如果数据出现误操作,可以通过flashback或BinLog2SQL等快速闪回工具恢复数据。
