MySQL8.0 binlog进阶

Hulong Cui 2022-10-28
224

MySQL8.0经过这几年的操揉磨治,已经上升到海平面了。其中binlog也悄然无声带来了不一样的变化。高可用核心复制基础binlog变化更应该进一步了解。从参数入手,了解带来的变化。

slave回放算法

slave_rows_search_algorithms
当使用基于 row-based复制格式的副本应用UPDATE或DELETE操作时,它必须在相关表中搜索匹配的行。用于执行此过程的算法使用表的一个索引作为首选执行搜索,如果没有合适的索引则

  • 5.7使用表扫描(默认值:TABLE_SCAN,INDEX_SCAN)
  • 8.0使用哈希表(默认值:INDEX_SCAN,HASH_SCAN)。
    image.png

该算法首先评估表定义中的可用索引,以确定是否有任何合适的索引可以使用,如果有多种可能性,则判断哪个索引最适合操作。该算法忽略以下类型的索引:

1.全文索引
2.隐藏索引
3.计算索引
4.多值索引
5.包含的event语句中,不包含索引字段(跟记录binlog内容有关,参数对应binlog_row_image)

记录语句引用如果有合适的索引,则从候选索引中选择一个索引,其优先级顺序如下:

1.主键。
2.唯一的索引,其中索引中的每一列都有一个NOT NULL属性。如果有多个这样的索引可用,
  算法将选择这些索引中最左边的一个。
3.其他指数。如果有多个这样的索引可用,算法将选择这些索引中最左边的一个。

如算法无法找到合适的索引,或者只能找到非唯一的索引或包含空值的索引,则使用哈希表来帮助识别表记录。

该算法创建一个哈希表,其中包含UPDATE或DELETE操作中的行,键作为行的完整前图像。然后,算法遍历目标表中的所有记录。对于目标表中的每条记录,它确定该行是否存在于散列表中。如果在哈希表中找到该行,则更新目标表中的记录,并从哈希表中删除该行。当目标表中的所有记录都被检查后,算法验证哈希表现在是否为空。如果哈希表中还有任何不匹配的行,算法返回错误ER_KEY_NOT_FOUND并停止复制应用程序线程。

可以说到主从复制架构下从库回放机制中,存在唯一性质的键,保持之前一致。如无主键的情况,8.0版本已经脱离全表扫描的范围。这种情况利和弊两者兼容,不用说hash算法,对性能来说是最优的,并且在所有场景下都能正确工作。

binlog清除机制

  • binlog_expire_logs_seconds
    binlog可以以秒为单位进行清理,之前参数是按照expire_logs_days天为删除,有时因1天当中,可能会生成几百G的binlog日志,导致空间不够用,手动或脚本清理。现在不需要那麻烦。更贴合现状的解决方案。

  • binlog_expire_logs_auto_purge
    binlog用于控制日志自动清理机制,MySQL 8.0.29开始,可以通过将binlog_expire_logs_auto_purge系统变量设置为OFF来禁用binlog的自动清除。这优先于binlog_expire_logs_seconds的任何设置。

按照代码注释记录:expire_logs_days准备废弃,binlog_expire_logs_auto_purge 和binlog_expire_logs_seconds 需要配合使用。

    3  Warning	1287	'@@expire_logs_days' is deprecated and will be removed 
    in a future release. Please use binlog_expire_logs_seconds instead.


# ASSERT: If binlog_expire_logs_auto_purge is set to ON, then the server
#         MUST purge automatically binary log files according to the
#         binlog_expire_logs_seconds setting.
#

#
# ASSERT: If binlog_expire_logs_auto_purge is set to ON and both
#         binlog_expire_logs_seconds and expire_logs_days are set to 0,
#         then binary log files SHALL NOT be automatically purged.
#

binlog加密

  • binlog_encryption
    为此服务器上的binlog和relay文件启用加密,必须安装并配置一个密匙环插件来提供MySQL服务器的密匙环服务。MySQL Keyring

  • binlog_rotate_encryption_master_key_at_startup

     ON:每当服务重新启动时,将生成一个新的加密密钥,并将其用作所有后续binlog文件和relay的主密钥。
     OFF:将再次使用现有的binlog主密钥
    

binlog记录事件大小

  • binlog_row_event_max_size
    对于binlog记录的事件,最大大小的软限制(以字节为单位)。普遍情况,将存储在binlog中的行分组为大小不超过此设置默认值8192字节的事件。如果不能拆分事件,则可以超过最大大小(64bit:17179869184GB,32bit:4GB)。

binlog列字段记录

  • binlog_row_metadata
    配置在使用基于行的日志记录时向binlog添加的表元数据的数量。当设置为默认值MINIMAL时,只记录与SIGNED标志、列字符集和 地理空间类型Geometry类型相关的元数据。当设置为FULL时,将记录表的完整元数据,如列名、ENUM或set字符串值、PRIMARY KEY信息等。

扩展metadata的目的:

1.当元数据的表结构与源的表结构不同时,副本使用元数据来传输数据。
2.外部软件可以使用元数据解码行事件并将数据存储到外部数据库(如数据仓库)。

binlog对于JSON处理

  • binlog_row_value_options
    binlog记录修改JSON文档的一小部分内容,而不是写入完整的JSON值。适用于UPDATE语句,它使用JSON_SET()、JSON_REPLACE()和JSON_REMOVE()的任意序列修改JSON列。如果服务器无法生成部分更新,则使用完整文档。
    默认值是一个空字符串,这禁止使用该格式。
    还是对MySQL支持JSON数据做了一定的改善。

binlog压缩

  • binlog_transaction_compression
    binlog启用压缩机制。主节点压缩的binlog信息,传输到从节点将以压缩状态写入relay log,因此它们间接受益于复制拓扑中其他服务器执行的压缩。

  • binlog_transaction_compression_level_zstd
    binlog内容的压缩级别,随着压缩级别的增加,数据压缩比也会增加,这将减少事务有效负载所需的存储空间和网络带宽。但是,数据压缩所需的工作量也会增加,会占用原始服务器上的时间、CPU和内存资源。压缩工作量的增加与数据压缩比的增加没有线性关系。

binlog精准时间记录

  • original_commit_timestamp
    供内部复制使用。当在副本上重新执行事务时,这将被设置为事务在原始源上提交的时间,以自epoch以来的微秒为单位。这允许在整个复制拓扑中传播原始提交时间戳。复制延时的测量。

original_commit_timestamp: 事务在 master 提交 binlog 的时间戳(微秒),该时间戳每个节点都是一样的。
immediate_commit_timestamp: 事务在 slave(包括中继节点)提交 binlog 的时间戳(微秒),该时间戳在 relay log 中与 original_commit_timestamp 一样,在 slave 的 binlog 是完成回放的时间戳。

binlog事件解析内容:

#221028  8:58:55 server id 129  end_log_pos 276 CRC32 0x17f79afd        GTID    last_committed=0        sequence_number=1       rbr_
only=yes    original_committed_timestamp=1666918735086611   immediate_commit_timestamp=1666918735086611     transaction_length=390
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1666918735086611 (2022-10-28 08:58:55.086611 CST)
# immediate_commit_timestamp=1666918735086611 (2022-10-28 08:58:55.086611 CST)
/*!80001 SET @@session.original_commit_timestamp=1666918735086611*//*!*/;
/*!80014 SET @@session.original_server_version=80031*//*!*/;
/*!80014 SET @@session.immediate_server_version=80031*//*!*/;
SET @@SESSION.GTID_NEXT= '22228e8c-b0ee-11ec-a2d1-00163e23e2cc:70'/*!*/;

总结来说 就是将事务原始提交时间写在binlog 中,提交时间在复制链路上传递,使得 slave 可以计算事务延迟,更全面更精准

总结

从上述MySQL8.0的binlog变化中,选择最受益的项的话,必然是以下这3个:

1.slave_rows_search_algorithms:hash替代 table scan
2.binlog_expire_logs_seconds:秒级别清理机制
3.original_commit_timestamp:复制延迟观测新方式,更全面更精准binlog记录。

对于这些日常运维和解决问题提供的更好的助力。

最后修改时间:2022-12-27 13:26:49
「喜欢文章,快来给作者赞赏墨值吧」
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论