26.4. 日志传送的替代方法

前面各节中描述的内置备用模式的替代方法是使用restore_command轮询存档位置。这是 8.4 及以下版本中唯一可用的选项。在此设置中,将standby_mode设置为 off,因为您将自己实现待机操作所需的轮询。请参阅pg_standby模块以获得此的参考实现。

请注意,在这种模式下,服务器将一次应用 WAL 一个文件,因此,如果您使用备用服务器进行查询(请参阅热备),则主服务器中的操作与该操作在服务器中可见之间会有一定的延迟。备用,对应于填充 WAL 文件所需的时间。 archive_timeout可用于缩短延迟时间。另请注意,您不能将流复制与此方法结合使用。

主服务器和备用服务器上发生的操作都是正常的连续归档和恢复任务。这两个数据库服务器之间的唯一联系点是共享的 WAL 文件的归档:主要写入归档,备用读取归档。必须注意确保来自不同主服务器的 WAL 存档不会混合在一起或混淆。如果仅用于备用操作,则存档不必很大。

使两个松散耦合的服务器协同工作的魔力只是备用服务器上使用的restore_command,当要求下一个 WAL 文件时,它 await 主服务器上的该文件变为可用。备用服务器上的recovery.conf文件中指定了restore_command。正常的恢复处理将向 WAL 存档请求一个文件,如果该文件不可用,则会报告失败。对于备用数据库处理,下一个 WAL 文件不可用是正常的,因此备用数据库必须 await 它出现。对于以.history结尾的文件,无需 await,并且必须返回非零的返回码。可以将 await 的restore_command写为自定义脚本,该脚本在轮询下一个 WAL 文件的存在之后循环播放。还必须有某种触发故障转移的方法,该方法应中断restore_command,中断循环并向备用服务器返回文件未找到的错误。这样就结束了恢复,然后备用数据库将作为普通服务器启动。

合适的restore_command的伪代码为:

triggered = false;
while (!NextWALFileReady() && !triggered)
{
    sleep(100000L);         /* wait for ~0.1 sec */
    if (CheckForExternalTrigger())
        triggered = true;
}
if (!triggered)
        CopyWALFileForRecovery();

pg_standby模块中提供了 awaitrestore_command的工作示例。它应作为有关如何正确实现上述逻辑的参考。还可以根据需要扩展它以支持特定的配置和环境。

触发故障转移的方法是规划和设计的重要组成部分。一种可能的选择是restore_command命令。每个 WAL 文件都会执行一次,但是运行restore_command的进程会创建并死于每个文件,因此没有守护进程或服务器进程,并且无法使用 signal 或 signal 处理程序。因此,restore_command不适合触发故障转移。可以使用简单的超时工具,尤其是与主要服务器上的archive_timeout设置结合使用时。但是,这有点容易出错,因为网络问题或繁忙的主服务器可能足以启动故障转移。如果可以安排通知机制,例如显式创建触发器文件,则是理想的选择。

26.4.1. Implementation

使用此替代方法配置备用服务器的简短过程如下。有关每个步骤的完整详细信息,请参见前面提到的部分。

  • 设置主要系统和备用系统,使其尽可能接近相同,包括处于相同发行版的两个相同的 PostgreSQL 副本。

  • 在备用服务器上设置从主目录到 WAL 归档目录的连续归档。确保在主数据库上正确设置了archive_modearchive_commandarchive_timeout(请参见Section 25.3.1)。

  • 对主服务器进行基本备份(请参阅Section 25.3.2),并将此数据加载到备用服务器上。

  • 使用指定restore_commandrecovery.conf开始从本地 WAL 存档中的备用服务器上恢复,如前所述(请参见Section 25.3.4)。

恢复将 WAL 存档视为只读,因此一旦 WAL 文件已复制到备用系统中,就可以在备用数据库服务器读取 WAL 文件的同时将其复制到磁带上。因此,可以在存储文件的同时执行备用服务器的高可用性,以实现更长期的灾难恢复目的。

为了进行测试,可以在同一系统上同时运行主服务器和备用服务器。这不会在服务器健壮性方面提供任何有价值的改进,也不会被描述为 HA。

26 .4.2. 基于记录的日志传送

也可以使用此替代方法来实现基于记录的日志传送,尽管这需要自定义开发,并且更改仅在完整 WAL 文件已传送后才对热备用查询可见。

外部程序可以调用pg_walfile_name_offset()函数(请参见Section 9.26)来查找文件名以及 WAL 当前末尾中的确切字节偏移量。然后,它可以直接访问 WAL 文件,并将数据从 WAL 的最后已知端到当前端复制到备用服务器。使用这种方法,数据丢失的时间就是复制程序的轮询周期时间,该时间可能非常小,并且不会因为强制使用部分使用的段文件而浪费带宽。请注意,备用服务器的restore_command脚本只能处理整个 WAL 文件,因此,增量复制的数据通常不可供备用服务器使用。仅当主节点失效时才使用它-然后,最后的部分 WAL 文件在允许它出现之前被馈送到备用数据库。此过程的正确实现需要restore_command脚本与数据复制程序的配合。

从 PostgreSQL 9.0 版开始,您可以使用流复制(请参见Section 26.2.5)以更轻松地获得相同的好处。