Binlog格式为ROW 详解

一、基于RBR行复制是与记录的位置有关,binlog里只记录了了相关表发生变化的列的数据,对此引入了4个事件:Table_map、Write_rows、Update_rows、Delete_rows。

二、在主库上一条语句执行完,在binlog中记录成:

Table_map事件(包含表的ID、表名和列的类型,没有列名),再后面是3个事件,最后是结束标志为STMT_END_F

下图是mysqlbinlog后的结果:

150241622.png

show binlog eventsin 'mysql-bin.001430' from 12893999 limit 4 \G

150257617.png


对于ROW格式的binlog在slave端的执行过程

1.SQL进程从relaylog日志读取事件

2.对于Table_map事件,SQL进程提取表信息,保存表的定义

3.锁定要更改的表,并检查master和slave上的结构是否一致

4.如果表结构不一致,则停止复制,否则继续执行,直到遇到STMT_END_F结束此事件的复制

对于Update_rows、Delete_rows事件,SQL进程首先要定位到具体的行,查找步骤如下:

1.主键优先

优先选装slave上的主键,当找到匹配的主键值的时候,就认为已经找到匹配的行,行的其他列的内容则不去匹配。

2.非空唯一索引扫描,只比较键值

3.其他索引或全表扫描:此时会比较整个行的数据在master和slave上是否一致(确实能保证主从复制的一致性,但也是最慢的)。

最近公司建从库备份数据(数据就不一致了),导致从库在运行一段时间后,报错,导致SQL进程中断:

150313723.png

Last_Errno: 1032
Last_Error: Could not execute Delete_rows event on table mdb.item_info; Can't find record in 'item_info', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.001430, end_log_pos 12893999