29.5. WAL 内部
WAL是自动打开的。除了要求一些磁盘空间存放WAL 日志以及一些必要的调节以外(参阅Section 29.4),对管理员没有什么其它要求。
WAL日志存放在数据目录的pg_xlog
子目录里, 它是作为一个文件段的集合存储的,通常每段 16MB (但是大小可以通过建立服务器时改变 --with-wal-segsize
配置选项改变)。每个段又分割成多个页,通常每页 8KB(这个大小可以通过 --with-wal-blocksize
配置选项改变)。日志记录头在access/xlog.h
里描述; 日志内容取决于它记录的事件类型。段文件的名字是递增自然数,从000000010000000000000000
开始。这些数字不能循环使用,不过要把所有可用的数字都用光也需要非常长的时间。
日志位于和主数据库文件位于不同的磁盘上会比较好。你可以通过把pg_xlog
目录移动到另外一个位置(此时必须关闭服务器),然后在原来的位置创建一个指向新位置的符号链接。
WAL的目的是确保在数据库记录被修改之前先写日志, 但是这个目的有可能被那些向内核谎报成功写入的磁盘驱动器 破坏,这时候, 它们实际上只是缓冲了数据而并未把数据存储到磁盘上。 这种情况下的电源失效仍然可能导致不可恢复的数据崩溃;管理员应该确保保存 PostgreSQL的WAL日志文件的磁盘不会做这种虚假汇报。 (参阅 Section 29.1.)
在完成一个检查点并且刷新了日志文件之后,检查点的位置就保存在了pg_control
文件里。因此在恢复开始的时候,后端首先读取pg_control
和检查点记录; 然后通过从检查点记录里标识的日志位置开始向前扫描执行 REDO 操作。 因为数据页的所有内容都保存在检查点之后的第一个页面修改的日志里(假设 full_page_writes没有禁用),所以自检查点以来的所有变化都将被恢复到一个一致的状态。
但是为了处理pg_control
可能的损坏, 我们应该支持对现存日志段的反向顺序扫描(从最新到最老),这样才能找到最后的检查点。 这些还没有实现。pg_control
很小(比一个磁盘页小), 因此它出现只写了一部分的问题的概率几乎为零,到目前为止, 我们还没有看到不能读取pg_control
自身的错误。因此, 尽管这在理论上是一个薄弱环节,但是实践中pg_control
似乎并不会出现问题。