改进了大型事务的 Binlog 处理
本提案由 AWS RDS Aurora MySQL 团队撰写。在本次讨论中,我们提出了一项优化,以提高大型事务的 binlog 写入和恢复性能。我们希望与社区合作,在上游 MySQL 中实现此性能优化。技术联系人为 Wu Xueting (@ams-binlog-replication)。## 简介大型事务对 MySQL 的二进制日志子系统提出了重大的性能挑战。当事务超出内存中的 binlog 缓存时,事件会溢出到本地临时文件。在提交时,必须将该文件的全部内容复制到最终的 binlog 文件中,这个过程与事务大小成正比,导致提交延迟增加,并增加与崩溃相关的恢复成本。Aurora MySQL 已实现了一项内部优化,通过直接将事件写入专用的远程 binlog 文件,并在提交时使用重命名操作来完成最终确认,从而消除了大型事务的数据复制瓶颈。此功能自 2020 年以来一直在生产环境中运行,大幅提高了写入性能,达到 6 倍,并将我们的 P99 崩溃恢复时间降低到所有 Aurora MySQL 客户的一个分钟内。受 Aurora MySQL 的启发,MariaDB 后来实现了类似的优化。我们认为 MySQL 将受益于相同的功能,并准备将我们的实现提交到上游 MySQL。## 问题陈述MySQL 当前的 binlog 架构处理大型事务如下:1. **内存缓存填满:** 事务事件被缓存在每个会话的 binlog 缓存中。当缓存超过 `binlog_cache_size` 时,事件会溢出到本地临时文件。2. **提交复制所有数据:** 在提交时,引擎将本地临时文件(可能多 GB)的全部内容复制到活动的 binlog 文件中。这使得提交延迟与事务大小成正比,并增加并发事务的组提交停滞时间。3. **恢复扫描完整文件:** 如果引擎在部分写入大型事务到 binlog 文件后发生崩溃,则恢复必须扫描整个 binlog 文件,以识别未完成的事务并确定 GTID 状态。对于多 GB 的文件,这可能需要数十分钟。## 解决方案我们提出了一项优化,其中大型事务直接将 binlog 事件写入持久存储上的专用临时文件,并使用重命名来完成提交,从而完全消除了数据复制瓶颈。### 写入协议当事务的 binlog 缓存超过可配置的阈值(默认:128 MB)时,引擎切换策略:1. **溢出到专用临时文件:** 迄今为止累积的所有事件都被刷入持久存储上的新临时 binlog 文件中。此事务的后续事件将直接写入此文件。我们建议使用类似 MariaDB 的 `binlog_large_commit_threshold` 系统变量来确定何时溢出。事务
内容来源: mysql/mysql-server