作者回复: Redo log不是记录数据页“更新之后的状态”,而是记录这个页 “做了什么改动”。
Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。
(谢谢你提这个问题,为了不打断文章思路,这个点没在正文写,但是又是很重要的点😄😄)
作者回复: 👍🏿置顶了
你说的物理复制业界有团队在做了
而且官方新版本也把MySQL的表结构都收归InnoDB管理了😄
作者回复: binlog还不能去掉。
一个原因是,redolog只有InnoDB有,别的引擎没有。
另一个原因是,redolog是循环写的,不持久保存,binlog的“归档”这个功能,redolog是不具备的。
作者回复: 几乎全对,除了这个“两阶段提交时,若redo log写入成功,但binlog写入失败…”这句话。
实际上,因为是两阶段提交,这时候redolog只是完成了prepare, 而binlog又失败,那么事务本身会回滚,所以这个库里面status的值是0。
如果通过binlog 恢复出一个库,status值也是0。
这样不算丢失,这样是合理的结果。
两阶段就是保证一致性用的。
你不用担心日志写错,那样就是bug了…
作者回复: 👍🏿,会想到这么细致的场景
这些数据在内存中是无效其他事务读不到的(读到了也放弃),同样的,即使写进磁盘,也没关系,再次读到内存以后,还是原来的逻辑
作者回复: 其实恢复数据只能恢复到误删之前到一刻,
误删之后的,不能只靠binlog来做,因为业务逻辑可能因为误删操作的行为,插入了逻辑错误的语句,
所以之后的,跟业务一起,从业务快速补数据的。只靠binlog补出来的往往不完整
作者回复: 因为是“循环”的,图中这个状态下,write_pos 往前写,写到3号文件末尾,就回到0号继续写,这样你再理解看看“追”的状态。
刚好借你这个问题,说明一下,文中“write pos和checkpoint之间的是’粉板’上还空着的部分,可以用来记录新的操作。”
这句话,说的“空着的部分”,就是write pos 到3号文件末尾,再加上0号文件开头到checkpoint 的部分。
作者回复: 文章中有提到“binlog没有被用来做崩溃恢复”,
历史上的原因是,这个是一开始就这么设计的,所以不能只依赖binlog。
操作上的原因是,binlog是可以关的,你如果有权限,可以set sql_log_bin=0关掉本线程的binlog日志。 所以只依赖binlog来恢复就靠不住。
@高枕、@思雨 也看下这个讨论😄
作者回复: 👍🏿,get 完成
作者回复: 其实在实现上5是调用了6的过程了的,所以是一回事。MySQL server 层和InnoDB层都保存了表结构,所以有书上描述时会拆开说。
这个描述很详细,同时还有点到我们后面要讲的内通(编辑快来,有人来砸场子啦😄😄)
作者回复: 好问题👍🏿表示中间那段你都听明白了👍🏿
Binlog如果已经接受,那么redolog是prepare, binlog已经完整了对吧,这时候崩溃恢复过程会认可这个事务,提交掉。 (你可以分析下这种情况下,是否符合我们要达到的“用binlog恢复的库跟原库逻辑相同” 这个要求)
作者回复: 你是有故事的人😄
作者回复: 你选择了最优路径👍🏿
作者回复: 1. Redolog是顺序写,并且可以组提交,还有别的一些优化,收益最大是是这两个因素;
2.是这样,正常执行是要commit 才算完,但是崩溃恢复过程的话,可以接受“redolog prepare 并且binlog完整” 的情况
作者回复: 你的理解是对的。
1. 写redo log是顺序写,不用去“找位置”,而更新数据需要找位置
2. 其实是3次(redolog两次 binlog 1次)。不过在并发更新的时候会合并写
作者回复: 这样理解哈。
逻辑日志可以给别的数据库,别的引擎使用,已经大家都讲得通这个“逻辑”;
物理日志就只有“我”自己能用,别人没有共享我的“物理格式”