2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0

53.4. 流式复制协议 #

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

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

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

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

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

运行时参数的名称。可用参数在 第 19 章 中有说明。

TIMELINE_HISTORY tli #

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

filename (text)

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

content (text)

时间线历史文件的内容。

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

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

slot_name

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

output_plugin

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

TEMPORARY

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

支持以下选项

TWO_PHASE [ boolean ]

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

RESERVE_WAL [ boolean ]

如果为 true,则此物理复制槽将立即预留WAL。否则,WAL仅在流式复制客户端连接时才预留。默认值为 false。

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

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

FAILOVER [ boolean ]

如果为 true,则启用槽同步到备库,以便在故障转移后可以恢复逻辑复制。默认值为 false。

响应此命令,服务器将发送包含以下字段的单行结果集

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 命令的这种备用语法。

ALTER_REPLICATION_SLOT slot_name ( option [, ...] ) #

更改复制槽的定义。有关复制槽的更多信息,请参见 第 26.2.6 节。此命令目前仅支持逻辑复制槽。

slot_name

要更改的槽的名称。必须是有效的复制槽名称(请参见 第 26.2.6.1 节)。

支持以下选项

FAILOVER [ boolean ]

如果为 true,则启用槽同步到备库,以便在故障转移后可以恢复逻辑复制。

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

如果通过slot_name提供了槽的名称,它将在复制过程中更新,以便服务器知道哪些 WAL 段以及(如果hot_standby_feedback已开启)哪些事务仍被备机需要。

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

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

WAL 数据以一系列 CopyData 消息的形式发送;有关详细信息,请参见第 53.6 节第 53.7 节。(这允许其他信息交织在一起;特别是,如果服务器在开始流式传输后遇到故障,它可以发送 ErrorResponse 消息。)从服务器到客户端的每个 CopyData 消息的有效负载包含以下格式之一的消息

XLogData (B) #
字节 1('w')

将消息标识为 WAL 数据。

Int64

此消息中 WAL 数据的起始点。

Int64

服务器上 WAL 的当前末尾。

Int64

传输时服务器的系统时钟,以 2000-01-01 午夜后的微秒数表示。

字节n

WAL 数据流的一部分。

单个 WAL 记录永远不会跨越两个 XLogData 消息。当 WAL 记录跨越 WAL 页面边界时,因此已经使用延续记录进行拆分,它可以在页面边界处拆分。换句话说,第一个主要 WAL 记录及其延续记录可以在不同的 XLogData 消息中发送。

主 keepalive 消息 (B) #
字节 1('k')

将消息标识为发送方 keepalive。

Int64

服务器上 WAL 的当前末尾。

Int64

传输时服务器的系统时钟,以 2000-01-01 午夜后的微秒数表示。

字节 1

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

接收进程可以随时使用以下消息格式之一将回复发送回发送方(也在 CopyData 消息的有效负载中)

备机状态更新 (F) #
字节 1('r')

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

Int64

备机中接收并写入磁盘的最后一个 WAL 字节的位置 + 1。

Int64

备机中最后一个 WAL 字节的位置 + 1(已刷新到磁盘)。

Int64

备机中最后一个 WAL 字节的位置 + 1(已应用)。

Int64

传输时客户端的系统时钟,以 2000-01-01 午夜后的微秒数表示。

字节 1

如果为 1,则客户端请求服务器立即回复此消息。这可以用来 ping 服务器,以测试连接是否仍然正常。

热备机反馈消息 (F) #
字节 1('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,从 WAL 位置XXX/XXX或槽的confirmed_flush_lsn(参见第 52.19 节)开始,以两者中较大的者为准。此行为使客户端更容易避免在没有要处理的数据时更新其本地 LSN 状态。但是,从与请求的 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)插件接受的选项,请参见第 53.5 节

option_value

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

DROP_REPLICATION_SLOT slot_name [ WAIT ] #

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

slot_name

要删除的槽的名称。

WAIT

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

UPLOAD_MANIFEST #

上传备份清单,以准备进行增量备份。

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

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

LABEL 'label'

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

TARGET 'target'

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

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

TARGET_DETAIL 'detail'

提供有关备份目标的附加信息。

目前,此选项只能在备份目标为server时使用。它指定应将备份写入的服务器目录。

PROGRESS [ boolean ]

如果设置为 true,则请求生成进度报告所需的 information。这将在每个表空间的标头中发送回近似大小,可用于计算流式传输完成的进度。这是通过在传输开始之前列举所有文件大小一次来计算的,因此可能会对性能产生负面影响。特别是,可能需要更长的时间才能流式传输第一批数据。由于数据库文件在备份期间可能会发生变化,因此该大小仅为近似值,在近似值与实际文件发送之间可能会增加或减少。默认值为 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 选项一起使用。如果该值为整数,则它指定压缩级别。否则,它应该是一个逗号分隔的项目列表,每个项目都采用 keywordkeyword=value 的形式。当前,支持的关键字为 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 rate

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

TABLESPACE_MAP [ boolean ]

如果为 true,则在名为 tablespace_map 的文件中包含有关 pg_tblspc 目录中存在的符号链接的信息。tablespace map 文件包含每个符号链接名(它存在于 pg_tblspc/ 目录中)和该符号链接的完整路径。默认值为 false。

VERIFY_CHECKSUMS [ boolean ]

如果为 true,则在启用校验和的情况下,将在基础备份期间验证校验和。如果为 false,则会跳过此步骤。默认值为 true。

MANIFEST manifest_option

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

MANIFEST_CHECKSUMS checksum_algorithm

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

INCREMENTAL

请求增量备份。在运行具有此选项的基础备份之前,必须执行 UPLOAD_MANIFEST 命令。

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

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

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

spcoid (oid)

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

spclocation (text)

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

size (int8)

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

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

新档案(B)
字节 1('n')

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

字符串

此档案的文件名。

字符串

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

清单(B)
字节 1('m')

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

档案或清单数据(B)
字节 1('d')

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

字节n

数据字节。

进度报告(B)
字节 1('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 中的符号链接将被保留。)

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

在所有上述命令中,当指定类型为 boolean 的参数时,可以省略 value 部分,这等效于指定 TRUE

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符或需要进一步澄清,请使用 此表格 报告文档问题。