Skip to content

55.4. 流复制协议#

要启动流复制,前端在启动消息中发送replication参数。Boolean 值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 (int8)

当前时间轴 ID。还可用于检查备用服务器是否与主服务器一致。

xlogpos (text)

当前 WAL 刷新位置。这有助于在可开始流式传输的预写式日志中获取一个已知位置。

dbname (text)

已连接的数据库或 null。

SHOW name #

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

name

运行时参数的名称。可用参数在 第 20 章 中进行了说明。

TIMELINE_HISTORY tli #

请求服务器发送时间线 tli 的时间线历史记录文件。服务器通过包含两个字段的单行结果集进行回复。虽然这些字段标记为 text,但它们实际上返回原始字节,而不进行编码转换

filename (text)

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

content (text)

时间线历史记录文件的内容。

CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL | LOGICAL output_plugin } [ ( option [, ...] ) ] #

创建物理或逻辑复制槽。有关复制槽的更多信息,请参见 第 27.2.6 节

slot_name

要创建的槽的名称。必须是有效的复制槽名称(请参见 第 27.2.6.1 节)。

output_plugin

用于逻辑解码的输出插件的名称(请参见 第 49.6 节)。

TEMPORARY

指定此复制槽是临时槽。临时槽不会保存到磁盘,并且会在出错或会话结束时自动删除。

支持以下选项

TWO_PHASE [ boolean ]

如果为 true,则此逻辑复制槽支持解码两阶段提交。使用此选项,将解码和传输与两阶段提交相关的命令,例如 PREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED。事务将在 PREPARE TRANSACTION 时间解码和传输。默认值为 false。

RESERVE_WAL [ boolean ]

如果为 true,此物理复制槽会立即保留 。否则,只有在流复制客户端连接时才会保留 。默认值为 false。

SNAPSHOT { 'export' | 'use' | 'nothing' }

决定在逻辑槽初始化期间创建的快照的处理方式。默认值为 'export',它会导出快照以供其他会话使用。此选项不能在事务中使用。 'use' 会将快照用于执行命令的当前事务。此选项必须在事务中使用,并且 CREATE_REPLICATION_SLOT 必须是该事务中运行的第一个命令。最后,'nothing' 只会将快照用于逻辑解码,但不会执行其他任何操作。

作为对该命令的响应,服务器将发送一个包含以下字段的一行结果集

slot_name (text)

新创建的复制槽的名称。

consistent_point (text)

槽变得一致的 WAL 位置。这是可以在此复制槽上开始流式传输的最早位置。

snapshot_name (text)

命令导出的快照的标识符。快照有效,直到在此连接上执行新命令或复制连接关闭。如果创建的槽是物理槽,则为 Null。

output_plugin (text)

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

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

为了与较旧版本兼容,CREATE_REPLICATION_SLOT 命令的此备用语法仍然受支持。

READ_REPLICATION_SLOT slot_name #

读取与复制槽相关的一些信息。如果复制槽不存在,则返回一个包含 NULL 值的元组。目前,此命令仅支持物理复制槽。

响应此命令时,服务器将返回一个包含以下字段的一行结果集

slot_type (text)

复制槽的类型,为 physicalNULL

restart_lsn (text)

复制槽的 restart_lsn

restart_tli (int8)

restart_lsn 关联的时间线 ID,遵循当前时间线历史记录。

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

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

如果通过 slot_name 提供了槽的名称,则它将在复制过程中更新,以便服务器知道备用仍然需要哪些 WAL 段,以及如果 hot_standby_feedback 处于启用状态,则需要哪些事务。

如果客户端请求的时间线不是最新的,但属于服务器的历史记录,则服务器将从请求的开始点开始流式传输该时间线上的所有 WAL,直到服务器切换到另一个时间线为止。如果客户端请求在旧时间线的末尾进行流式传输,则服务器将完全跳过 COPY 模式。

在流式传输不是最新时间线上的所有 WAL 后,服务器将通过退出 COPY 模式来结束流式传输。当客户端通过也退出 COPY 模式来确认此操作后,服务器将发送一个包含一行和两列的结果集,指示此服务器历史记录中的下一个时间线。第一列是下一个时间线的 ID(类型 int8),第二列是发生切换的 WAL 位置(类型 text)。通常,切换位置是已流式传输的 WAL 的末尾,但在某些特殊情况下,服务器可以在提升之前发送一些它自己尚未重放的旧时间线 WAL。最后,服务器发送两个 CommandComplete 消息(一个结束 CopyData,另一个结束 START_REPLICATION 本身),并准备接受新命令。

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,则客户端请求服务器立即回复此消息。这可用于 ping 服务器,以测试连接是否仍然正常。

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

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

Int64

传输时的客户端系统时钟,单位为 2000-01-01 午夜以来的微秒数。

Int32

备用当前的全局 xmin,排除任何复制槽中的 catalog_xmin。如果此值和以下 catalog_xmin 均为 0,则将其视为通知,在此连接上将不再发送热备用反馈。后来的非零消息可能会重新启动反馈机制。

Int32

备用上全局 xmin xid 的纪元。

Int32

备用上任何复制槽的最低 catalog_xmin。如果备用上不存在 catalog_xmin 或正在禁用热备用反馈,则设置为 0。

Int32

备用上 catalog_xmin xid 的纪元。

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

指示服务器从 WAL 位置 XXX/XXX 或槽的 confirmed_flush_lsn(请参阅第 54.19 节)开始流式传输 WAL 以进行逻辑复制,以较大者为准。此行为使客户端在没有数据要处理时更轻松地避免更新其本地 LSN 状态。但是,从与请求不同的 LSN 开始可能无法捕获某些类型的客户端错误;因此,客户端可能希望在发出 START_REPLICATION 之前检查 confirmed_flush_lsn 是否符合其预期。

服务器可以回复错误,例如如果槽不存在。如果成功,服务器将使用 CopyBothResponse 消息进行回复,然后开始向前端流式传输 WAL。

CopyBothResponse 消息中的消息格式与为 START_REPLICATION ... PHYSICAL 记录的格式相同,包括两个 CommandComplete 消息。

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

SLOT slot_name

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

XXX/XXX

开始流式传输的 WAL 位置。

option_name

传递给槽的逻辑解码输出插件的选项的名称。有关标准 (pgoutput) 插件接受的选项,请参见 第 55.5 节

option_value

与指定选项关联的可选值,采用字符串常量的形式。

DROP_REPLICATION_SLOT slot_name [ WAIT ] #

删除复制槽,释放任何保留的服务器端资源。如果该槽是在 walsender 连接的数据库之外的数据库中创建的逻辑槽,则此命令会失败。

slot_name

要删除的槽的名称。

WAIT

此选项会导致命令在槽处于活动状态时等待,直到它变为非活动状态,而不是引发错误的默认行为。

BASE_BACKUP [ ( option [, ...] ) ] #

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

LABEL 'label'

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

TARGET 'target'

告诉服务器将备份发送到何处。如果目标是 client(这是默认值),则备份数据将发送到客户端。如果它是 server,则备份数据将写入 TARGET_DETAIL 选项指定的路径名的服务器。如果它是 blackhole,则备份数据不会发送到任何地方;它只是被丢弃。

server 目标需要超级用户权限或被授予 pg_write_server_files 角色。

TARGET_DETAIL 'detail'

提供有关备份目标的其他信息。

目前,此选项仅可用于备份目标为 server 的情况。它指定应将备份写入到的服务器目录。

PROGRESS [ boolean ]

如果设置为 true,则请求生成进度报告所需的信息。这将在每个表空间的标头中发回一个近似大小,该大小可用于计算流已完成的进度。这是通过在传输开始前枚举所有文件大小一次来计算的,因此可能会对性能产生负面影响。特别是,在流式传输第一个数据之前可能需要更长的时间。由于数据库文件在备份期间可能会发生变化,因此大小只是近似的,并且可能在估算时间和发送实际文件之间增长和缩小。默认值为 false。

CHECKPOINT { 'fast' | 'spread' }

设置基本备份开始时要执行的检查点类型。默认值为 spread

WAL [ boolean ]

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

WAIT [ boolean ]

如果设置为 true,则备份将等到最后一个必需的 WAL 段已存档,或者在未启用 WAL 存档时发出警告。如果为 false,则备份既不会等待也不会发出警告,让客户端负责确保所需的日志可用。默认值为 true。

COMPRESSION 'method'

指示服务器使用指定的方法压缩备份。目前,支持的方法有 gziplz4zstd

COMPRESSION_DETAIL detail

指定所选压缩方法的详细信息。这应仅与 COMPRESSION 选项结合使用。如果该值是一个整数,则它指定压缩级别。否则,它应是一个用逗号分隔的项列表,每个项的形式为 关键字关键字=值。目前,支持的关键字为 levellongworkers

level 关键字设置压缩级别。对于 gzip,压缩级别应为 19 之间的整数(默认 Z_DEFAULT_COMPRESSION-1),对于 lz4,为 1 到 12 之间的整数(默认 0,表示快速压缩模式),对于 zstd,为 ZSTD_minCLevel()(通常为 -131072)和 ZSTD_maxCLevel()(通常为 22)之间的整数(默认 ZSTD_CLEVEL_DEFAULT3)。

long 关键字启用长距离匹配模式,以提高压缩比,但会增加内存使用量。长距离模式仅受 zstd 支持。

workers 关键字设置用于并行压缩的线程数。并行压缩仅受 zstd 支持。

MAX_RATE 速率

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

TABLESPACE_MAP [ 布尔值 ]

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

VERIFY_CHECKSUMS [ 布尔值 ]

如果为 true,则在启用时,在基本备份期间验证校验和。如果为 false,则跳过此步骤。默认值为 true。

MANIFEST manifest_option

当此选项指定为 yesforce-encode 值时,将创建备份清单并随备份一起发送。清单是备份中存在的所有文件的列表,但 WAL 文件除外。它还存储每个文件的大小、上次修改时间以及校验和(可选)。force-encode 值强制所有文件名进行十六进制编码;否则,仅对名称为非 UTF8 八位字节序列的文件执行此类编码。 force-encode 主要用于测试目的,以确保读取备份清单的客户端可以处理此情况。为了与之前的版本兼容,默认值为 MANIFEST 'no'

MANIFEST_CHECKSUMS checksum_algorithm

指定应应用于备份清单中包含的每个文件的校验和算法。当前,可用的算法有 NONECRC32CSHA224SHA256SHA384SHA512。默认值为 CRC32C

启动备份时,服务器将首先发送两个普通结果集,然后发送一个或多个 CopyOutResponse 结果。

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

第二个普通结果集为每个表空间有一行。此行中的字段为

spcoid (oid)

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

spclocation (text)

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

size (int8)

表空间的近似大小,以千字节(1024 字节)为单位(如果已请求进度报告);否则为 null。

在第二个常规结果集之后,将发送 CopyOutResponse。每个 CopyData 消息的有效负载将包含以下格式之一的消息

新存档 (B)
Byte1('n')

标识消息为指示新存档的开始。主数据目录将有一个存档,每个附加表空间将有一个存档;每个都将使用 tar 格式(遵循 POSIX 1003.1-2008 标准中指定的“ustar 交换格式”)。

字符串

此存档的文件名。

字符串

对于主数据目录,为空字符串。对于其他表空间,则是创建此存档的目录的完整路径。

清单 (B)
Byte1('m')

标识消息为指示备份清单的开始。

存档或清单数据 (B)
Byte1('d')

标识消息为包含存档或清单数据。

Byten

数据字节。

进度报告 (B)
Byte1('p')

标识消息为进度报告。

Int64

已完成处理的当前表空间的字节数。

在发送 CopyOutResponse 或所有此类响应后,将发送最终的普通结果集,其中包含备份的 WAL 结束位置,格式与开始位置相同。

数据目录和每个表空间的 tar 存档将包含目录中的所有文件,无论它们是 PostgreSQL 文件还是添加到同一目录的其他文件。唯一排除的文件是

  • postmaster.pid

  • postmaster.opts

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

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

  • 未记录的关系,除了在恢复时重新创建(空)未记录的关系所需的 init 分支。

  • pg_wal,包括子目录。如果备份在包含 WAL 文件的情况下运行,将包含 pg_wal 的合成版本,但它将仅包含备份工作所需的必要文件,而不是其余内容。

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

  • 跳过常规文件和目录之外的文件,例如符号链接(上述目录除外)和特殊设备文件。(pg_tblspc 中的符号链接将被保留。)

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