55.4. 流复制协议#
要启动流复制,前端在启动消息中发送replication
参数。Boolean 值true
(或on
、yes
、1
)告诉后端进入物理复制 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 TRANSACTION
、COMMIT PREPARED
和ROLLBACK 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
)复制槽的类型,为
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 消息发送。(这允许混合其他信息;特别是如果服务器在开始流式处理后遇到故障,则可以发送 ErrorResponse 消息。)从服务器到客户端的每个 CopyData 消息的有效负载包含以下格式之一的消息
- XLogData (B) #
- Byte1('w')
将消息标识为 WAL 数据。
- Int64
此消息中 WAL 数据的起始点。
- Int64
服务器上 WAL 的当前结束点。
- Int64
传输时的服务器系统时钟,单位为 2000-01-01 午夜以来的微秒数。
- Byte
n
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_SLOT
在LOGICAL
模式中创建的现有逻辑复制槽。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'
指示服务器使用指定的方法压缩备份。目前,支持的方法有
gzip
、lz4
和zstd
。COMPRESSION_DETAIL
detail
指定所选压缩方法的详细信息。这应仅与
COMPRESSION
选项结合使用。如果该值是一个整数,则它指定压缩级别。否则,它应是一个用逗号分隔的项列表,每个项的形式为关键字
或关键字=值
。目前,支持的关键字为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
速率
限制(节流)从服务器传输到客户端的数据的最大量,以每单位时间为单位。预期单位为千字节每秒。如果指定此选项,则该值必须等于零或必须在 32 kB 到 1 GB(包括)的范围内。如果传递零或未指定该选项,则不对传输施加任何限制。
TABLESPACE_MAP [
布尔值
]如果为真,则在名为
tablespace_map
的文件中包含有关目录pg_tblspc
中存在的符号链接的信息。表空间映射文件包括目录pg_tblspc/
中存在的每个符号链接名称以及该符号链接的完整路径。默认值为假。VERIFY_CHECKSUMS [
布尔值
]如果为 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 交换格式””)。
- 字符串
此存档的文件名。
- 字符串
对于主数据目录,为空字符串。对于其他表空间,则是创建此存档的目录的完整路径。
- 清单 (B)
- Byte1('m')
标识消息为指示备份清单的开始。
- 存档或清单数据 (B)
- Byte1('d')
标识消息为包含存档或清单数据。
- Byte
n
数据字节。
- 进度报告 (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_dynshmem
、pg_notify
、pg_replslot
、pg_serial
、pg_snapshots
、pg_stat_tmp
和pg_subtrans
被复制为目录(即使它们是符号链接)。跳过常规文件和目录之外的文件,例如符号链接(上述目录除外)和特殊设备文件。(
pg_tblspc
中的符号链接将被保留。)
如果服务器上的底层文件系统支持,则设置所有者、组和文件模式。