ACID(Force & Steal)

PostgreSQL使用CLOG/WAL保证在故障(主机软硬件或数据库自身缺陷)出现时数据库的持久性(D)和原子性(A),实际上除了WAL/CLOG之外还有其他多种方式保证A和D.
从数据库理论上来看,我们首先要理解两个概念Force和Steal.
Force
Force是指在事务commit之前,事务对应的脏页(Dirty Page)必须落盘;与其对应的,No-Force是指在事务commit之前,脏页可以不落盘.

Steal
Steal是指在事务commit之前,脏页可以落盘;相应的,No-Steal是指在事务commit之前,脏页不允许写入持久化设备.

Force和Steal组合起来一共有4个选项:

1.Force+Steal
事务commit前脏页必须落盘且在执行事务过程中脏页可以落盘.
这种情况下,不需要redo支持(因为commit前脏页已落盘),但需要undo支持(因为脏页在执行过程可以落盘).

2.Force+No-Steal
事务commit前脏页必须落盘且在执行事务过程中脏页不可以落盘.
这种情况下,不需要redo也不需要undo支持.

3.No-Force+Steal
事务commit前脏页不需要落盘且在执行事务过程中脏页可以落盘.
这种情况下,需要redo和undo支持.
PostgreSQL的WAL对应redo,而由于MVCC机制的存在,天然就有before-image并配合clog即可支持undo.

4.No-Force+No-Steal
事务commit前脏页不需要落盘且在执行事务过程中脏页不可以落盘.
这种情况下,需要redo支持但不需要undo.

PostgreSQL使用了上述的第3种方式,避免事务commit刷脏时对磁盘的随机读写,而利用高效的磁盘顺序读写写入WAL.
近几年伴随着新型硬件NVM的出现,新出现了一种WBL(Write-Behind-Log),采用上述第2种方式,也就是在commit时脏页落盘,同时不允许在事务执行过程中脏页写入持久化设备,从而减少了数据的多重写入(normal data+redo log+undo log).有兴趣的可参考相关论文.

请使用浏览器的分享功能分享到微信等