102023.02

技术分享丨 关于MySQL binlog解析那些事

2023.02.10

为一名数据库DBA,查看解析 binlog 是日常工作的一部分。

但如果 binlog 文件很多呢?如何高效解析 binlog,能否同时解析多个binlog?这个问题至关重要。

本文就针对能否同时解析多个binlog、innodb_buffer_pool_instances设置多少合适这两个问题进行探讨。


可以同时解析多个binlog吗?


首先,答案是肯定的。

其次,当我们采用这种方式解析binlog时 $ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=2000 binlog.000001 binlog.000002 时,它的工作方式是这样的:

  • 指定binlog停止位置的参数,只对最后一个binlog 文件生效(指定开始位置则针对第一个文件生效);

  • 前面的binlog文件则是全量解析;

  • 如果没有匹配的 stop-position,则向上取值最接近的position;

  • 如果同时多次指定 start-position 或 stop-position,则以最后一次指定的为准;

  • 如果指定的 stop-position 超出binlog的最大范围,则会发出WARN;

  • 如果 stop-position 指向的最后一个event是 table_map,也会发出WARN。

我们分别举几个例子看下:


a.解析多个文件,但每次指定顺序不同

$ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=1500 mgr01.001205 mgr01.001206 mgr01.001207 > /tmp/b1$ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=1500 mgr01.001206 mgr01.001205 mgr01.001207 > /tmp/b2$ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=1500 mgr01.001207 mgr01.001206 mgr01.001205 > /tmp/b3$ ls -la /tmp/b*-rw-r--r-- 1 root root 5027246 Oct 30 19:36 /tmp/b1-rw-r--r-- 1 root root 5027246 Oct 30 19:21 /tmp/b2-rw-r--r-- 1 root root 3126107 Oct 30 19:22 /tmp/b3# 虽然 /tmp/b1、/tmp/b2文件大小看起来一样,但其MD5SUM是不同的
$ md5sum /tmp/b*ac8e223d417310e02366d5cbfcb4a882  /tmp/b16a09fddd30ab210f3370613aff85571c  /tmp/b29e2e70e1cee5fb10860c66c2ef770c0a  /tmp/b3


b.指定stop-position,但实际会向上取值

$ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=1500 mgr01.001205 mgr01.001206 mgr01.001207 > /tmp/b1# 查看文本格式的binlog,发现end_log_pos最大值超过了1500$ grep end_log_pos /tmp/b1 | tail
...
#221030 19:17:12 server id 3306  end_log_pos 1208 CRC32 0x8e5ca346      Table_map: `sbtest`.`sbtest5` mapped to number 926#221030 19:17:12 server id 3306  end_log_pos 1624 CRC32 0x0059617f      Update_rows: table id 926 flags: STMT_END_F



c.指定stop-position对应的是table_map event,会发出WARN


$ mysqlbinlog -vvv --base64-output=decode-rows --start-position=4 --stop-position=1208 mgr01.001205WARNING: The range of printed events ends with a row event or a table map event that does not have the STMT_END_F flag set. This might be because the last statement was not fully written to the log, or because you are using a --stop-position or --stop-datetime that refers to an event in the middle of a statement. The event(s) from the partial statement have not been written to output.#221030 19:17:12 server id 3306  end_log_pos 1141 CRC32 0x5226ecd8      Rows_query
# UPDATE sbtest7 SET c='85585077000-51806678786-29036174562-00737528630-90333366602-59672213053-90973506235-01305133574-41639459483-63273277428' WHERE id=83642# at 1141#221030 19:17:12 server id 3306  end_log_pos 1208 CRC32 0x96186542      Table_map: `sbtest`.`sbtest7` mapped to number 928ROLLBACK /* added by mysqlbinlog */ /*!*/;SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

更多的规则自己摸索吧 :)




innodb_buffer_pool_instances 设置多少合


将innodb buffer pool拆分成多个instance,每个instance有独立的free lists、flush lists、LRU list,也有独立的mutex,有助于提升InnoDB并发性能。


当 innodb_buffer_pool_size 小于1GB时,innodb_buffer_pool_instances 默认值为1。反之,则默认值为8。

instance的设置尽量符合几个原则:

  • 首先,innodb_buffer_pool_size 大于1GB时,设置多个instance才有意义;

  • 拆分后,每个instance也尽量大于1GB;

  • 拆分后,每个instance必须是128MB(innodb_buffer_pool_chunk_size定义的值)的整数倍。

 编辑