选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

52.4. 流复制协议 #

要启动流复制,前端在启动消息中发送replication参数。布尔值true (或onyes1)告诉后端进入物理复制 walsender 模式,在此模式下,可以发出下面列出的一小组复制命令,而不是 SQL 语句。

database作为replication参数的值传递给后端, 指示其进入逻辑复制 walsender 模式,并连接到dbname参数中指定的数据库。 在逻辑复制 walsender 模式下,可以发出下文所示的复制命令以及普通 SQL 命令。

无论是物理复制还是逻辑复制的 walsender 模式,都只能使用简单查询协议。

为了测试复制命令,可以通过psql或其他使用libpq的工具建立复制连接,连接字符串中应包含replication选项,例如:

psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"

不过,通常更有用的做法是使用pg_receivewal(用于物理复制)或pg_recvlogical(用于逻辑复制)。

复制命令在服务器日志中记录,当启用log_replication_commands时。

复制模式接受以下命令:

IDENTIFY_SYSTEM

请求服务器标识自身。服务器返回一个只有一行的结果集,包含四个字段:

systemid (text)

标识数据库集簇的唯一系统标识符。可用于检查初始化备库的基础备份是否来自同一个数据库集簇。

timeline (int4)

当前时间线 ID。也可用于检查备库是否与主库一致。

xlogpos (text)

当前 WAL 刷盘位置。可用于获取预写式日志中一个已知的位置,以便从该处开始流式传输。

dbname (text)

所连接的数据库,或 null。

SHOW name

请求服务器发送运行时参数的当前设置。这类似于SQL命令SHOW

name

一个运行时参数的名称。可用参数在Chapter 19中有文档记录。

TIMELINE_HISTORY tli

请求服务器发送时间线 tli 的时间线历史文件。服务器返回一个只有一行的结果集,包含两个字段。虽然这些字段被标记为 textbytea,它们实际返回的是原始字节,不进行转义或编码转换:

filename (text)

时间线历史文件的文件名,例如,00000002.history

content (bytea)

时间线历史文件的内容。

CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin [ EXPORT_SNAPSHOT | NOEXPORT_SNAPSHOT | USE_SNAPSHOT ] } #

创建一个物理或逻辑复制槽。查看Section 26.2.6了解更多关于复制槽的信息。

slot_name

要创建的复制槽名称。必须是合法的复制槽名称(参见Section 26.2.6.1)。

output_plugin

用于逻辑解码的输出插件名称(参见 Section 48.6)。

TEMPORARY

该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。

RESERVE_WAL

指定此物理复制槽立即保留 WAL。否则,只有在流复制客户端连接时才会保留 WAL

EXPORT_SNAPSHOT
NOEXPORT_SNAPSHOT
USE_SNAPSHOT

决定如何处理初始化逻辑复制槽时创建的快照。默认选项 EXPORT_SNAPSHOT 会导出快照供其他会话使用,此选项不能在事务内使用。USE_SNAPSHOT 会将快照用于执行该命令的当前事务;此选项必须在事务内使用,且 CREATE_REPLICATION_SLOT 必须是该事务中执行的第一条命令。最后,NOEXPORT_SNAPSHOT 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。

作为对此命令的响应,服务器会发送仅含一行的结果集,其中包含以下字段:

slot_name (text)

新建复制槽的名称。

consistent_point (text)

复制槽达到一致状态时的 WAL 位置。这是可从该复制槽开始流式传输的最早位置。

snapshot_name (text)

该命令导出的快照标识符。该快照在此连接上执行下一条命令之前,或复制连接关闭之前有效。如果所创建的是物理复制槽,则为 null。

output_plugin (text)

新建复制槽所使用的输出插件名称。如果所创建的是物理复制槽,则为 null。

START_REPLICATION [ SLOT slot_name ] [ PHYSICAL ] XXX/XXX [ TIMELINE tli ]

指示服务器开始流式传输WAL,从WAL位置XXX/XXX开始。 如果指定了TIMELINE选项,则流式传输将从时间线tli开始; 否则,将选择服务器当前的时间线。如果请求的WAL部分已经被回收,服务器可能会回复错误。 成功时,服务器将用CopyBothResponse消息回复,然后开始向前端流式传输WAL。

如果通过slot_name提供了复制槽名称, 那么在复制进行期间会更新该复制槽,以便服务器知道哪些 WAL 段, 以及在启用了 hot_standby_feedback 时,哪些事务 仍然被备库所需要。

如果客户端请求的时间线不是最新时间线,但属于服务器的历史,服务器会从请求的起点开始,流式传输该时间线上的所有 WAL,直到服务器切换到另一条时间线的位置。如果客户端请求的流式传输起点恰好位于旧时间线的末尾,服务器会立即返回 CommandComplete,而不进入 COPY 模式。

在非最新时间线上流式传输完全部 WAL 后,服务器会通过退出 COPY 模式来结束流式传输。当客户端也通过退出 COPY 模式来确认时,服务器会发送一个包含一行两列的结果集,指示该服务器历史中的下一条时间线。第一列是下一条时间线的 ID(类型为 int8),第二列是发生切换的 WAL 位置(类型为 text)。通常,切换位置就是所流式传输 WAL 的末尾,但也存在一些边界情况,服务器可能会先发送一些自己在提升前尚未重放的旧时间线 WAL。最后,服务器发送 CommandComplete 消息,然后准备接受新的命令。

WAL 数据通过一系列 CopyData 消息发送。(这样可以混合发送其他信息;尤其是服务器在开始流式传输后遇到故障时,可以发送 ErrorResponse 消息。)服务器发给客户端的每条 CopyData 消息,其有效载荷都包含一条具有下列格式之一的消息:

XLogData (B)
Byte1('w')

将该消息标识为 WAL 数据。

Int64

本消息中 WAL 数据的起始位置。

Int64

服务器上当前的 WAL 末尾位置。

Int64

发送消息时服务器的系统时钟,以自 2000-01-01 午夜以来的微秒数表示。

Byten

WAL 数据流的一个片段。

单条 WAL 记录绝不会被拆分到两条 XLogData 消息中。当 WAL 记录跨越 WAL 页边界,因而已经通过续接记录拆分时,可以在页边界处分开发送。换句话说,最初的主 WAL 记录及其续接记录可以在不同的 XLogData 消息中发送。

主库保活消息 (B)
Byte1('k')

将该消息标识为发送端保活消息。

Int64

服务器上当前的 WAL 末尾位置。

Int64

发送消息时服务器的系统时钟,以自 2000-01-01 午夜以来的微秒数表示。

Byte1

1 表示客户端应尽快回复此消息,以避免超时断开连接;否则为 0。

接收进程可以随时使用以下消息格式之一回复发送端(同样放在 CopyData 消息的有效载荷中):

备库状态更新 (F)
Byte1('r')

将该消息标识为接收端状态更新。

Int64

备库已接收并写入磁盘的最后一个 WAL 字节的位置加 1。

Int64

备库已刷盘的最后一个 WAL 字节的位置加 1。

Int64

备库已应用的最后一个 WAL 字节的位置加 1。

Int64

发送消息时客户端的系统时钟,以自 2000-01-01 午夜以来的微秒数表示。

Byte1

如果为 1,表示客户端请求服务器立即回复此消息。可用它向服务器发送探测请求,以测试连接是否仍然正常。

热备反馈消息 (F)
Byte1('h')

将该消息标识为热备反馈消息。

Int64

发送消息时客户端的系统时钟,以自 2000-01-01 午夜以来的微秒数表示。

Int32

备库当前的全局 xmin,不包括任何复制槽的 catalog_xmin。如果此值及后面的 catalog_xmin 都为 0,则视为通知服务器:此连接将不再发送热备反馈。之后的非零消息可以重新启动反馈机制。

Int32

备库全局 xmin 事务 ID 的纪元。

Int32

备库上所有复制槽中最小的 catalog_xmin。如果备库上不存在 catalog_xmin,或者正在禁用热备反馈,则设为 0。

Int32

备库 catalog_xmin 事务 ID 的纪元。

START_REPLICATION SLOT slot_name LOGICAL XXX/XXX [ ( option_name [ option_value ] [, ...] ) ]

指示服务器开始为逻辑复制流式传输 WAL,起始 WAL 位置为 XXX/XXX。服务器可以返回错误,例如请求的 WAL 段已被回收。成功时,服务器会响应一条 CopyBothResponse 消息,然后开始向前端流式传输 WAL。

CopyBothResponse 中承载的消息采用与 START_REPLICATION ... PHYSICAL 文档中记载的相同格式。

与所选复制槽关联的输出插件将用于处理流式输出。

SLOT slot_name

要从中流式传输更改的复制槽名称。该参数是必需的,并且必须对应于使用 CREATE_REPLICATION_SLOTLOGICAL 模式下创建的现有逻辑复制槽。

XXX/XXX

开始流式传输的WAL位置。

option_name

传递给复制槽逻辑解码输出插件的选项名称。请参阅Section 52.5, 了解标准(pgoutput)插件接受的选项。

option_value

指定选项相关的可选值,以字符串常量的形式表示。

DROP_REPLICATION_SLOT slot_name [ WAIT ]

删除复制槽,释放任何保留的服务器端资源。如果该槽是逻辑槽,且创建它的数据库与 walsender 当前连接的数据库不同,则此命令失败。

slot_name

要删除的复制槽名称。

WAIT

该选项会让命令在复制槽处于活跃状态时等待,直到其变为非活跃,而不是按默认行为报错。

BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ]

指示服务器开始流式传输基础备份。系统会在备份开始前自动进入备份模式,在备份完成后退出该模式。接受以下选项:

LABEL 'label'

设置备份的标签。如果未指定,则将使用base backup作为备份标签。 标签的引用规则与打开standard_conforming_strings的标准SQL字符串相同。

PROGRESS

请求生成进度报告所需的信息。这将在每个表空间的头部发回大致大小,可用于计算流式传输的完成进度。此大小通过在传输开始之前枚举所有文件大小来计算,因此可能对性能有负面影响。特别是在第一个数据被发出之前可能需要更长的时间。

FAST

请求快速检查点。

WAL

如果设置为true,则在备份中包含必要的WAL段。这将包括在开始和停止备份之间的所有文件在基本目录tar文件的pg_wal目录中。默认值为false。

NOWAIT

默认情况下,备份会等待最后一个必需的 WAL 段完成归档;如果未启用日志归档,则发出警告。指定 NOWAIT 会同时禁用等待和警告,由客户端负责确保所需日志可用。

MAX_RATE rate

限制(节流)每单位时间从服务器传输到客户端的最大数据量。预期的单位是每秒千字节。 如果指定了此选项,则该值必须等于零,或者必须在32 kB到1 GB(含)的范围内。 如果传递零或未指定该选项,则不对传输施加任何限制。

TABLESPACE_MAP

如果为true,则在名为tablespace_map的文件中包含目录pg_tblspc中存在的符号链接的信息。 表空间映射文件包括目录pg_tblspc/中每个符号链接的名称及该符号链接的完整路径。默认值为false。

NOVERIFY_CHECKSUMS

默认情况下,如果启用了校验和,基础备份期间就会验证校验和。指定 NOVERIFY_CHECKSUMS 会禁用此项验证。

备份开始时,服务器首先发送两个普通结果集,然后发送一个或多个 CopyResponse 结果。

第一个普通结果集包含备份的起始位置,在一个包含两列的单行中。第一列包含以XLogRecPtr格式给出的起始位置,第二列包含相应的时间线ID。

第二个普通结果集为每个表空间包含一行。这一行的字段如下:

spcoid (oid)

表空间的OID,如果是基本目录则为null。

spclocation (text)

表空间目录的完整路径,如果是基本目录则为null。

size (int8)

如果请求了进度报告,则为表空间的大致大小;否则为空值。

在第二个普通结果集之后,会发送一个或多个 CopyResponse 结果,其中一个用于主数据目录,其他结果分别用于 pg_defaultpg_global 之外的各个附加表空间。CopyResponse 结果中的数据是表空间内容的 tar 格式转储(遵循 POSIX 1003.1-2008 标准中规定的 ustar interchange format),但省略了标准规定的末尾两个全零块。tar 数据传输完成后,会发送最后一个普通结果集,其中包含备份的 WAL 结束位置,格式与起始位置相同。

数据目录和每个表空间的 tar 归档都会包含目录中的所有文件,无论是PostgreSQL文件,还是添加到同一目录的其他文件。仅排除以下文件:

  • postmaster.pid

  • postmaster.opts

  • pg_internal.init(在多个目录中找到)

  • PostgreSQL 服务器运行期间创建的各种临时文件和目录,例如以pgsql_tmp开头的任何文件或目录以及临时关系。

  • 不记录 WAL 的关系(Unlogged表),除了需要在恢复时重新创建(空的)不记录 WAL 的关系的init fork。

  • pg_wal,包括子目录。如果备份包含WAL文件,则将包含pg_wal的合成版本,但它只包含备份工作所需的文件,而不包含其余内容。

  • pg_dynshmempg_notifypg_replslotpg_serialpg_snapshotspg_stat_tmppg_subtrans将作为空目录复制(即使它们是符号链接)。

  • 除了常规文件和目录之外的文件,如符号链接(除了上述列出的目录之外的符号链接)以及特殊设备和操作系统文件,将被跳过。(pg_tblspc中的符号链接将被保留。)

如果服务器底层文件系统支持,还会设置所有者、组和文件模式。