mysql5.7组提交_mysql 5.7基于组提交,group commit

MySQL 组提交

prepare_commit_mutex锁

MySQL5.6以前,为了保证数据库上层二进制日志的写入顺序和InnoDB层的事务提交顺序一致,MySQL数据库内部使用了prepare_commit_mutex锁。但是持有这把锁之后,会导致组提交失败。锁的持有与释放在二阶段中如下:

InnoDB prepare (持有prepare_commit_mutex);

write/sync Binlog;

InnoDB commit (写入COMMIT标记后释放prepare_commit_mutex)。

这样事务提交就是一个一个执行,导致组提交失败。

Binary Log Group Commit(BLGC)

MySQL5.6通过BLGC的方式实现了binlog的组提交。

binlog组提交的基本思想是,引入队列机制保证innodb commit顺序与binlog落盘顺序一致,并将事务分组,组内的binlog刷盘动作交给一个事务进行,实现组提交目的。

fcdfeb34c65807f5a2f07f05af955014.png

binlog提交将提交分为了3个阶段,FLUSH阶段,SYNC阶段和COMMIT阶段。每个阶段都有一个队列,队列中的第一个事务称为leader,其他事务称为follower,leader控制着follower的行为。BLGC的步骤分为以下三个阶段:

FLUSH阶段:

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

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

将binlog buffer到I/O cache

通知dump线程dump binlog

SYNC阶段:

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

将一组binlog 落盘(sync动作,最耗时,也是group commit实现了的优化的重点所在)

COMMIT阶段:

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

遍历队列中的事务,逐一进行innodb commit(这里不用写redo log,在prepare阶段已写)

释放Lock_commit mutex

唤醒队列中等待的线程

每个stage分配一个线程进行操作。

这种实现的优势在于三个阶段可以并发执行,从而提升效率。(PS:innodb prepare阶段没有变,还是write/sync redo log,打上prepare标记)

每个stage都有自己的队列。每个队列各自有mutex保护,队列之间是顺序的。只有flush完成后,才能进入到sync阶段的队列中;sync完成后,才能进入到commit阶段的队列中。但是,这三个阶段的作业是可以同时并发执行的,即当一组事务在进行commit阶段时,其他新事务可以进行flush阶段,实现了group commit。

当一个事务来到一个stage是一个空队列,那么他就是leader,后面来的事务就是follower,leader控制队列中follower的行为。如果leader带着自己的follower去下一个stage,是非空队列,那么leader变成follower。但是follower不会变成leader。

Tips:当引入Group Commit后,sync_binlog的含义就变了,假定设为1000,表示的不是1000个事务后做一次fsync,而是1000个事务组。也就是说,当设置sync_binlog=1,binlog还未落盘,此时系统crash,会丢失对应的最后一个事务组;如果这个事务组内有10个事务,那么这10个事务都会丢失。

如何查看是否属于一个事务组:通过mysqlbinlog可以查看binlog日志中last_committed值,如果值一样,表明是在同一事务组内。

### INSERT INTO `wukong_test`.`wukong`

### SET

###   @1=3 /* INT meta=0 nullable=1 is_null=0 */

###   @2='ccccc' /* VARSTRING(80) meta=80 nullable=1 is_null=0 */

# at 496468

#170527  4:17:35 server id 12001  end_log_pos 496499 CRC32 0xd6e7f69f   Xid = 5556

COMMIT/*!*/;

# at 496499

#170527  4:17:35 server id 12001  end_log_pos 496564 CRC32 0x28816d5c   GTID    last_committed=1845 sequence_number=1846

SET @@SESSION.GTID_NEXT= '0a646c88-36e2-11e7-937d-fa163ed7a7b1:3624'/*!*/;

# at 496564

#170527  4:17:35 server id 12001  end_log_pos 496632 CRC32 0x03150d48   Query   thread_id=1852  exec_time=0 error_code=0

SET TIMESTAMP=1495873055/*!*/;

BEGIN

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值