redo log与binlog间的破事
共 1484字,需浏览 3分钟
·
2021-08-18 22:45
点击下方“IT牧场”,选择“设为星标”
前言
今天来聊聊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存储引擎》
MySQL好文推荐
关于我
阿星是一个热爱技术的 Java
程序猿,公众号「程序猿阿星」定期分享有趣有料的精品原创文章!
非常感谢各位小哥哥小姐姐们能看到这里,原创不易,文章有帮助可以关注、点个赞、分享与评论,都是支持(莫要白嫖)!
愿你我都能奔赴在各自想去的路上,我们下篇文章见。
干货分享
最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!
•001:《Java并发与高并发解决方案》学习笔记;•002:《深入JVM内核——原理、诊断与优化》学习笔记;•003:《Java面试宝典》•004:《Docker开源书》•005:《Kubernetes开源书》•006:《DDD速成(领域驱动设计速成)》•007:全部•008:加技术群讨论
加个关注不迷路
喜欢就点个"在看"呗^_^