书生笔记-MySQL 层事务提交流程简析

作者:高鹏
文章末尾有他著作的《深入理解MySQL主从原理 32讲》,深入透彻理解MySQL主从,GTID相关技术知识。

本文节选自《深入理解MySQL主从原理》第15节本节包含一个笔记如下:
https://www.jianshu.com/writer#/notebooks/37013486/notes/50142567

本文提要

本节将解释 MySQL 层详细的提交流程,但是由于能力有限,这里不可能包含全部的步骤,只是包含了一些重要的、并且我学习过的步骤。

我们首先需要来假设参数设置,因为某些参数的设置会直接影响到提交流程,我们也会逐一解释这些参数的含义。
本节介绍的大部分内容都集中在函数 MYSQL_BIN_LOG::prepare和MYSQL_BIN_LOG::ordered_commit 之中。

一、参数设置

本部分假定参数设置为:

  • binlog_group_commit_sync_delay:0
  • binlog_group_commit_sync_no_delay_count:0
  • binlog_order_commits:ON
  • sync_binlog:1
  • binlog_transaction_dependency_tracking:COMMIT_ORDER

关于参数 binlog_transaction_dependency_tracking 需要重点说明一下。我们知道 Innodb 的行锁是在语句运行期间就已经获取,因此如果多个事务同时进入了提交流程(prepare阶段),在 Innodb 层提交释放 Innodb 行锁资源之前各个事务之间肯定是没有行冲突的,因此可以在从库端并行执行。在基于 COMMIT_ORDER 的并行复制中,last commit 和 seq number 正是基于这种思想生成的,如果 last commit 相同则视为可以在从库并行回放,在19节我们将解释从库判定并行回放的规则。而在基于 WRITESET 的并行复制中,last commit 将会在 WRITESET 的影响下继续降低,来使从库获得更好的并行回放效果,但是它也是 COMMIT_ORDER 为基础的,这个下一节将讨论。我们这节只讨论基于COMMIT_ORDER 的并行复制中 last commit 和 seq number 的生成方式。

而sync_binlog参数则有两个功能:

  • sync_binlog=0:binary log 不 sync 刷盘,依赖于 OS 刷盘机制。同时会在flush阶段后通知DUMP线程发送Event。
  • sync_binlog=1:binary log 每次 sync 队列形成后都进行sync刷盘,约等于每次group commit 进行刷盘。同时会在 sync 阶段后通知DUMP线程发送 Event。注意sync_binlog 非1的设置可能导致从库比主库多事务。

after_commit(5.6默认):master将每个事务写入binlog(sync_binlog=1),传递到slave刷新到磁盘(sync_relay=1),同时主库提交事务(此时数据已经提交了)。master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。

after_sync(5.7默认):master将每个事务写入binlog , 传递到slave刷新到磁盘(relay log)。master等待slave反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。

区别:

1,ACK的时间点不同:

(1)半同步复制在InnoDB层的Commit Log后等待ACK,主从切换会有数据丢失风险。

(2)无损复制在MySQL Server层的Write binlog后等待ACK,主从切换会有数据变多风险。

2,主从数据一致性:

(1)半同步复制意味着在Master节点上,这个刚刚提交的事物对数据库的修改,对其他事物是可见的。因此,如果在等待Slave ACK的时候crash了,那么会对其他事务出现幻读,数据丢失

(2)无损复制在write binlog完成后,就传输binlog,但还没有去写commit log,意味着当前这个事物对数据库的修改,其他事物也是不可见的。因此,不会出现幻读和数据丢失风险。

  • sync_binlog>1:binary log 将在指定次 sync 队列形成后进行 sync 刷盘,约等于指定次 group commit 后刷盘。同时会在 flush 阶段后通知 DUMP 线程发送 Event。

二,步骤解析第一阶段:prepare阶段

注意:在第1步之前会有一个获取 MDL_key::COMMIT

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值