为什么PG只是用REDO方法来进行数据库的恢复
在阅读<PG数据内核分析>一书中, 看到这样一句话:
PG只是用REDO方法来进行数据库的恢复, 它不使用UNDO是因为其数据的多版本使得UNDO没有必要. 但从本质上来讲, PG日志并非是REDO日志, 而应该是UNDO/REDO日志, 其创建检查点时大体上服从UNDO/REDO日志创建检查点时要服从的规则, 只是做了一点改动.
为什么不使用UNDO呢?
我们知道Oracle数据库恢复时除过redo日志, 还需要undo日志. 看看Oracle数据库是如何恢复的. 先了解一下Oracle undo表空间的作用.
undo表空间
回退段介绍
在Oracle数据库中,当某个事物对数据进行修改时,Oracle首先将数据的原始值保存到一个回退段中。一个事物只能将它的回退信息保存到一个回退段中,而多个并行事物可以使用同一个回退段。
(1)回退段的作用
回退段主要有4个作用,分别是:事物回滚、数据库恢复、读一致性、闪回查询。
–事物回滚:当事物执行失败或用户执行回滚操作(rollback)时,Oracle会利用保存在回退段中的信息将数据恢复到原来的值;
–数据库恢复:当数据库实例运行失败,在数据库重启恢复时,Oracle先利用重做日志文件的信息对数据库进行恢复(包括已提交和未提交的事务),再利用回滚段中的信息回滚未提交的事务;
–读一致性:当一个用户对数据进行修改时,会预先将其原始值保存到回退段中,这时,如果有其它用户访问该数据,则访问回退段中的信息,使当前用户未提交的修改其他用户无法看到,保证了数据的一致性;
–闪回查询:通过保留在回退段中的信息,用户可以查询某个数据在过去某个时刻的状态
(2)回退段的工作方式
当事务开始时,系统分配给该事物一个回退段,在事务的整个生命周期中,当数据发生改变时,数据的原始值被复制到回退段中。回退段采用循环写的方式进行工作,当事务写满回退段的一个区之后,会接着写入回退段的下一个区,当所有的区都写满后,事务开始循环写入到第一个区或者分配新的区(datafile为autoextend)。回退段归用户sys所有,每个回退段至少包含2个区。
总结
个人理解, Oracle未提交数据恢复时, 需要从undo段空间中以回滚(undo)的方式获得"旧版数据", 并且还要写回到数据文件中. 而PG旧版数据就在数据文件中, 所谓恢复, 其实就是更改一下数据的标记, 即: 将原旧版数据"修改标记"成新的即可.
所以, 基于以上机制, 当为提交需要恢复的数据量很大时, PG的数据恢复会很快. 代价就是引入了Vacuum这样的机制.
当然, 上面讲了" PG日志并非是REDO日志", 这个后续研究明白了, 再讲.