RDS AliSQL 面向 Binlog 的性能优化大揭密(下)——强效瓶颈消除

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介: 本篇将继续揭秘AliSQL在binlog高并发性能上做的企业级优化。

背景介绍


在上篇中,我介绍了MySQL官方解决IO问题的binlog group commit优化,并介绍了它的局限性(低并发下效果欠佳)。为此AliSQL引入了binlog in redo优化很好的解决了这个问题。最后一章中,我们提到了影响性能的另一个因素——串行flush binlog带来的瓶颈。


本篇我将继续揭秘AliSQL在binlog高并发性能上做的企业级优化——binlog parallel flush,并给出binlog性能优化的完整版本——binlog in redo V2。


如果您还没有看过上篇,请先阅读:RDS AliSQL 面向 Binlog 的性能优化大揭密(上)—— 极致 IO 优化


一、Binlog Parallel flush 优化

优化背景

Binlog Commit 瓶颈分析

1.png

当我们在MySQL官方代码上做sysbench时,可以看到如上图的耗时占比。在低并发下,redo log和binlog的IO操作耗时占大头,然而在高并发下,耗时占比的大头是 flush binlog操作,IO操作只占到 35% 左右。


这是因为MySQL的binlog group commit机制合并的是事务间的 IO,在并发数很少的时候,只能合并几个事务的 IO 操作,在并发数很多的时候,可以合并几百个事务的 IO 操作,差距非常明显。


从耗时占比可以看出,在高并发下,主要的性能瓶颈来自于flush binlog的操作。


MySQL 的 Binlog Flush 机制

2.png

MySQL的binlog flush主要包含上述步骤,总的来说可以分为两种操作。


  • 第2步和4步是一些解析和处理的动作,我们可以将其称为:事务准备binlog的操作;
  • 第3步和5步是写文件动作(只是写到page cache,并非真 IO),可以称为:事务写binlog的操作。


接下来我们从耗时和可并发性这两个维度来研究这两类操作。


耗时


事务准备binlog的操作在整个flush流程中耗时占比很大,其中GTID event对象的生成,binlog cache的解析和填补,都是繁重的CPU工作;

事务写binlog的操作,仅仅是从MySQL内存到page cache的一个内存拷贝操作,速度很快,耗时很短。


可并发性


事务准备 binlog 的操作是可以并发执行的,每个事务准备自己的 binlog,不会有任何的冲突,因为 GTID 和逻辑时钟还有事务在 binlog 中的位置早已在第一步分配好;


事务写 binlog 的操作是不可并发的,binlog 是一个事务型日志,这意味着在 binlog 文件中,一个事务的 binlog events 必须连续的放在一起。因此,写 binlog 文件时必须串行的,一个接一个的写。

3.png

不幸的是,MySQL 代码实现时,将上述两种操作混在了一起,导致整个 flush 阶段的两种操作,全部串行执行。这导致在高并发下,flush binlog 成为瓶颈。


我们的优化目标是,将 flush binlog 中准备 binlog 的部分拆出来,让每个事务并行执行,以优化性能。


Binlog Flush 的并行化改造

4.png

为了将第一类操作改造的可并行,引入一段预先分配好的内存空间叫做 binlog buffer。Flush binlog 阶段,每个事务串行在 binlog buffer 中分配好空间后,就可以并行的准备自身的 binlog 内容,并写入 buffer 中。随后,再由后台线程将 binlog buffer 按顺序写进 binlog 文件。


并行 Flush Binlog 的流程


在 binlog parallel flush 架构下,flush binlog 的操作被分为了三个部分,分别是串行部分,并行部分和异步线程部分。

5.png

串行部分

  • 分配 buffer 中的空间;
  • 分配 Gtid 和 逻辑时钟。


并行部分

  • 生成 GTID event 并写到 Binlog buffer;
  • 解析 binlog cache 中的 binlog events,填充 postion 和 checksum,并写入 binlog buffer 中。


异步线程部分

  • 由异步的 writer 线程,负责将 binlog buffer 中准备好的部分写入 binlog 文件;
  • 由异步的 Syncer 线程,负责将 binlog 文件持久化。


合并 Redo Log IO

6.png

前面我们对于 binlog flush 的并行优化,大大提升了事务的并发度,这对于 flush binlog 来说是大大缓解了瓶颈。但是对于 redo log 来说,并发执行把原先由 binlog group commit 合并在一起的的 redo IO 又分开了,会导致了较严重的 log write up to 热点。


为此,我们继续保留 MySQL 原有的 binlog group commit 优化,在组内由 leader 串行的执行每个事务的 flush 动作,在组与组之间并发执行 flush。


Binlog Parallel Flush 架构

7.png

上图是 binlog parallel flush 的最终架构。进入提交阶段的事务会被分成多个组,每个组有一个 Leader,Leader 负责执行本组所有事务的提交操作,包括写 binlog buffer,sync redo 和等待异步线程的操作。根据 sync_binlog 参数的取值,leader 会选择等待 writer 或 syncer 线程。多个事务组之间,不同组的 leader 可以并发的执行 flush 动作。


性能测试

8.png

上图中红色曲线是 MySQL 的性能表现,橙色曲线是 AliSQL 使用 binlog parallel flush 后的性能表现。可以看到,在使用双一配置的高可靠场景,使用 parallel flush 可将峰值性能提升 56%;在使用 (0, 2) 的高性能场景,即 sync_binlog = 0,innodb_flush_log_at_trx_commit = 2 的场景下,峰值性能提升幅度可以达到 61%。


二、Binlog in redo V2 优化


上篇提到的 binlog in redo 优化是针对双一场景的 IO 优化,下篇提到的 parallel flush 优化可以应用于双一和(0,2)两种配置。也就是说,在双一场景下,两种优化都可以发挥作用,因此在双一场景下,我们同时使用两种优化思路,完成了 binlog in redo V2 优化。


Binlog in redo V2 架构

9.png

上图是 binlog in redo 优化与 parallel flush 优化结合后的架构图。进入提交阶段的事务会被分成多个组,每个组有一个 Leader,Leader 负责执行本组所有事务的提交操作,包括写 binlog buffer,写事务的 binlog 到 redo log,持久化 redo log 的操作。


随后,事务组结束,每个事务并发的进行自己的 innodb commit。由于 binlog 已经有 redo log 来保护,因此事务提交不需等待 sync 线程完成,原理上来讲也不需等待 writer 线程完成,不会有 crash safe 问题。但是许多用户会订阅 binlog,如果事务已经返回成功,但是 binlog 中还暂时读不到这个事务,可能会影响下游的逻辑判断。


因此,我们将事务返回成功前是否等待 writer 线程,作为一个用户可配置的参数,选择等待则相关逻辑与优化前不会有任何变化,不等待性能更好。


Crash Recovery 机制

10.png

Binlog in redo V2 架构中,当实例 crash 后,binlog 中的内容有可能丢失,因此需要在重启后的 recovery 过程中补齐。


与 V1 不同,在 V2 中 binlog flush 阶段是并行的,这导致 binlog 在 redo log 中可能是乱序的。因此,我们引入一个 recovery buffer,恢复过程中先将 binlog 写到 buffer 中,再将 buffer 写入 binlog 文件中。这样就可以解决乱序的问题。


性能测试

11.png

Binlog in redo V2 能够全方面的优化双一配置下实例的性能。可以看到,在各种并发度下,实例的性能都有显著的提升。


总结


通过上篇讲述的合并 IO 和本篇讲述 binlog 并行写这两种思路,我们对 binlog 提交阶段做了全方位的优化。AliSQL对比MySQL有了全方位,全场景的性能领先

12.png

以上是在 sysbench 的两种不同的业务脚本下,MySQL 和使用 binlog commit 优化的 AliSQL 的性能曲线对比。可以看到,无论是高可靠的(1,1)配置,还是高性能的(0,2)配置,AliSQL 都有着显著的性能提升。


如果您使用 (1, 1) 的高数据可靠性配置,推荐直接使用 Binlog in redo V2 优化,能够适应各种业务压力,带来六成左右的写性能提升;如果您使用 (0, 2) 的高性能推荐使用 Binlog parallel flush 优化,能够讲写性能峰值再提升流程左右。


通过本系列提到的优化手段,AliSQL 在各业务场景,各种数据可靠度,各种并发度下,都取得显著的性能提升。我们能够在同样的资源下,成倍的增大 qps,可以显著降低用户的使用成本。本系列中的所有优化,都会在 RDS MySQL 8.0 的最新版本中上线,欢迎大家使用。


作者简介

武根泽(子堪),RDS MySQL内核团队核心研发,擅长MySQL内核代码研发,性能调优和技术问题探索,在MySQL Binlog,Innodb等领域多有涉猎。关于RDS MySQL内核方面的问题,欢迎邮件联系: vogts.wangt@alibaba-inc.com 咨询。


 / End /  

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
20天前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
22 2
|
20天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的binlog日志文件
MySQL的binlog日志记录了所有对数据库的更改操作(不包括SELECT和SHOW),主要用于主从复制和数据恢复。binlog有三种模式,可通过设置binlog_format参数选择。示例展示了如何启用binlog、设置格式、查看日志文件及记录的信息。
122 6
|
1月前
|
存储 缓存 负载均衡
mysql的性能优化
在数据库设计中,应选择合适的存储引擎(如MyISAM或InnoDB)、字段类型(如char、varchar、tinyint),并遵循范式(1NF、2NF、3NF)。功能上,可以通过索引优化、缓存和分库分表来提升性能。架构上,采用主从复制、读写分离和负载均衡可进一步提高系统稳定性和扩展性。
42 9
|
1月前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志(Redo Log)和二进制日志(Binary Log)是两种重要的日志系统。重做日志主要用于保证事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务更改。二进制日志则记录了数据库的所有逻辑变化操作,用于数据的复制、恢复和审计。两者在写入时机、存储方式、配置参数和使用范围上有所不同,共同确保了数据库的稳定性和可靠性。
|
3月前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
643 15
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
3月前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
397 11
|
2月前
|
存储 关系型数据库 MySQL
MySQL中的Redo Log、Undo Log和Binlog:深入解析
【10月更文挑战第21天】在数据库管理系统中,日志是保障数据一致性和完整性的关键机制。MySQL作为一种广泛使用的关系型数据库管理系统,提供了多种日志类型来满足不同的需求。本文将详细介绍MySQL中的Redo Log、Undo Log和Binlog,从背景、业务场景、功能、底层实现原理、使用措施等方面进行详细分析,并通过Java代码示例展示如何与这些日志进行交互。
242 0
|
2月前
|
存储 关系型数据库 MySQL
MySQL性能优化实践指南
【10月更文挑战第16天】MySQL性能优化实践指南
155 0

相关产品

  • 云数据库 RDS MySQL 版
  • 云数据库 RDS