参考资料
https://mariadb.com/kb/en/binlog-event-checksums/
https://dev.mysql.com/doc/refman/8.0/en/binary-log.html
从 MySQL5.6 开始,binlog_checksum 默认值 CRC32,此设置下写 binlog 时会为每个 event 写入一个校验值。当 binlog_checksum=NONE,则通过检查每个 event 的长度来验证写入 binlog event 的完整性。
启用 binlog_checksum 后,slave io 线程会检查通过网络接收到的 binlog event 的校验值是否正确,如果检查到损坏的 event,将停止复制并报错。
另外,还可以通过配置指定在以下两个地方通过校验值验证 event 的完整性:
- master_verify_checksum,默认值为 OFF,如果设置为 ON,则在从 master 上读取 binlog event 时,会进行校验。那具体什么场景会触发读取 binlog 呢?主要是以下两个地方:
- show binlog events 时
- binlog dump 线程向 slave 发送 binlog 时
- slave_sql_verify_checksum,默认值为 ON,在 slave sql 线程从 relay log 中读取 event 时,验证校验值。
默认情况下 mysqlbinlog 客户端程序在解析 binlog 文件时不会验证校验值,但是也可以使用 verify-binlog-checksum 参数进行校验。
总结
默认设置下,binlog_checksum 开启,slave io 线程在接收 binlog 时,以及 slave sql 线程在读取 relay log 时都会通过校验值来验证 event 的完整性。此默认行为,从库已经能保证收到的 binlog event 的完整性,且产生的消耗都在从库上,不影响主库。
因此,在默认设置下,主库在发送 binlog event 时是否验证校验值对从库没有影响,开启反而会对主库性能造成影响,因此 master_verify_checksum 保持默认值(关闭)即可。
举个生活中的例子:
发件和收件过程:收件方检查包裹是否完整,不完整拒收就行。也可以选择将检查提前到发件方,发件方检查到包裹不完整,不发就完了。在生活中,因为整个运输的时间比较长,发件的成本比较高,如果发件方进行检查,不完整的包裹直接不发送,则可以避免这部分发件的成本。因此在这个过程中发件方、收件方都会检查包裹的完整性。
但是在 MySQL 中,主从间传输 binlog 的时间非常短,只消耗少量的 CPU、内存和网络,如果 binlog event 在发送时就不完整,从库收到时也很快可以检验到。如果主库在发送 binlog event 时就检验,则会消耗较多的 CPU,固然可以减少网络的消耗,但是一比较却是划不来的。因此建议只在从库进行检查。
网友评论