iis服务器助手广告
返回顶部
首页 > 资讯 > 数据库 >如何理解MYSQL GroupCommit
  • 443
分享到

如何理解MYSQL GroupCommit

2023-06-06 01:06:12 443人浏览 薄情痞子
摘要

今天就跟大家聊聊有关如何理解MYSQL  GroupCommit,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。组提交(group commit)是Mysql处理日志的一种优

今天就跟大家聊聊有关如何理解MYSQL  GroupCommit,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

组提交(group commit)是Mysql处理日志的一种优化方式,主要为了解决写日志时频繁刷磁盘的问题。组提交伴随着mysql的发展不断优化,从最初只支持redo log 组提交,到目前5.6官方版本同时支持redo log 和binlog组提交。组提交的实现大大提高了mysql事务处理性能,下文将以innodb 存储引擎为例,详细介绍组提交在各个阶段的实现原理。

redo log的组提交

     WAL(Write-Ahead-Logging)是实现事务持久性的一个常用技术,基本原理是在提交事务时,为了避免磁盘页面的随机写,只需要保证事务的redo log写入磁盘即可,这样可以通过redo log的顺序写代替页面的随机写,并且可以保证事务的持久性,提高了数据库系统的性能。虽然WAL使用顺序写替代了随机写,但是,每次事务提交,仍然需要有一次日志刷盘动作,受限于磁盘io,这个操作仍然是事务并发的瓶颈。

      组提交思想是,将多个事务redo log的刷盘动作合并,减少磁盘顺序写。Innodb的日志系统里面,每条redo log都有一个LSN(Log Sequence Number),LSN是单调递增的。每个事务执行更新操作都会包含一条或多条redo log,各个事务将日志拷贝到log_sys_buffer时(log_sys_buffer 通过log_mutex

保护),都会获取当前最大的LSN,因此可以保证不同事务的LSN不会重复。那么假设三个事务Trx1,Trx2和Trx3的日志的最大LSN分别为LSN1,LSN2,LSN3(LSN1<LSN2<LSN3),它们同时进行提交,那么如果Trx3日志先获取到log_mutex进行落盘,它就可以顺便把[LSN1---LSN3]这段日志也刷了,这样Trx1和Trx2就不用再次请求磁盘IO。组提交的基本流程如下:

  1. 获取 log_mutex

  2. 若flushed_to_disk_lsn>=lsn,表示日志已经被刷盘,跳转5

  3. 若 current_flush_lsn>=lsn,表示日志正在刷盘中,跳转5后进入等待状态

  4. 将小于LSN的日志刷盘(flush and sync)

  5. 退出log_mutex

备注:lsn表示事务的lsn,flushed_to_disk_lsn和current_flush_lsn分别表示已刷盘的LSN和正在刷盘的LSN。 

redo log 组提交优化

     我们知道,在开启binlog的情况下,prepare阶段,会对redo log进行一次刷盘操作(innodb_flush_log_at_trx_commit=1),确保对data页和undo 页的更新已经刷新到磁盘;commit阶段,会进行刷binlog操作(sync_binlog=1),并且会对事务的undo log从prepare状态设置为提交状态(可清理状态)。通过两阶段提交方式(innodb_support_xa=1),可以保证事务的binlog和redo log顺序一致。二阶段提交过程中,mysql_binlog作为协调者,各个存储引擎和mysql_binlog作为参与者。故障恢复时,扫描最后一个binlog文件(在flush阶段,判断binlog是否超过阀值,进行rotate binlog文件,rotate的binlog文件中对应的事务一定是已经提交的,处于prepared的事务的binlog还没有刷进来,因为还没进入ordered_commit函数),提取其中的xid;重做检查点以后的redo日志,读取事务的undo段信息,搜集处于prepare阶段的事务链表,将事务的xid与binlog中的xid对比,若存在,则提交,否则就回滚。

     通过上述的描述可知,每个事务提交时,都会触发一次redo flush动作,由于磁盘读写比较慢,因此很影响系统的吞吐量。淘宝童鞋做了一个优化,将prepare阶段的刷redo动作移到了commit(flush-sync-commit)的flush阶段之前,保证刷binlog之前,一定会刷redo。这样就不会违背原有的故障恢复逻辑。移到commit阶段的好处是,可以不用每个事务都刷盘,而是leader线程帮助刷一批redo。如何实现,很简单,因为log_sys->lsn始终保持了当前最大的lsn,只要我们刷redo刷到当前的log_sys->lsn,就一定能保证,将要刷binlog的事务redo日志一定已经落盘。通过延迟写redo方式,实现了redo log组提交的目的,而且减少了log_sys->mutex的竞争。目前这种策略已经被官方mysql5.7.6引入。

两阶段提交

     在单机情况下,redo log组提交很好地解决了日志落盘问题,那么开启binlog后,binlog能否和redo log一样也开启组提交?首先开启binlog后,我们要解决的一个问题是,如何保证binlog和redo log的一致性。因为binlog是Master-Slave的桥梁,如果顺序不一致,意味着Master-Slave可能不一致。MYSQL通过两阶段提交很好地解决了这一问题。Prepare阶段,innodb刷redo log,并将回滚段设置为Prepared状态,binlog不作任何操作;commit阶段,innodb释放,释放回滚段,设置提交状态,binlog刷binlog日志。出现异常,需要故障恢复时,若发现事务处于Prepare阶段,并且binlog存在则提交,否则回滚。通过两阶段提交,保证了redo log和binlog在任何情况下的一致性。

binlog的组提交

      回到上节的问题,开启binlog后,如何在保证redo log-binlog一致的基础上,实现组提交。因为这个问题,5.6以前,mysql在开启binlog的情况下,无法实现组提交,通过一个臭名昭著的prepare_commit_mutex,将redo log和binlog刷盘串行化,串行化的目的也仅仅是为了保证redo log-Binlog一致,但这种实现方式牺牲了性能。这个情况显然是不能容忍的,因此各个mysql分支,mariadb,facebook,perconal等相继出了补丁改进这一问题,mysql官方版本5.6也终于解决了这一问题。由于各个分支版本解决方法类似,我主要通过分析5.6的实现来说明实现方法。

     binlog组提交的基本思想是,引入队列机制保证innodb commit顺序与binlog落盘顺序一致,并将事务分组,组内的binlog刷盘动作交给一个事务进行,实现组提交目的。binlog提交将提交分为了3个阶段,FLUSH阶段,SYNC阶段和COMMIT阶段。每个阶段都有一个队列,每个队列有一个mutex保护,约定进入队列第一个线程为leader,其他线程为follower,所有事情交由leader去做,leader做完所有动作后,通知follower刷盘结束。binlog组提交基本流程如下:

FLUSH 阶段

1)      持有Lock_log mutex [leader持有,follower等待]

2)      获取队列中的一组binlog(队列中的所有事务)

3)      将binlog buffer到I/O cache

4)      通知dump线程dump binlog

SYNC阶段

1)      释放Lock_log mutex,持有Lock_sync mutex[leader持有,follower等待]

2)      将一组binlog 落盘(sync动作,最耗时,假设sync_binlog为1)

COMMIT阶段

1)      释放Lock_sync mutex,持有Lock_commit mutex[leader持有,follower等待]

2)      遍历队列中的事务,逐一进行innodb commit

3)      释放Lock_commit mutex

4)      唤醒队列中等待的线程

说明:由于有多个队列,每个队列各自有mutex保护,队列之间是顺序的,约定进入队列的一个线程为leader,因此FLUSH阶段的leader可能是SYNC阶段的follower,但是follower永远是follower。

      通过上文分析,我们知道MYSQL目前的组提交方式解决了一致性和性能的问题。通过二阶段提交解决一致性,通过redo log和binlog的组提交解决磁盘IO的性能。下面我整理了Prepare阶段和Commit阶段的框架图供各位参考。

 如何理解MYSQL  GroupCommit

如何理解MYSQL  GroupCommit

看完上述内容,你们对如何理解MYSQL  GroupCommit有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网数据库频道,感谢大家的支持。

您可能感兴趣的文档:

--结束END--

本文标题: 如何理解MYSQL GroupCommit

本文链接: https://www.lsjlt.com/news/245428.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解MYSQL GroupCommit
    今天就跟大家聊聊有关如何理解MYSQL  GroupCommit,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。组提交(group commit)是MYSQL处理日志的一种优...
    99+
    2023-06-06
  • 如何理解MYSQL-GroupCommit 和 2pc提交
    这篇文章将为大家详细讲解有关如何理解MYSQL-GroupCommit 和 2pc提交,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 组提交(gr...
    99+
    2024-04-02
  • MySQL组提交groupcommit详解
    目录引 言前提:背景说明:图解:Flush 阶段 (图中第一个渡口)Sync 阶段 (图中第二个渡口)Commit 阶段 (图中第三个渡口)缺陷分析:引 言 前提: 以下讨论的前提...
    99+
    2024-04-02
  • 如何理解MySQL锁
    这篇文章主要介绍“如何理解MySQL锁”,在日常操作中,相信很多人在如何理解MySQL锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解MySQL锁”的疑惑有所帮助!接...
    99+
    2024-04-02
  • 如何理解Mysql Replication
    如何理解Mysql Replication,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Mysql Replication类似...
    99+
    2024-04-02
  • 如何理解Mysql index extensions
    这篇文章给大家介绍如何理解Mysql index extensions,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 1、什么是index extensions 前者的key...
    99+
    2024-04-02
  • 如何理解MySQL索引原理
    本篇内容主要讲解“如何理解MySQL索引原理”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解MySQL索引原理”吧!案例背景假设面试官问你:在电商平台的订...
    99+
    2024-04-02
  • 如何理解MySQL索引cardinalit
    本篇内容主要讲解“如何理解MySQL索引cardinalit”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解MySQL索引cardinalit”吧!查看一...
    99+
    2024-04-02
  • 如何理解Mysql debug模式
    如何理解Mysql debug模式,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 以debug模式编译 -D...
    99+
    2024-04-02
  • 如何理解MySQL Replication线程
    这篇文章将为大家详细讲解有关如何理解MySQL Replication线程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Replication 线程Mysq...
    99+
    2024-04-02
  • 如何理解MySQL的Buffer Pool
    本篇内容介绍了“如何理解MySQL的Buffer Pool”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前...
    99+
    2024-04-02
  • 如何理解MYSQL 解锁与锁表
    如何理解MYSQL 解锁与锁表,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 解锁第一种show processl...
    99+
    2024-04-02
  • 如何深入理解MySQL索引
    这篇文章将为大家详细讲解有关如何深入理解MySQL索引,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。前言当提到MySQL数据库的时候,我们的脑海里会想起几个...
    99+
    2024-04-02
  • 如何理解MySQL中filesort排序
    MySQL中什么是filesort排序,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。排序(filesort)作为DBA绕不开的话题,也经常...
    99+
    2024-04-02
  • 如何理解mysql权限参考
    本篇文章为大家展示了如何理解mysql权限参考,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。mysql日常管理和应用工作中,大家经常会涉及到授权问题,下面,我们就列...
    99+
    2024-04-02
  • 如何理解MySQL中binlog和innodb_flush_log_at_trx_commit
    如何理解MySQL中binlog和innodb_flush_log_at_trx_commit ,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希...
    99+
    2024-04-02
  • 如何理解MySQL中的事务
    今天就跟大家聊聊有关如何理解MySQL中的事务,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。事务又叫做TCL,全称是transaction cont...
    99+
    2024-04-02
  • 如何理解mysql的锁机制
    本篇文章为大家展示了如何理解mysql的锁机制,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 锁0.1 锁机制当前MySQL已经支持 ISAM, MyIS...
    99+
    2024-04-02
  • 如何理解mysql自增长列
    本篇文章给大家分享的是有关如何理解mysql自增长列,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。 自增长列必须是...
    99+
    2024-04-02
  • 如何理解PHP与MySQL通讯
    如何理解PHP与MySQL通讯,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在我们的一款WebGame的生产环境中,一次无意的strace抓包时,发现了php与mysql大...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作