PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

pg_receivewal

pg_receivewal — 从 PostgreSQL 服务器流式接收预写日志

Synopsis

pg_receivewal [option...]

描述

pg_receivewal 用于从一个正在运行的 PostgreSQL 集簇流式接收预写日志。预写日志使用流复制协议进行流式传输,并被写入一个本地的文件目录。该目录可以用作归档位置,以便使用基于时间点的恢复来执行还原(参见 Section 25.3)。

pg_receivewal 会在预写日志于服务器上生成时实时地流式传输它,而不会像 archive_command 和 archive_library 那样等待段完成。因此,archive_timeout 在使用 pg_receivewal 时无需设置。

与 PostgreSQL 后备服务器的 WAL 接收器不同,pg_receivewal 默认只在 WAL 文件被关闭时才刷写 WAL 数据。必须指定 --synchronous 选项才能实时刷写 WAL 数据。由于 pg_receivewal 不应用 WAL,当 synchronous_commit 等于 remote_apply 时,不应允许它成为同步后备。如果这样做,它将表现为一个永远追不上的后备,并且会导致事务提交被阻塞。为避免这种情况,你应该要么为 synchronous_standby_names 配置一个合适的值,要么指定一个与之不匹配的 application_name(用于 pg_receivewal),要么把 synchronous_commit 的值改成 remote_apply 以外的值。

预写日志通过一个普通的 PostgreSQL 连接进行流式传输,并使用复制协议。建立连接所用的用户必须拥有 REPLICATION 权限(参见 Section 21.2)或者是超级用户,并且 pg_hba.conf 必须允许复制连接。服务器还必须经过配置,将 max_wal_senders 设置得足够高,以便为该流留出至少一个可用的会话。

预写日志流式传输的起始点是在 pg_receivewal 启动时确定的:

  1. 首先,扫描写入 WAL 段文件的目录,并找到最新的已完成段文件,以下一个 WAL 段文件的开头作为起始点。

  2. 如果无法用前一种方法计算出起始点,并且使用了复制槽,则会额外发出一条 READ_REPLICATION_SLOT 命令来获取该槽的 restart_lsn 用作起始点。只有在从 PostgreSQL 15 及更高版本流式接收预写日志时,此选项才可用。

  3. 如果无法用前一种方法计算出起始点,则使用服务器通过 IDENTIFY_SYSTEM 命令报告的最新 WAL 刷写位置。

如果连接因非致命错误而丢失,或者最初无法建立连接,pg_receivewal 将无限期地重试连接,并尽快重新建立流式传输。要避免这种行为,请使用 -n 参数。

在没有致命错误的情况下,pg_receivewal 将一直运行,直到被 SIGINT(Control+C)或 SIGTERM 信号终止。

选项

-D directory
--directory=directory

写入输出的目录。

此参数是必需的。

-E lsn
--endpos=lsn

当接收到达指定的 LSN 时,自动停止复制并以正常的退出状态 0 退出。

如果存在一条 LSN 恰好等于 lsn 的记录,该记录将被处理。

--if-not-exists

当指定了 --create-slot 且具有指定名称的槽已经存在时,不报错退出。

-n
--no-loop

不在连接错误上进行循环重试。而是立即以错误退出。

--no-sync

此选项使 pg_receivewal 不强制将 WAL 数据刷写到磁盘上。这样速度更快,但意味着随后发生的操作系统崩溃可能会使 WAL 段损坏。一般来说,此选项对测试很有用,但在生产部署中进行 WAL 归档时不应使用。

此选项与 --synchronous 不兼容。

-s interval
--status-interval=interval

指定发送回服务器的状态包之间的秒数。这使得从服务器端监控进度更加容易。值为零会完全禁用周期性的状态更新,但在服务器请求时仍会发送更新,以避免超时断开连接。默认值为 10 秒。

-S slotname
--slot=slotname

要求 pg_receivewal 使用一个现有的复制槽(参见 Section 26.2.6)。使用此选项时,pg_receivewal 会向服务器报告刷写位置,表明每个段何时已被同步到磁盘上,这样服务器就可以在该段没有其他用途时将其移除。

当 pg_receivewal 的复制客户端在服务器上被配置为同步后备时,使用复制槽会向服务器报告刷写位置,但只会在 WAL 文件被关闭时报告。因此,这种配置会导致主服务器上的事务长时间等待,实际上无法令人满意地工作。除此之外还必须指定 --synchronous 选项(见下文),才能使其正确工作。

--synchronous

在接收到 WAL 数据之后立即将其刷写到磁盘上。并且在刷写之后立即向服务器发送一个状态包,而不考虑 --status-interval。

如果 pg_receivewal 的复制客户端在服务器上被配置为同步后备,则应指定此选项,以确保向服务器发送及时的反馈。

-v
--verbose

启用详细模式。

-Z level
-Z method[:detail]
--compress=level
--compress=method[:detail]

启用预写日志的压缩。

压缩方法可以被设置为 gzip、lz4(如果 PostgreSQL 编译时带有 --with-lz4)或 none(表示不压缩)。可以选择指定一个压缩细节字符串。如果该细节字符串是一个整数,则它指定压缩级别。否则,它应该是一个以逗号分隔的列表,其中每一项的形式为 keyword 或 keyword=value。当前唯一支持的关键字是 level。

如果未指定压缩级别,将使用默认的压缩级别。如果只指定了级别而没有提到算法,当级别大于 0 时将使用 gzip 压缩,当级别为 0 时不使用压缩。

后缀 .gz 会在使用 gzip 时被自动添加到所有文件名上;后缀 .lz4 则会在使用 lz4 时被添加。

下列命令行选项控制数据库连接参数。

-d connstr
--dbname=connstr

指定用于连接到服务器的参数,采用 connection string 的形式;这些参数将覆盖任何与之冲突的命令行选项。

为了与其他客户端应用保持一致,此选项被称为 --dbname,但由于 pg_receivewal 不会连接到集簇中的任何特定数据库,连接字符串中包含的任何数据库名都会被服务器忽略。不过,以这种方式提供的数据库名会覆盖默认的数据库名(replication),这一名称用于在 ~/.pgpass 中查找复制连接的密码。类似地,用于连接 PostgreSQL 的中间件或代理可能会将该名称用于连接路由等目的。

-h host
--host=host

指定服务器所在机器的主机名。如果值以斜杠开头,则它被用作 Unix 域套接字的目录。默认值取自 PGHOST 环境变量(如果设置了),否则会尝试进行 Unix 域套接字连接。

-p port
--port=port

指定服务器监听连接所用的 TCP 端口或本地 Unix 域套接字文件扩展名。默认为 PGPORT 环境变量(如果设置了),或者为编译进程序的默认值。

-U username
--username=username

用于连接的用户名。

-w
--no-password

从不发出输入密码的提示。如果服务器要求密码认证,而密码无法通过其他方式(例如 .pgpass 文件)获得,则连接尝试将失败。此选项在没有用户在场输入密码的批处理作业和脚本中很有用。

-W
--password

强制 pg_receivewal 在连接数据库之前提示输入密码。

此选项从来都不是必需的,因为如果服务器要求密码认证,pg_receivewal 会自动提示输入密码。不过,pg_receivewal 会浪费一次连接尝试来发现服务器需要密码。在某些情况下,键入 -W 可以避免这次额外的连接尝试,这样做是值得的。

pg_receivewal 可以执行以下两种操作之一来控制物理复制槽:

--create-slot

创建一个 --slot 中指定名称的新物理复制槽,然后退出。

--drop-slot

删除 --slot 中指定名称的复制槽,然后退出。

此外还有一些其他选项可用:

-V
--version

打印 pg_receivewal 的版本并退出。

-?
--help

显示关于 pg_receivewal 命令行参数的帮助,然后退出。

退出状态

pg_receivewal 在被 SIGINT 或 SIGTERM 信号终止时将以状态 0 退出。(这是结束它的正常方式,因此这不是错误。)对于致命错误或其他信号,退出状态将为非零。

环境

与大多数其他 PostgreSQL 工具一样,此工具也使用 libpq 支持的环境变量(参见 Section 32.15)。

环境变量 PG_COLOR 指定是否在诊断消息中使用颜色。可能的值是 always、auto 和 never。

注记

当使用 pg_receivewal 而不是 archive_command 或 archive_library 作为主要的 WAL 备份方法时,强烈建议使用复制槽。否则,服务器可以随意在预写日志文件被备份之前回收或移除它们,因为无论是 archive_command、archive_library 还是复制槽,都没有提供关于 WAL 流已被归档到什么程度的信息。不过请注意,如果接收方没有跟上获取 WAL 数据的进度,复制槽会耗尽服务器的磁盘空间。

如果源集簇上启用了组权限,pg_receivewal 将在接收到的 WAL 文件上保留组权限。

示例

从位于 mydbserver 的服务器流式接收预写日志,并将其存储在本地目录 /usr/local/pgsql/archive 中:

$ pg_receivewal -h mydbserver -D /usr/local/pgsql/archive

另请参阅

pg_basebackup