Hi,大家好!我是白日梦!本文是MySQL专题的第 26 篇。

下文还是白日梦以自导自演的方式,围绕“组提交”展开本话题。看看你能抗到第几问吧

换一种写作风格,自导自演面试现场!感觉这样还是比较有趣的,欢迎大家订阅我的MySQL专题,公众号首发!持续更新中~

点击阅读原文,格式会好看一点哦~

点击阅读原文,格式会好看一点哦~

点击阅读原文,格式会好看一点哦~

公众号后台回复:数据库 可以参与抽奖活动,3本《MySQL技术内幕-InnoDB存储引擎》

欢迎关注白日梦,公众号首发!持续连载中


库尼奇瓦,同学,听说你上一面表现的还可以,这一面要不咱继续?


嗯,好啊!




好,你了解MySQL的两阶段提交不?说说看


嗯,了解。 简单来说两阶段提交就是将事务提交分成两部分,经过这两步处理后,我们称这个事务被提交了。




嗯,那两个阶段呢?你说说看!


可以看下面这张图:我们当执行commit命令时,会按照如下进行。


第一阶段:写redo log,并标识上prepare。

— 中间穿插写binlog —

第二阶段:写redo log,完成事务的最终提交。




嗯,那你知不知道为什么事务的提交要分成两个阶段?


嗯,你看上图中的两阶段是redolog-prepare、redolog-commit这两个阶段,然后在这两个阶段中又写了binlog。


这个redolog主要提供的能力是对事务进行rollback、并且redolog是存储引擎层面记录的日志。


而binlog的作用是方面我们进行数据的备份以及MySQL集群主从之间的数据同步使用,并且binlog是MySQL上层,也就是Server层面记录的日志。


综上:MySQL的两阶段提交是为了保证redolog、binlog两者在逻辑上的一致性。才能进一步保证。事务的回滚、数据备份、已经MySQL集群之间的数据才是安全可靠的




嗯,那你能不能举个例子,更直观的告诉我,redolog、binlog两者在逻辑一致的必要性以及用途?


嗯,好啊!,比如这个例子:


在这个例子中,进行完第三步之后,没来得及写binlog,然后主库就挂了,事务也没来得及提交。


这时主库从新启动之后会选择将这个事务丢弃,因为如果它将事务提交了,从库们相对主库来说就少了这条数据,造成了主从数据不一致问题




嗯,在看这个例子

在这个例子中主库宕机前虽然也没有完成对事务对提交,但是它已经写了redolog-prepare、还写了binlog,binlog写完之后很可能从库已经收到这个最新的binlog,并且将这个binlog中的数据回放到自己身上了。


所以主库重新启动之后呢,会选择按照redolog将宕机前的事务状态从内存中恢复出来,也就是说把内存中的缓存页改成脏数据页,然后提交事务


这时主库如果不提交事务,那主库就比从库少了一条数据,同时会造成主从不一致的情况出现。



白日梦补充:
本小节我们重点看MySQL的组提交,而不是两阶段提交,想更多的两阶段提交的故事,可以点击查看白日梦写的:全网最牛X的两阶段提交笔记


嗯,你说的没错。我有个问题哈,你看你画的这张图,事务提交时写了好几次日志。


而且一般我们线上的数据库都有这两个配置

# 该参数控制binlog的落盘时机# 设置为1表示当事务被提交时将binlog落盘# 设置为0表示由文件系统自己控制binlog的落盘时机sync_binlog=1# 该参数控制redolog的落盘时机  # 设置为1表示当事务被提交时将redolog落盘innodb_flush_log_at_trx_commit=1

那你有没有想过:即使写日志是磁盘的顺序IO速度极快,即使固态硬盘的性能很

版权声明:本文为ZhuChangwu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/ZhuChangwu/p/14539264.html