1.1 PG日志的实现方式——预写式日志 (WAL)
预写式日志 (WAL):
是一种实现事务日志的标准方法。WAL 的中心思想是对数据文件的修改(它们是表和索引等数据库对象的载体)必须是只能发生在这些修改已经记录了日志之后, 也就是说,在描述这些变化的日志记录冲刷到永久存储器之后。 如果我们遵循这个过程,那么我们就不需要在每次事务提交的时候都把数据页冲刷到磁盘,因为我们知道在出现崩溃的情况下, 我们可以用日志来恢复数据库:任何尚未附加到数据页的记录都将先从日志记录中重做(这叫向前滚动恢复,也叫做 REDO)。
检查点(Checkpoints) 是事务序列中的点, 我们保证在该点之前的所有日志信息都更新到数据文件中去了。 在检查点时,所有脏数据页都冲刷到磁盘并且向日志文件中写入一条特殊的检查点记录。 结果是,在发生崩溃的时候,恢复器就知道应该从日志中的哪个点(称做 redo 记录)开始做 REDO 操作, 因为在该记录前的对数据文件的任何修改都已经在磁盘上了。 在完成检查点处理之后,任何在 redo 记录之前写的日志段都不再需要, 因此可以循环使用或者删除。(在进行 WAL 归档的时候, 这些日志在循环利用或者删除之前必须先归档)。 检查点信息在PG系统中写在了控制文件“\data\global\pg_control”文件中。
WAL 日志存放在数据目录的 pg_xlog 目录里,它是作为一个文件段的集合存储的,通常每个段 16 MB 大。 每个段分割成多个页,通常 8K 大。日志记录头在 access/xlog.h 里描述;日志内容取决于它记录的事件的类型。目前,PG8.x版本记载了14类可以恢复的信息,具体可参见“RmgrTable”中定义的内容。
WAL 的目的是确保在数据库记录被修改之前, 先写了日志,但是可能它们实际上只是缓冲了数据而并未把数据存储到磁盘上。 这种情况下的电源失效仍然可能导致不可恢复的数据崩溃; 管理员应该确保保存 PostgreSQL 的日志文件的磁盘不会做这种虚假汇报。这需要考察磁盘是否缓存了数据信息。
在完成一个检查点并且日志文件冲刷了之后,检查点的位置保存在了文件 pg_control 里。因此在需要做恢复的时候, 后端首先读取 pg_control 和检查点记录; 然后它通过从检查点记录里标识的日志位置开始向前扫描执行 REDO 操作。 因为数据页的所有内容都保存在检查点之后的第一个页面修改的日志里, 所以自检查点以来的所有变化都将被恢复到一个一致的状态。这时,PG调用的是“StartupXLOG”方法进行工作的。
关于物理日志:
物理日志
PG中使用物理日志,而不是逻辑日志
日志记录的单位是磁盘块
日志的存储
系统中存在多个日志段文件
如果一个旧的日志段文件不再需要了,那么它将得到循环使用(重命名为顺序的下一个可用段)。