当前位置: 首页 > news >正文

阿里思想学习-如何优化大事务提交

参考文章:大事务提交优化_云数据库 RDS(RDS)-阿里云帮助中心


介绍一下BinlogCache

binlogCache写入流程介绍

binlog cache:每个客户端连接都有一个线程级别的binlog缓存区,用于临时存储事务产生的binlog事件

事务提交过程

  1. 事务执行期间:所有DML操作产生的binlog会先写入binlog cache
  2. 事务提交时:binlog cache中的内容才会写入磁盘的binlog文件
  3. 写入后:binlog cache会被清空

大事务导致Binlog Cache写满

事务过大

  1. 当单个事务包含大量DML操作(如批量插入/更新数十万行)
  2. 产生的binlog事件总量超过了binlog cache的容量

Cache无法动态扩展

  1. binlog cache大小由binlog_cache_size参数决定(默认32KB)
  2. 事务执行期间cache大小固定,不会自动扩容

Cache写满后的行为

  1. 当cache空间不足时,MySQL会报错:"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage"
  2. 事务会被回滚

既然BinlogCache是线程级别的,那为什么说大事务会阻塞其他事务呢?

Binlog Cache写入Binlog的时候要拿到锁,也就是拿到二进制日志全局锁-binlog group commit

拿到这个锁才能往binlog文件写入日志,大事务会导致写日志的时间非常长,从而阻塞同步

其他事务必须等待这个锁释放才能提交,导致所有新事务在提交阶段被阻塞


大事务提交优化

文章来源:

大事务提交优化_云数据库 RDS(RDS)-阿里云帮助中心


什么是大事务

在有大事务的业务场景中,大事务提交时常会出现Binlog耗时过长、实例长时间不可写或阻塞的问题

RDS MySQL引入的Binlog Cache Free Flush功能,优化了大事务提交的速度

解决了因大事务提交时间过长导致的实例抖动、长时间不可写的问题,提升了实例的稳定性

功能说明:

由于Binlog的串行写入机制大事务不仅自身写入Binlog缓慢,还会阻塞其他事务提交

本功能优化了大事务提交时的Binlog写入机制,使提交速度不再受Binlog Event数量影响,始终保持高效


解决了什么问题?

本功能解决了以下典型问题:

  1. 超大事务阻塞实例,导致其他事务无法及时提交
  2. 大事务引发大量IO消耗,造成IO资源耗尽并拖慢查询等业务
  3. 大事务导致小事务执行变慢,引发活跃连接激增和性能抖动,严重时可能触发雪崩效应导致实例不可用。
  4. 频繁执行大事务持续引发业务流量的性能抖动

使用说明

使用说明:

  1. 新建实例:Binlog Cache Free Flush功能默认开启。
  2. 存量实例:通过设置全局系统变量loose_binlog_cache_free_flush可开启该功能,参数修改后立即生效,无需重启实例。
  3. 相关参数:

loose_binlog_cache_free_flush_limit_size :开启Binlog Cache Free Flush功能后,当事务的Binlog超过该参数值,提交时会将Binlog Cache临时文件转为Binlog正式文件。默认值:256 MB,取值范围: 20971520~18446744073709551615 (单位:字节)


问题分析

当MySQL实例执行大事务时,慢查询日志可能记录到某些本应快速完成的语句(如COMMIT)出现异常延迟

原因是另一个线程的大事务因Binlog串行写入机制导致资源竞争

大事务不仅自身写Binlog耗时较长,还会阻塞其他事务的Binlog提交,从而引发全局串行化延迟

运行sysbench oltp_write_only时,在每5秒执行一次产生512 MB Binlog的大 UPDATE 操作后,观察到以下现象:

  • 每次大UPDATE提交时,TPS(每秒事务数)剧烈下降
  • 抖动时长与Binlog大小正相关:事务产生的Binlog越大,对其他业务的延迟影响越显著

下图直观的展示了大事务对线上运行业务的影响

UPDATE 相关操作:

CREATE TABLE t_large (a INT, b LONGTEXT) ENGINE = InnoDB;# 插入一行数据包含256 MB文本,UPDATE时产生的Binlog events是512 MB。
INSERT INTO t_large VALUES (1, repeat('a', 256000000)); UPDATE t_large SET a = a + 1;

实现原理

Binlog Cache介绍

Binlog Cache是一块会话级别的临时空间

即为每一个会话建立一个Binlog Cache,用来暂存Binlog events

Binlog Cache由内存缓存(Buffer)和临时文件(Temp File)两部分组成,其中内存缓存的大小由binlog_cache_size参数控制

当事务比较大,内存缓存被写满之后,事务的events就会被记录到临时文件中

事务在执行过程中,会将自己生成的events暂存在Binlog Cache中

事务在提交时,需要按顺序从Binlog Cache中读出一个个Event,并且更新events的end_pos(结束位置)和checksum(校验和),然后将其写到Binlog文件中

为了保证事务在Binlog文件中的连续性,整个过程是加锁进行的,即一个事务写Binlog文件时,其他事务都会被阻塞


大事务写Binlog带来的问题

对于非常大的事务,其使用的Binlog Cache可能会达到几十个GB,在提交事务期间写Binlog的过程耗时很长,并且对实例影响极大,主要包括以下两点:

  1. 大事务写Binlog过程中,会持有Binlog写锁,期间整个实例将处于不可写状态
  2. 大事务写Binlog的过程会消耗大量IO资源,在IO资源有限的场景下,可能导致整个实例夯住(hang)

Binlog Cache Free Flush优化

AliSQL对Binlog Cache的临时文件进行了改造,使其具备了直接转为Binlog文件的能力

开启本功能后,在大事务提交时会将Binlog Cache临时文件直接转化为Binlog正式文件

这个过程的耗时很短,并且IO资源消耗很少,彻底解决了大事务写Binlog对实例的影响


对Binlog Cache的改造

为了使Binlog Cache的临时文件能够直接转化为Binlog正式文件,AliSQL对Binlog Cache的使用方式进行了改造。主要包括以下两点:

  • 在写Binlog Cache的临时文件时,在文件头部预留出一部分空间。在临时文件转Binlog正式文件过程中,这部分空间用于存放Binlog头部的events
  • 在写Binlog Cache时,每个events都根据预留空间的大小计算自己的end_pos

阿里SQL的创新解决方案

阿里云的优化思路是:让临时文件可以直接"变身"为正式binlog文件省去中间的读取-计算-写入过程


关键设计:"预留头部空间"

  1. 预留请求头空间的作用

在创建binlog cache临时文件时,预先在文件开头保留一定空间

这个空间专门用来存放binlog文件的标准头部信息

  1. 写入events时的特殊处理

每个event写入临时文件时,其位置计算会考虑预留空间的大小

即实际写入位置 = 逻辑位置 + 预留空间大小

这样event之间的相对位置关系保持不变

  1. 提交时的转换过程

当需要将临时文件转为正式binlog时:


在预留空间写入标准的binlog文件头

修改文件元数据(如inode信息)将其标记为正式binlog文件
更新binlog索引文件

整个过程几乎不涉及数据移动,只是【重命名+补头】


为什么这个设计能提升性能

  1. 避免数据拷贝

传统方式需要读取GB级临时文件并重新写入

新方案直接重用已有文件,节省大量IO

  1. 减少计算开销

不需要重新计算每个event的end_pos和checksum

因为event位置在写入时已经考虑了预留空间

  1. 缩短锁持有时间

转换过程极快(毫秒级)

大幅减少binlog写锁的持有时间


类比解释

可以把这个过程想象成写一封信:

传统方式

  1. 先在草稿纸上写完整封信
  2. 然后重新在正式信纸上誊写一遍
  3. 最后加上正式信件的抬头和落款

阿里云优化方式

  1. 先在纸上预留出抬头的位置
  2. 直接从预留位置之后开始写正文
  3. 完成后只需补上抬头
  4. 把整张纸直接作为正式信件

这种【预留空间+原地转换】的设计,是大事务优化性能提升的关键所在


大事务优化-简单总结

大事务的4个问题:

超大事务阻塞实例,导致其他事务无法及时提交

大事务引发大量IO消耗,造成IO资源耗尽并拖慢查询等业务

大事务导致小事务执行变慢,引发活跃连接激增和性能抖动,严重时可能触发雪崩效应导致实例不可用。

频繁执行大事务持续引发业务流量的性能抖动

Binlog Cache:

事务进行时是用Binlog Cache暂存的

当事务写完要提交的时候,就要写入Binlog文件,写入Binlog文件是要争夺Binlog写锁然后串行执行的

所以大事务会阻塞其他事务的持久化和提交

大事务还会造成大量的磁盘IO,给CPU带来压力

由于Binlog的加锁和串行写入机制大事务不仅自身写入Binlog缓慢,还会阻塞其他事务提交

当事务比较大,内存缓存被写满之后,事务的events就会被记录到临时文件中

事务在执行过程中,会将自己生成的events暂存在Binlog Cache中

事务在提交时,需要按顺序从Binlog Cache中读出一个个Event,并且更新events的end_pos(结束位置)和checksum(校验和),然后将其写到Binlog文件中

阿里的RDS对Binlog Cache的改造:

阿里的RDS的Binlog Cache Free Flush功能优化了大事务提交时的Binlog写入机制,使提交速度不再受Binlog Event数量影响,始终保持高效

AliSQL对Binlog Cache的临时文件进行了改造,使其具备了直接转为Binlog文件的能力

大事务提交时会将Binlog Cache临时文件直接转化为Binlog正式文件

这个过程的耗时很短,并且IO资源消耗很少,彻底解决了大事务写Binlog对实例的影响

通过【预留空间+原地转换】优化

传统方式需要读取GB级临时文件并重新写入,而新方案直接重用已有文件节省大量IO,从而让写锁占用时间也减少了

http://www.lryc.cn/news/595502.html

相关文章:

  • JAVA后端开发—— JWT(JSON Web Token)实践
  • c语言----文件操作
  • 上海RISC-V峰会-香山开源RISC-V CPU随想随记
  • 软件测试 —— A / 入门
  • 从0开始学习R语言--Day53--AFT模型
  • react-window 大数据列表和表格数据渲染组件之虚拟滚动
  • Spring关于依赖注入的几种方式和Spring配置文件的标签
  • 面试总结第54天微服务开始
  • Spring处理器和Bean的生命周期
  • 线程池与ThreadPoolExecutor源码解析(上)
  • 暴力破解练习
  • Pandas - JSON格式数据操作实践
  • AV1平滑缓冲区
  • iostat的使用说明
  • MongoDB 查询时区问题
  • GUI简介
  • Kafka 如何优雅实现 Varint 和 ZigZag 编码
  • 【每天一个知识点】非参聚类(Nonparametric Clustering)
  • 期权到期会对大盘有什么影响?
  • 如何用 Z.ai 生成PPT,一句话生成整套演示文档
  • 【操作篇】群晖NAS用root权限直接访问系统分区文件
  • 圆柱电池自动分选机:全流程自动化检测的革新之路
  • 83、形式化方法
  • 淘宝获取商品分类接口操作指南
  • MySQL介绍和MySQL包安装
  • accelerate 在Pycham中执行的设置方法
  • 泛型:C#中的类型抽象艺术
  • Telnet远程登录配置全流程详解
  • 大模型为什么出现幻觉?
  • 二分查找:区间内查询数字的频率