什么是两阶段提交
当有数据修改时,会先将修改redo log cache和binlog cache然后在刷入到磁盘形成redo log file,当redo log file全都刷入到磁盘时(prepare 状态)和提交成功后才能将binlog cache刷入磁盘,当binlog全部刷新到磁盘后会记录一个xid,然后在relo log file上打上commit标志(commit阶段)。

为什么要有两阶段提交
MySQL在修改数据时,MySQL是先从磁盘中将数据copy到内存,然后再将内存中的数据进行修改,并记录redo log buffer 然后在通过系统调用将事务日志写入磁盘redo log file 最后最后事务提交后将内存中修改后的数据在开始写入磁盘中。
1.当只有redo log,binlog失效时,会导致主库可以通过redo log来重做,而从库因为没有及时获取到binlog而不能进行回放,导致主从数据不一致。这样会出现 redo log 写入到磁盘了,但是 binlog 还没写入磁盘,于是当发生 crash recovery 时,恢复后,主库会应用redo log,恢复数据,但是由于没有 binlog,从库就不会同步这些数据,主库比从库“新”,造成主从不一致
2.跟上一种情况类似,很容易知道,这样会反过来,造成从库比主库“新”,也会造成主从不一致。

而两阶段提交,就解决这个问题,crash recovery 时:
如果 redo log 已经 commit,那毫不犹豫的,把事务提交
如果 redo log 处于 prepare,则去判断事务对应的 binlog 是不是完整的
是,则把事务提交
否,则事务回滚
两阶段提交,其实是为了保证 redo log 和 binlog 的逻辑一致性。

mysql的两阶段提交原理

(1) perpare阶段 写入redo日志
1、设置undo state=TRX_UNDO_PREPARED;
2、刷事务更新产生的redo日志;
(2) commit阶段 写入binlog日志
1、将事务产生的binlog写入文件,刷入磁盘;
2、设置undo页的状态,置为TRX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE; //标记可以清理回滚段
3、记录事务对应的binlog偏移,写入系统表空间。
两阶段提交是跨系统维持数据逻辑一致性时常用的一个方案。两阶段存在阻塞难题,提出的三阶段提交,在二阶段的基础上增加了一个预提交。
(3)假设法验证为什么分两阶段:
A. 先写 redo log 后写 binlog。假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。
但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。
然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。
B. 先写 binlog 后写 redo log。如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把c 从 0 改成 1”这个日志。所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。
(4)redo和binlog这两种日志有以下三点不同。
1、 redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
2、 redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
3、redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
(5) 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的性能。

mysql之两阶段提交相关推荐

  1. mongodb mysql 事务_MongoDB数据库两阶段提交实现事务的方法详解 _ 蚂蚁视界

    本文实例讲述了MongoDB数据库两阶段提交实现事务的办法.分享给年夜家供年夜家参考,详细如下: MongoDB数据库中操作单个文档老是原子性的,然而,涉及多个文档的操作,通常被作为一个"事 ...

  2. 提交mysql代码_MySQL源码之两阶段提交

    在双1的情况下,两阶段提交的过程 环境准备:mysql 5.5.18, innodb 1.1 version 配置: sync_binlog=1 innodb_flush_log_at_trx_com ...

  3. mysql三阶段提交实现_基于两阶段提交的分布式事务实现(UP-2PC)

    引言:分布式事务是分布式数据库的基础性功能,在2017年上海MySQL嘉年华(IMG)和中国数据库大会(DTCC2018)中作者都对银联UPSQL Proxy的分布式事务做了简要介绍,受限于交流形式难 ...

  4. mysql commit阶段,MySQL 基本架构与日志两阶段提交

    MySQL大致可以分为Server层和存储引擎层 Server层包括连接器,查询缓存,解析器,预处理器,优化器,执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程,触发器和视图等 连接器 负责 ...

  5. MySQL 为什么需要两阶段提交?

    文章目录 1. 什么是两阶段提交 1.1 binlog 与 redolog binlog redo log 1.2 两阶段提交 2. 为什么需要两阶段提交 3. 小结 为什么要两阶段提交?一阶段提交不 ...

  6. 5.7之前的MySQL版本不完全支持两阶段提交

    在对最近发布的通用JCA适配器进行一些测试时,该适配器能够将对微服务(以及其他东西)的远程调用绑定到JTA事务中,我发现Mysql 5.6中的一个错误已经存在了将近十年. 在XA事务的"准备 ...

  7. MySQL调优(七):滴滴一面二面题,服务器参数设置,redolog两阶段提交

    某同学的滴滴一面二面 1.自我介绍不要念稿 2.对项目描述要准确,不要看起来不懂装懂:态度问题.一些问题没接触过很正常.不要所有问题都抢着说,要展示态度. 服务器参数设置 thread_cache_s ...

  8. flink的mysql两阶段提交_flink 两阶段提交

    flink exactly-once系列目录: 一.两阶段提交概述 二.TwoPhaseCommitSinkFunction与FlinkKafkaProducer源码分析 三.StreamingFil ...

  9. 分布式事务Seata的AT模式下两阶段提交原理

    文章目录 第一阶段 1. 扫描@GlobalTransactional注解,获取全局事务XID 2. TC生成全局事务XID,记录入库 3. 执行业务逻辑,提交本地事务,记录branch_table. ...

最新文章

  1. C#中类的继承 override virtual new的作用以及代码分析
  2. LAMP之二:LAMP的性能测试以及安装xcache,为php加速
  3. java 递归原理_Java中递归原理实例分析
  4. 面试宝典_Python.常规算法.0002.输出任意两个字符串中最长公共子串?
  5. Python3算术运算符
  6. mysql时间戳在某天内_mysql根据时间戳查询指定日期内数据
  7. ActivePython 百科指南
  8. 自定义View以及事件分发总结
  9. android view 平滑,Android移动view动画问题(让移动更平滑)
  10. Eclipse中文乱码解决汇总(应该比较全):
  11. 软件设计师2021考试大纲
  12. 【通信协议】IIC通信协议详解
  13. 15.在springboot中的事务处理
  14. Arduino学习模拟输出
  15. 江苏省计算机一级主要考什么,江苏省计算机一级考试复习资料 很全面的
  16. Element UI 多选表格【翻页多选】全能版(含翻页多选数据反显、toggleRowSelection失效的原因解析和解决方案)
  17. mysql存储emoji表情_MySQL中支持emoji表情的存储
  18. android studio下使用TUTK SDK
  19. 鸿蒙系统硬盘分区,电脑硬盘分区分错了有哪些危害?如何正确分区?今天我再说一遍...
  20. win10 绿色版gsql启动卡住_Win10优化软件Windows 10 Manager+MP3剪切合并大师 优化版

热门文章

  1. matlab写中秋祝福
  2. 肝吧,加油学习新知识
  3. RAID阵列概述及阵列创建步骤
  4. C++ MFC深入详解之----设置控件背景透明
  5. XSS注入的原理与实现
  6. 会python再学java要多久_【学过python多久能学会java】廖雪峰python教程要学多久
  7. ubuntu14.04 + caffe
  8. Analog-BJT, JFET, MOSFET 的噪声分析
  9. Cisco考试再认证常见疑难问题解答
  10. 1115. 裁判机 / 数组 【PATbasic】