MySQL进阶【十一】—— Innodb 事务的两阶段提交

导读:本篇文章讲解 MySQL进阶【十一】—— Innodb 事务的两阶段提交,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

两阶段提交是什么

  • prepare阶段:此阶段innodb将事务 trx_id洗入redo_log,将事务状态置为prepare状态
  • commit阶段:
    • 写入bin_log
    • 写入redo_log,将事务状态置为commit
      在这里插入图片描述

两阶段提交解决了什么问题

故障恢复、主从、主备复制时,保持了数据的一致性
在这里插入图片描述

  • 故障恢复过程
    • Innodb进行crash recovery时是根据binlog来进行前滚回滚的,只有记录了binlog才会根据redo log前滚或回滚事务。
    • crash recovery的流程其实是:先扫描binlog,提取出xid,然后比较redo中checkpoint之后的xid,如果在binlog存在,那么提交,如果不存在那么回滚。
    • 二阶段日志提交其实是依靠一种内部的分布式(XA)机制避免的,因此MySQL的innodb_support_xa必须设置为1(默认为1且5.7.10后已经弃用)。来具体分析下二阶段提交各个阶段crash的恢复情况:
    • 如果是在一阶段(prepare阶段)后crash,那么binlog未写,事务回滚。
    • 如果在二阶段第一步后crash,那么binlog已写,重做事务。由于二阶段事务的提交是原子性的,这样总能保证binlog与innodb的一致,即便出现了XA事务内的crash,也能合理的进行事务前滚或回滚。
  • 对于主从复制的影响:
    • 上面讨论的二阶段日志提交解决了mysql server与innodb层的日志一致性的问题,单实例的情况下最多因为sync_binlog和innodb_flush_log_at_trx_commit的设置问题导致事务丢失,但是对于主从复制事务丢失却是很严重的问题–>主从不一致。
    • 在主从复制的情况下如果innodb_flush_log_at_trx_commit不为1则有可能出现binlog已写但是redo log未写的情况,此时主库崩溃后在事务前滚时会出现找不到redo的情况导致前滚失败,而从库已经应用binlog,导致主从不一致。
    • 而sync_binlog不为1则可能出现主库直接丢失事务的情况。
    • 因此,为保证主从完全一致且事务不丢失,主库的innodb_flush_log_at_trx_commit和sync_binlog都必须设置为1。

参考链接:https://www.cnblogs.com/leohahah/p/8176553.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/83657.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!