穿越1995之二:顺序I/O给“My蜗牛SQL”逆天改命(MySQL写入篇,三大日志)

11 阅读1分钟

1 场景引入:总工的焦虑

  • 背景: 1995年,磁盘转速极其缓慢,随机读写仅有几百次/秒。
  • 冲突:用户执行UPDATE,如果我直接去磁盘寻找那行数据并直接修改,磁头来回摆动,数据库每秒只能处理几十个请求。
  • 总工的直觉:我需要先在内存中修改(buffer pool),但是内存一断电就会崩掉。我需要像写日记一样快的持久化方式。

2 设计核心:为什么“日记”比“档案”快?

  • 物理定律:硬盘的顺序追加的速度,是随机写入的速度的几百倍。
  • 设计决策:引入RedoLog
    • 当数据变更时,我只在内存中修改数据,然后同时在RedoLog顺序记上一笔:“在102房(数据页)搬走了一个沙发”
    • 只要这笔账记到了硬盘的日志文件上,我就敢告诉用:“提交成功!”

3 三大剑客: UndoLog RedoLog BinLog

  • UndoLog: 后悔药剑客,事务开始前先写的,记下反向操作。如果事务崩溃了,靠他回滚到最初的模样。
  • RedoLog:速记剑客,InnoDB专属,是为了掉电救命。
  • Binlog: 历史剑客,作用是主从同步和误删恢复。

4 二阶段提交

image.png

5 MySQL崩溃恢复逻辑

  • 首先扫描Redolog,发现日志状态Prepare
  • 根据事务唯一的XID去找Binlog
  • 如果找到了对应XID的Binlog,则说明事务已经成功,这时MySQL自动修改Redolog状态为Commit,并且恢复数据
  • 如果没有找到对应XID的Binlog,说明崩溃发生在写Binlog之前,为了保持主从一致(从库肯定没有这个数据),MySQL会使用UndoLog回滚Prepare