知识卡片

Commit Logging用日志与提交记录保障原子性和持久性

普通读书笔记卡

内容

数据写入磁盘不是原子操作,客观存在”正在写”的中间状态,加上崩溃随时可能 发生,这使得直接就地修改数据无法保证原子性与持久性。ARIES理论给出的 经典解法是Commit Logging:不直接改动数据本身,而是先把”改了什么、从哪个 值改成哪个值”以顺序追加的日志形式安全落盘;只有当日志里出现代表事务成功 提交的”Commit Record”,数据库才会据此真正修改数据,修改完再写一条”End Record”表示持久化完成。这样一来,只要日志成功写入Commit Record,即使 真正改数据时崩溃,重启后照日志重演一遍即可(持久性成立);只要日志里没有 Commit Record,这次修改就当作没发生过、直接标记回滚(原子性成立)。SQLite 采用的Shadow Paging是另一种思路——不改原数据而是复制一份改副本,最后把 指针原子地切到新副本,逻辑更简单但并发能力较弱,高性能数据库用得不多。 Commit Logging有一个先天限制——不允许在事务提交前把变动数据提前写盘,见 [[Write-Ahead-Logging的FORCE与STEAL组合与崩溃恢复三阶段]]中WAL如何突破 这个限制。

参考来源

- 位置:《凤凰架构:构建可靠的大型分布式系统》第3章"事务处理"3.1.1节 "实现原子性和持久性"(源文件:_epub-src对应OEBPS/Text/chapter26.xhtml) - 结论依据:原文说明写盘存在中间状态、崩溃不可避免,因此必须先以日志 形式记录变动,只有日志中出现Commit Record才真正改数据,并逐条解释这 为何能同时保证持久性与原子性,直接支撑本卡片结论。 - 原始内容:只有在日志记录全部安全落盘,数据库在日志中看到代表事务成功 提交的"提交记录"(Commit Record)后,才会根据日志上的信息对真正的数据 进行修改……这种事务实现方法被称为"提交日志"(Commit Logging)。