数据库

保证原子性的两种做法:日志和影子分页

事务做到一半崩溃了,改了一半的数据怎么还原?

  1. 日志:改之前先记下旧值(undo),回滚或崩溃后据此撤销。
  2. 影子分页:要改的页先复制一份(写时复制),在副本上改;提交时把页表的根指针切过去。崩溃了就丢掉没切过去的副本。

影子分页听起来更干净,但几乎没人用在通用数据库里:

  • 改过的页散落在磁盘各处,变成大量随机写
  • 提交时要刷所有改过的页和页表
  • 旧页要回收,也很难支持多个事务并发写

日志是顺序追加,提交时只要把日志刷盘。

容易混的一点:崩溃后撤销没提交的修改靠 undo,属于原子性;重做已提交的修改靠 redo,属于持久性。

esc