↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
预发布版本文档。 PostgreSQL 19beta4 为测试版本,最终发布内容可能有所不同。

54.4. 流复制协议 #

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

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

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

为了测试复制命令,可以通过 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 #

一个运行时参数的名称。可用参数在第 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 节)。名称不能是 pg_conflict_detection,因为它保留给冲突检测使用。

output_plugin #

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

TEMPORARY #

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

支持以下选项:

TWO_PHASE [ boolean ] #

如果为 true,则该逻辑复制槽支持对两阶段提交进行解码。使用此选项后,PREPARE TRANSACTION、COMMIT PREPARED 和 ROLLBACK 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) #

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

output_plugin (text) #

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

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 节)。

支持以下选项:

TWO_PHASE [ boolean ] #

如果为 true,则该逻辑复制槽支持对两阶段提交进行解码。使用此选项后,PREPARE TRANSACTION、COMMIT PREPARED 和 ROLLBACK PREPARED 等两阶段提交命令会被解码并传输。事务会在 PREPARE TRANSACTION 时解码并传输。

FAILOVER [ boolean ] #

如果为 true,则允许该复制槽同步到备库,以便在故障切换后恢复逻辑复制。

READ_REPLICATION_SLOT slot_name #

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

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

slot_type(text)#

复制槽的类型,可以是 physical 或 NULL。

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 消息发送,详见第 54.6 节和第 54.7 节。(这样可以混合发送其他信息;尤其是服务器在开始流式传输后遇到故障时,可以发送 ErrorResponse 消息。)服务器发给客户端的每条 CopyData 消息,其有效载荷都包含一条具有下列格式之一的消息:

WALData (B) #
Byte1('w') #

将该消息标识为 WAL 数据。

Int64 #

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

Int64 #

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

Int64 #

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

Byten #

WAL 数据流的一个片段。

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

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

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

Int64 #

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

Int64 #

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

Byte1 #

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

主库状态更新 (B) #
Byte1('s') #

将该消息标识为主库状态更新。

Int64 #

服务器上最后插入的 WAL 记录的末尾位置。

Int64 #

服务器上当前处于提交阶段的最老事务 ID 及其纪元。高 32 位为纪元,低 32 位为事务 ID。如果服务器上没有活跃事务,则该值为下一个待分配的事务 ID。

Int64 #

服务器上下一个待分配的事务 ID 及其纪元。高 32 位为纪元,低 32 位为事务 ID。

Int64 #

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

接收进程可以随时使用以下消息格式之一回复发送端(同样放在 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 的纪元。

请求主库状态更新 (F) #
Byte1('p')

将该消息标识为对主库状态更新的请求。

Int64

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

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

指示服务器开始为逻辑复制流式传输 WAL,起点为 WAL 位置 XXX/XXX 或该复制槽的 confirmed_flush_lsn(参见第 53.22 节)中的较大者。这种行为让客户端在没有数据可处理时更容易避免更新本地 LSN 状态。不过,从与请求值不同的 LSN 开始,可能无法捕获某些类型的客户端错误;因此,客户端在发出 START_REPLICATION 之前,可能希望先确认 confirmed_flush_lsn 是否符合预期。

服务器可以返回错误,例如复制槽不存在时。成功时,服务器会响应一条 CopyBothResponse 消息,然后开始向前端流式传输 WAL。

CopyBothResponse 中承载的消息采用与 START_REPLICATION ... PHYSICAL 文档中记载的相同格式,包括两个 CommandComplete 消息。

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

SLOT slot_name #

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

XXX/XXX #

开始流式传输的 WAL 位置。

option_name #

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

option_value #

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

DROP_REPLICATION_SLOT slot_name [ WAIT ] #

删除复制槽,释放任何保留的服务器端资源。

slot_name #

要删除的复制槽名称。

WAIT #

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

UPLOAD_MANIFEST #

上传备份清单(backup manifest),为执行增量备份做准备。

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

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

LABEL 'label' #

设置备份标签。如果未指定,则使用 base backup 作为备份标签。标签的引号规则与标准 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,备份既不等待也不警告,而由客户端负责确保所需 WAL 可用。默认值为 true。

COMPRESSION 'method' #

指示服务器使用指定的方法压缩备份。目前支持的方法有 gzip、lz4 和 zstd。

COMPRESSION_DETAIL detail #

指定所选压缩方法的详细信息。这应该只与 COMPRESSION 选项一起使用。如果该值是一个整数,则指定压缩级别。否则,它应该是一个逗号分隔的项目列表,每个项目的形式为 keyword 或 keyword=value。目前,支持的关键字是 level、long 和 workers。

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

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

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

MAX_RATE rate #

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

TABLESPACE_MAP [ boolean ] #

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

VERIFY_CHECKSUMS [ boolean ] #

如果为 true,则在进行基础备份时验证校验和(如果已启用)。如果为 false,则跳过此步骤。默认值为 true。

MANIFEST manifest_option #

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

MANIFEST_CHECKSUMS checksum_algorithm #

指定应用于备份清单中包含的每个文件的校验和算法。目前,可用的算法有 NONE、CRC32C、SHA224、SHA256、SHA384 和 SHA512。默认值为 CRC32C。

INCREMENTAL #

请求执行增量备份。使用该选项执行基础备份前,必须先执行 UPLOAD_MANIFEST 命令。

当备份开始时,服务器将首先发送两个普通的结果集,然后是一个或多个 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 interchange format”)。

String #

这个归档的文件名。

String #

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

清单 (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 开头的任何文件或目录以及临时关系。

  • 不记录 WAL 的关系,但不包括恢复时重新创建(空的)不记录 WAL 的关系所需的初始化分支。

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

  • pg_dynshmem,pg_notify,pg_replslot,pg_serial,pg_snapshots,pg_stat_tmp 和 pg_subtrans 将作为空目录复制(即使它们是符号链接)。

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

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

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

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.