pg_rewind - 在时间线分叉后,使用另一个源数据目录同步 PostgreSQL 数据目录
pg_rewind
[选项
...] { --D
| --target-pgdata
} directory
{ --source-pgdata=
| directory
--source-server=
}connstr
pg_rewind 是一款工具,用于在集群时间线分叉后,将一个 PostgreSQL 集群与同一集群的另一个副本进行同步。一种典型的方案是在故障转移后,将旧的主服务器重新联机并作为追随新主服务器的备用服务器。
完成倒带操作后,目标数据目录的状态类似于源数据目录的基本备份。与创建新的基本备份或使用 rsync 等工具不同,pg_rewind 无需比较或复制集群中未更改的关系块。只复制现有关系文件中的已更改块;包括新关系文件、配置文件和 WAL 段在内的所有其他文件都将被完整复制。因此,当数据库很大且各个集群之间只有少部分块不同时,与其他方法相比,倒带操作要快得多。
pg_rewind 检查源集群和目标集群的时间线历史记录,以确定它们分歧的位置并希望在目标集群的 pg_wal
目录中找到一直到分歧点为止的 WAL。分歧点可以在目标时间线上、源时间线上或它们的共同祖先上找到。在目标集群在分歧后不久关闭的典型故障转移场景中这不是问题,但是如果目标集群在分歧后运行很长时间,其旧 WAL 文件可能不再存在。在这种情况下,您可以手动将它们从 WAL 存档复制到 pg_wal
目录,或使用 -c
选项运行 pg_rewind 以自动从 WAL 存档检索它们。pg_rewind 的使用不限于故障转移,例如,备用服务器可以提升,运行一些写入事务,然后再倒带以再次成为备用。
运行 pg_rewind 后,必须完成 WAL 重放,这样数据目录才能处于一致状态。当目标服务器再次启动时,它将进入归档恢复,并重放从分歧点之前最后检查点以来源服务器中生成的所有 WAL。如果在运行 pg_rewind 时源服务器中不再有某些 WAL,因此 pg_rewind 会话无法复制,则必须在启动目标服务器时使其可用。可以通过在目标数据目录中创建 recovery.signal
文件并在 postgresql.conf
中配置合适的 restore_command 来完成此操作。
pg_rewind 要求目标服务器在 postgresql.conf
中启用 wal_log_hints 选项或在使用 initdb 初始化集群时启用数据校验和。这两个目前都不是默认启用的。full_page_writes 也必须设置为 on
,但默认启用。
如果 pg_rewind 在处理过程中失败,那么目标的数据文件夹很可能处于无法恢复的状态。在这种情况下,建议采用新的全新备份。
由于 pg_rewind 从源完全复制配置文件,因此在重新启动目标服务器之前可能需要更正用于恢复的配置,尤其是在目标被重新引入了源的备用时。如果在倒带操作完成后但在未配置恢复的情况下重新启动服务器,目标可能会再次偏离主服务器。
pg_rewind 在发现自己无法直接写入文件时,会立即失败。例如,当源服务器和目标服务器使用相同的文件映射读取只读 SSL 密钥和证书时,就会出现这种情况。如果目标服务器上存在此类文件,建议在运行 pg_rewind 之前将其删除。在执行回退后,其中一些文件可能已从源服务器复制,在这种情况下,可能有必要删除所复制的数据并恢复回退前使用的链接集。
pg_rewind 接受以下命令行参数
-D directory
--target-pgdata=directory
此选项指定与源服务器同步的目标数据目录。在运行 pg_rewind 之前必须干净地关闭目标服务器
--source-pgdata=directory
指定源服务器数据目录的文件系统路径,以使目标数据目录与之同步。此选项要求干净地关闭源服务器。
--source-server=connstr
指定 libpq 连接字符串以连接到源 PostgreSQL 服务器,以使目标服务器与此源服务器同步。连接必须是正常(非复制)连接,其角色在源服务器上具有执行 pg_rewind 所使用函数的足够权限(详情请见注释部分)或超级用户角色。此选项要求源服务器正在运行并接受连接。
-R
--write-recovery-conf
创建 standby.signal
并将连接设置追加到输出目录中的 postgresql.auto.conf
中。此选项需要 --source-server
。
-n
--dry-run
执行所有操作,但实际上不修改目标目录。
-N
--no-sync
默认情况下,pg_rewind
会等待所有文件安全地写入磁盘。此选项导致 pg_rewind
返回而不等待,这更快,但意味着随后的操作系统崩溃可能损坏数据目录。通常,此选项对于测试很有用,但不应在生产安装中使用。
-P
--progress
启用进度报告。启用此选项将在从源集群复制数据时提供近似的进度报告。
-c
--restore-target-wal
如果 pg_wal
目录中不再提供 WAL 文件,则使用目标集群配置中定义的 restore_command
从 WAL 归档文件中检索 WAL 文件。
--config-file=文件名
针对目标集群使用指定的服务器主配置文件。当 pg_rewind 在该集群上执行倒带操作时,它会在内部使用 postgres 命令时影响此操作(当使用选项 -c/--restore-target-wal
检索 restore_command
时,并且强制完成崩溃恢复时)。
--debug
打印详细的调试输出,这对于调试 pg_rewind 的开发人员非常有用。
--no-ensure-shutdown
pg_rewind 要求在倒带之前必须先干净地关闭目标服务器。默认情况下,如果目标服务器未干净地关闭,则 pg_rewind 会在单用户模式下启动目标服务器以首先完成崩溃恢复,然后停止目标服务器。通过传递此选项,pg_rewind 会跳过此步骤并立即报告错误(如果服务器未干净地关闭)。在此情况下,用户应当自行处理这种情况。
--sync-method=方法
设置为 fsync
(这是默认值)时,pg_rewind
会递归打开数据目录中的所有文件并对它们进行同步。文件搜索将遵循 WAL 目录和每个已配置表空间的符号链接。
在 Linux 上,可以使用 syncfs
来要求操作系统同步包含数据目录、WAL 文件和每个表空间的整个文件系统。有关使用 syncfs
时需要了解的注意事项,请参见 recovery_init_sync_method。
使用 --no-sync
时,此选项不起作用。
-V
--version
显示版本信息,然后退出。
-?
--help
显示帮助,然后退出。
使用 --source-server
选项时,pg_rewind 也使用 libpq 支持的环境变量(请参见 第 32.15 节)。
环境变量 PG_COLOR
指定是否在诊断消息中使用颜色。可能的值有 always
、auto
和 never
。
在将在线集群用作源使用 pg_rewind 时,可以对在源集群上执行 pg_rewind 使用的函数拥有足够权限的角色进行操作(而不是超级用户)。以下是创建在此处名为 rewind_user
的此类角色的方法
CREATE USER rewind_user LOGIN; GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user; GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;
基本思路是从源集群复制所有文件系统级别的变更并将其复制到目标集群
扫描目标群集的 WAL 日志,从源群集的时间线历史分叉目标群集之前的最后一个检查点开始。对于每个 WAL 记录,记录了触及的每个数据块。这会生成一个源群集分叉后在目标群集已更改的所有数据块的列表。如果某些 WAL 文件不再可用,请尝试在 pg_rewind 中重新运行 -c
选项,以在 WAL 存档中搜索丢失的文件。
从源群集使用直接文件系统访问 (--source-pgdata
) 或 SQL (--source-server
) 将所有这些已更改的块复制到目标群集。现在关系文件的状态等同于在源群集和目标群集的时间线分歧之前最后一次完成检查点的时刻,以及此次分歧后在源群集更改的所有块的当前状态。
将所有其他文件(包括新的关系文件、WAL 段、pg_xact
和配置文件)从源群集复制到目标群集。与基本备份类似,目录内容 pg_dynshmem/
、pg_notify/
、pg_replslot/
、pg_serial/
、pg_snapshots/
、pg_stat_tmp/
和 pg_subtrans/
从从源群集复制的数据中省略。文件 backup_label
、tablespace_map
、pg_internal.init
、postmaster.opts
、postmaster.pid
和 .DS_Store
以及任何以 pgsql_tmp
开头的文件或目录均会省略。
创建一个 backup_label
文件在故障转移时创建的检查点开始 WAL 重播,并使用最小一致性 LSN(当从活动源回滚时定义为 pg_current_wal_insert_lsn()
的结果,或当从已停止源回滚时定义为最后一个检查点 LSN)配置 pg_control
文件。
当启动目标时,PostgreSQL 会重播所有必需的 WAL,从而使数据目录处于一致的状态。