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

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

55.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

一个运行时参数的名称。可用参数在第 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 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' 只会像平常一样将快照用于逻辑解码,不会对其执行其他操作。

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

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

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 消息发送,详见第 55.6 节和第 55.7 节。(这样可以混合发送其他信息;尤其是服务器在开始流式传输后遇到故障时,可以发送 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 或该复制槽的 confirmed_flush_lsn(参见第 54.19 节)中的较大者。这种行为让客户端在没有数据可处理时更容易避免更新本地 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

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

option_value

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

DROP_REPLICATION_SLOT slot_name [ WAIT ] #

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

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,备份既不等待也不警告,而由客户端负责确保所需 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。

当备份开始时,服务器将首先发送两个普通的结果集,然后是一个或多个 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 中的符号链接将被保留。)

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

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.