在 PostgreSQL 的数据目录的 pg_wal (10版本之前是 pg_xlog 子目录)子目录中始终维护一个 WAL 日志文件。该日志文件记录了数据库数据文件的每次改变。最初设计该日志文件的主要目的是为了数据库异常崩溃后,能够重放最后一次 checkpoint 点之后的日志文件,把数据库推到最终的一致状态,避免数据丢失或不一致。

当然,由于此日志文件的机制也提供了另一种热备份方案:先把数据库以文件系统的方式备份出来,同时把相应的 WAL 日志也备份出来。虽然直接复制数据库的数据文件会导致数据文件不一致,如复制的多个数据文件不是同一个时间点的文件。

同时复制一个 8KB 的数据块时也存在数据不一致的情况:假设完前 4KB 个块,而数据库又写了整个 8KB块的内容,这时,复制的这个数据块的前 4KB 块和后 4KB 块不是一个完整的 8KB 数据块,从而导致不一致。但是,因为有了 WAL 日志,即使备份出来的数据块不一致,也可以重放备份开始后的 WAL 日志文件,把备份的文件推到一致状态。

由此可见,当有 WAL 日志之后,备份数据库不再需要一个完美的一致性备份,备份中的任何非一致性数据都会被重放 WAL 日志文件的过程纠正,所以,我们在备份数据库时,可以通过简单的 cp 命令或 tar 等操作系统提供的备份文件的工具,来实现数据库的在线备份。

之后,不停地重放 WAL 日志,就可以把数据库推到备份结束后的任意一个时间点,这就是基于时间点的备份,英文名是 “Point-in-Time Recovery”,缩写为“PITR”。

使用简单的 cp 命令或其他命令把数据库在线复制出来的备份,称为基础备份。从基础备份操作开始之后产生的 WAL 日志和此基础备份构成了一个完整的备份。把基础备份恢复到另一台机器,然后不停地从原始数据库机器上接收 WAL 日志,在新机器上持续重放 WAL 日志,只要应用 WAL 日志足够快,该备数据库就会追上主数据库的变化,拥有当前主数据库的最新数据状态。这个新机器上的数据库被称为 Standby (备份)数据库

当主数据库出现问题无法正常服务时,可把 standby 打开提供服务,从而实现高可用。

把 WAL 日志传送到另一台机器上的方法有两种:一是通过 WAL 归档日志方法;二是通过流复制


-- 摘自 《PostgreSQL修炼之道 从小工到专家》第2版 。