MySQL组提交group commit详解
作者:长烟慢慢 发布时间:2024-01-21 05:33:09
引 言
前提:
以下讨论的前提 是设置MySQL的crash safe相关参数为双1:
sync_binlog=1
innodb_flush_log_at_trx_commit=1
背景说明:
WAL机制 (Write Ahead Log)定义: WAL指的是对数据文件进行修改前,必须将修改先记录日志。MySQL为了保证ACID中的一致性和持久性,使用了WAL。
Redo log的作用: Redo log就是一种WAL的应用。当数据库忽然掉电,再重新启动时,MySQL可以通过Redo log还原数据。也就是说,每次事务提交时,不用同步刷新磁盘数据文件,只需要同步刷新Redo log就足够了。相比写数据文件时的随机IO,写Redo log时的顺序IO能够提高事务提交速度。
组提交的作用:
在没有开启binlog时
Redo log的刷盘操作将会是最终影响MySQL TPS的瓶颈所在。为了缓解这一问题,MySQL使用了组提交,将多个刷盘操作合并成一个,如果说10个事务依次排队刷盘的时间成本是10,那么将这10个事务一次性一起刷盘的时间成本则近似于1。
当开启binlog时
为了保证Redo log和binlog的数据一致性,MySQL使用了二阶段提交,由binlog作为事务的协调者。而 引入二阶段提交 使得binlog又成为了性能瓶颈,先前的Redo log 组提交 也成了摆设。为了再次缓解这一问题,MySQL增加了binlog的组提交,目的同样是将binlog的多个刷盘操作合并成一个,结合Redo log本身已经实现的 组提交,分为三个阶段(Flush 阶段、Sync 阶段、Commit 阶段)完成binlog 组提交,最大化每次刷盘的收益,弱化磁盘瓶颈,提高性能。
图解:
下图我们假借“渡口运输”的例子来看看binlog 组提交三个阶段的流程:
在MySQL中每个阶段都有一个队列,每个队列都有一把锁保护,第一个进入队列的事务会成为leader,leader领导所在队列的所有事务,全权负责整队的操作,完成后通知队内其他事务操作结束。
Flush 阶段 (图中第一个渡口)
首先获取队列中的事务组
将Redo log中prepare阶段的数据刷盘(图中Flush Redo log)
将binlog数据写入文件,当然此时只是写入文件系统的缓冲,并不能保证数据库崩溃时binlog不丢失 (图中Write binlog)
Flush阶段队列的作用是提供了Redo log的组提交
如果在这一步完成后数据库崩溃,由于协调者binlog中不保证有该组事务的记录,所以MySQL可能会在重启后回滚该组事务
Sync 阶段 (图中第二个渡口)
这里为了增加一组事务中的事务数量,提高刷盘收益,MySQL使用两个参数控制获取队列事务组的时机:
binlog_group_commit_sync_delay=N:在等待N μs后,开始事务刷盘(图中Sync binlog)
binlog_group_commit_sync_no_delay_count=N:如果队列中的事务数达到N个,就忽视binlog_group_commit_sync_delay的设置,直接开始刷盘(图中Sync binlog)
Sync阶段队列的作用是支持binlog的组提交
如果在这一步完成后数据库崩溃,由于协调者binlog中已经有了事务记录,MySQL会在重启后通过Flush 阶段中Redo log刷盘的数据继续进行事务的提交
Commit 阶段 (图中第三个渡口)
首先获取队列中的事务组
依次将Redo log中已经prepare的事务在引擎层提交(图中InnoDB Commit)
Commit阶段不用刷盘,如上所述,Flush阶段中的Redo log刷盘已经足够保证数据库崩溃时的数据安全了
Commit阶段队列的作用是承接Sync阶段的事务,完成最后的引擎提交,使得Sync可以尽早的处理下一组事务,最大化组提交的效率
缺陷分析:
本文最后要讨论的bug(可通过阅读原文查看)就是来源于Sync 阶段中的那个binlog参数binlog_group_commit_sync_delay,在MySQL 5.7.19中,如果该参数不为10的倍数,则会导致事务在Sync 阶段等待极大的时间,表现出来的现象就是执行的sql长时间无法返回。该bug已在MySQL 5.7.24和8.0.13被修复。
来源:https://blog.csdn.net/cymm_liu/article/details/106030636


猜你喜欢
- 0 前言安装:pip install pypiwin32 1 Excel的APIimport win32com.client as win3
- 安全公司 Imperva Cloud WAF 保护了全球超过10万个网站,并且每天观察到大约10亿次攻击。他们每天都会检测到成千上万种黑客工
- 一、APC缓存简介APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中
- 假如页面上有很多条记录,很多情况下,对这些信息按照字母表降序排序会比传统的升序排序显示效率更高。采用你熟悉的ORDER BY 子句,你可以很
- 本文实例讲述了Python数据类型之Tuple元组。分享给大家供大家参考,具体如下:tuple元组1.概述本质上是一种有序的集合,和列表非常
- 使用说明:需要引入插件calendar.js/calendar.min.js须要引入calendar.css 样式表,可以自定义自己想要的皮
- 前言在不远的将来,实现一定程度上的语音支持将成为日常科技的基本要求,整合了语音识别的python程序提供了其他技术无法比拟的交互性和可访问性
- 前言本文用Python实例阐述了一些关于进程、线程和协程的概念,由于水平有限,难免出现错漏,敬请批评改正。前提条件熟悉Python基本语法熟
- 大家好,我是才哥。最近周末也加班了,害…有刚接触python的粉丝同学在运行此前《》的完整代码遇到以下问题,然后…好吧,今天我们就专门介绍一
- golang时间格式化科普 CST 含义CST: 中部标准时间 (Central Standard Time) 同时表示下面4个时区CST
- 前言字符串是 字符的序列 。字符串基本上就是一组单词。我几乎可以保证你在每个Python程序中都要用到字符串,所以请特别留心下面这部分的内容
- 资源预加载组件——preload队列,可以支持队列加载和回调,也可以加载视频或者音频进度条,可以动态获取进度条信息支持img标签的预加载,添
- 如下所示:var table_name = table.render({});page_size = table_name.config.l
- 区别:xx:公有变量,所有对象都可以访问;xxx:双下划线代表着是系统定义的名字。__xxx:双前置下划线,避免与子类中的属性命名冲突,无法
- 本文实例为大家分享了python实现简单俄罗斯方块游戏的具体代码,供大家参考,具体内容如下import pygame,sys,random,
- 在做机器学习的时候,遇到这样一个数据集...一共399行10列,1-9列是用不定长度的空格分割,第9-10列之间用'\t'分
- 目录一、MySQL数据备份1.1、 mysqldump命令备份数据1.2、 mysqldump常用操作示例1.3、 还原mysql备份内容二
- 前言双端队列deque支持从任意一端增加和删除元素。其中,栈和队列就是双端队列的退化形式,它们的输入输出被限制在某一端。基本用法首先,我们来
- 初入Python,一开始就被她简介的语法所吸引,代码简洁优雅,之前在C#里面打开文件写入文件等操作相比Python复杂多了,而Python打
- 在实际信息系统开发中,经常会用到各种各样的协议,网络协议常用的有http,tcp,udp等,传输数