本文读完需3分钟,速读仅需1分钟。
前言
华仔在前面推过两篇文章都详细聊过redo log
与binlog
,有兴趣的朋友可以去看看前面两篇文章:
今天就来聊聊InnoDB
是如何保证redo log
与binlog
两份日志之间的逻辑一致。
两阶段提交
redo log
(重做日志)让InnoDB
存储引擎拥有了崩溃恢复能力。
binlog
(归档日志)保证了MySQL
集群架构的数据一致性。
虽然它们都属于持久化的保证,但是则重点不同。
在执行更新语句过程,会记录redo log
与binlog
两块日志,以基本的事务为单位,redo log
在事务执行过程中可以不断写入,而binlog
只有在提交事务时才写入,所以redo log
与binlog
的写入时机不一样。
回到正题,redo log
与binlog
两份日志之间的逻辑不一致,会出现什么问题?
我们以update
语句为例,假设id=2
的记录,字段c
值是0
,把字段c
值更新成1
,SQL
语句为update T set c=1 where id=2
。
假设执行过程中写完redo log
日志后,binlog
日志写期间发生了异常,会出现什么情况呢?
由于binlog
没写完就异常,这时候binlog
里面没有对应的修改记录。因此,之后用binlog
日志恢复数据时,就会少这一次更新,恢复出来的这一行c
值是0
,而原库因为redo log
日志恢复,这一行c
值是1
,最终数据不一致。
为了解决两份日志之间的逻辑一致问题,InnoDB
存储引擎使用两阶段提交方案。
原理很简单,将redo log
的写入拆成了两个步骤prepare
和commit
,这就是两阶段提交。
使用两阶段提交后,写入binlog
时发生异常也不会有影响,因为MySQL
根据redo log
日志恢复数据时,发现redo log
还处于prepare
阶段,并且没有对应binlog
日志,就会回滚该事务。
再看一个场景,redo log
设置commit
阶段发生异常,那会不会回滚事务呢?
并不会回滚事务,它会执行上图框住的逻辑,虽然redo log
是处于prepare
阶段,但是能通过事务id
找到对应的binlog
日志,所以MySQL
认为是完整的,就会提交事务恢复数据。
站在巨人的肩膀上
《MySQL实战45讲》 《从零开始带你成为MySQL实战优化高手》 《MySQL技术Innodb存储引擎》
双11马上要到了,送一个福利,给大家申请了 10 张 60 元知识星球优惠券(历史上大优惠),原价:239,今天券后仅需:179,还送下面的技术小册,错过了要等一年。 关于星球介绍点击: 超 500 万字详解,从零到一带你彻底吃透 Kafka + RocketMQ 小红书实战 码哥的小报童,仅需 19 元,需要的可以扫码加入,加入星球的老铁送该小册。 本专栏内容涵盖 Java 基础、Java 高级进阶、Redis、MySQL、消息中间件、微服务
架构设计等面试必考点、面试高频点。本专栏不只是单纯教大家学会背八股文知识,
更多是结合实际大厂高并发项目的场景,去学习面试技术要点。从面试官的角度去出
发,介绍互联网 Java 流行技术体系各个面试要点。
本专栏适合于准备进阶 Java 后端技术、有面试或提升技术需求,希望学习互联网大
厂 Java 流行技术体系的程序员和面试官,助你拿到名企高薪 Offer。
需要续费的扫这个,优惠25元 另外必须要注意的是上车的老铁一定要加我微信 好友,拉你们加入星球专属交流群。