mysql-两阶段提交

图中可看出,事务的提交过程有两个阶段,就是将redo log的写入拆成了两个步骤:prepare和commit,中间再穿插写入binlog

组提交

第一阶段(prepare阶段):

持有prepare_commit_mutex,并且write/fsync redo log到磁盘,设置为prepared状态,完成后就释放prepare_commit_mutex,binlog不作任何操作。

第二个阶段(commit阶段):

这里拆分成了三步,每一步的任务分配给一个专门的线程处理:

1.Flush Stage(写入binlog缓存)

① 持有Lock_log mutex [leader持有,follower等待]
② 获取队列中的一组binlog(队列中的所有事务)
③ 写入binlog缓存

2.Sync Stage(将binlog落盘)

①释放Lock_log mutex,持有Lock_sync mutex[leader持有,follower等待]
②将一组binlog落盘(fsync动作,最耗时,假设sync_binlog为1)。

3.Commit Stage(InnoDB commit,清楚undo信息)
①释放Lock_sync mutex,持有Lock_commit mutex[leader持有,follower等待]
② 遍历队列中的事务,逐一进行InnoDB commit
③ 释放Lock_commit mutex

每个Stage都有自己的队列,队列中的第一个事务称为leader,其他事务称为follower,leader控制着follower的行为。每个队列各自有mutex保护,队列之间是顺序的。只有flush完成后,才能进入到sync阶段的队列中;sync完成后,才能进入到commit阶段的队列中。但是这三个阶段的作业是可以同时并发执行的,即当一组事务在进行commit阶段时,其他新事务可以进行flush阶段,实现了真正意义上的组提交,大幅度降低磁盘的IOPS消耗。

针对组提交为什么比两阶段提交加锁性能更好,简单做个总结:组提交虽然在每个队列中仍然保留了prepare_commit_mutex锁,但是锁的粒度变小了,变成了原来两阶段提交的1/4,所以锁的争用性也会大大降低;另外,组提交是批量刷盘,相比之前的单条记录都要刷盘,能大幅度降低磁盘的IO消耗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值