关注
首先,需要明确 MySQL 中这两种 log 存放的是什么数据。
binlog 是 MySQL 自己的日志,它里面存放的是二进制格式的 SQL 语句 或 变化的每行 SQL 信息。(具体要看 binlog_format 是 STATEMENT 还是 ROW)为了简化讨论,就把它当作存放了一堆 SQL 的二进制文件。
redo log 是 InnoDB 的日志,InnoDB 是 MySQL 的一种可选引擎。redo log 里面存放的是对 InnoDB 数据页面的「修改动作」,可以抽象成把某个字节从 X 改成 Y。由于它只记录操作,所以 redo log 并不清楚这些操作在逻辑上对应什么。
(数据页面也简单解释下,可以想象成把表里的数据,一行接一行的排列到一个大的文件中。修改数据页面的动作,实际上就是在修改行内的数据。)
基本概念对齐以后,我们来考虑没有 redo log 会怎么样。我们要知道 binlog 和 磁盘上的数据页 从物理上没办法保证同时写入完成,总归会有先后。那么我们写入 binlog 后,数据页面刷到一半,机器断电了,我们如何把数据页从茫茫字节中,恢复到之前的内容呢?(这里还涉及一个 doublewrite buffer 的概念,但为了聚焦问题,先假设一次性刷写能完整刷写一个页面)
可以简单认为,MySQL 决定一个事务是否成功提交,取决于 binlog。假设 binlog 是完整的,存储引擎无论如何都得把这条 binlog 对应的记录还原回来,否则事务就丢失了。同时 MySQL 主备复制也是依赖 binlog,也就是 binlog 具有 “一票否决权”。而 redo log 是 InnoDB 指导自己如何恢复数据的。
从我的表述来看,redo log 和 binlog 必须保证一致。要么都有,要么都没有。这点从物理上无法保证,但是从逻辑上可以。redo log 先写入本次操作,并记录 “type” 为 prepare;这时写入 binlog,再写入一条 redo log commit 记录。
假设1:只有 redo log prepare,没有 binlog。说明事务没有提交,我需要根据 redo log prepare 的操作指导,保证数据页的正确性。
假设2:有 binlog,没有 redo log commit。说明事务是正确提交的,只是 redo commit 没来得及写入,我需要根据 redo log prepare 的操作指导,进行页面数据恢复。
其实,当你觉得一个东西不需要的时候,想象一下把它去掉,这个系统是否可以保证正确。
查看原帖
7 评论
相关推荐
点赞 评论 收藏
分享
01-06 15:37
河北工业大学 Java 点赞 评论 收藏
分享
点赞 评论 收藏
分享
牛客热帖
更多
正在热议
更多
# 哪些公司在招寒假实习? #
9482次浏览 105人参与
# 你怎么看待AI面试 #
132825次浏览 738人参与
# MiniMax求职进展汇总 #
516次浏览 19人参与
# 26年哪些行业会变好/更差 #
15355次浏览 215人参与
# 卷__卷不过你们,只能卷__了 #
8777次浏览 204人参与
# 去年的flag与今年的小目标 #
7569次浏览 170人参与
# 写论文的崩溃时刻 #
4461次浏览 117人参与
# 有深度的简历长什么样? #
13936次浏览 294人参与
# 找工作时的取与舍 #
114862次浏览 846人参与
# 求职你最看重什么? #
150655次浏览 875人参与
# 你不能接受的企业文化有哪些 #
9211次浏览 146人参与
# 腾讯音乐求职进展汇总 #
147309次浏览 1048人参与
# 你觉得第一学历对求职有影响吗? #
219598次浏览 1226人参与
# 你都用AI做什么 #
5556次浏览 128人参与
# 入职第一天 #
8343次浏览 170人参与
# 机械人求职现状 #
31602次浏览 292人参与
# 晒一晒你收到的礼盒 #
94947次浏览 460人参与
# 一人分享一道面试手撕题 #
18587次浏览 698人参与
# 机械人的秋招小目标 #
25934次浏览 228人参与
# 实习中的菜狗时刻 #
457318次浏览 3525人参与
# 毕业后不工作的日子里我在做什么 #
225928次浏览 1681人参与