2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17
开发版本: devel

pg_createsubscriber

pg_createsubscriber — 将物理副本转换为新的逻辑副本

概要

pg_createsubscriber [选项...] { -d | --database }dbname { -D | --pgdata }datadir { -P | --publisher-server }connstr

描述

pg_createsubscriber 从物理备用服务器创建一个新的逻辑副本。指定数据库中的所有表都包含在 逻辑复制 设置中。为每个数据库创建一对发布对象和订阅对象。它必须在目标服务器上运行。

成功运行后,目标服务器的状态类似于全新的逻辑复制设置。逻辑复制设置和 pg_createsubscriber 之间的主要区别在于数据同步的方式。pg_createsubscriber 不会复制初始表数据。它只执行同步阶段,这确保了每个表都达到同步状态。

pg_createsubscriber 针对大型数据库系统,因为在逻辑复制设置中,大部分时间都花在初始数据复制上。此外,花费大量时间同步数据的副作用通常是需要应用大量的更改(这些更改是在初始数据复制期间产生的),这进一步增加了逻辑副本可用所需的时间。对于小型数据库,建议使用初始数据同步来设置逻辑复制。有关详细信息,请参阅 CREATE SUBSCRIPTIONcopy_data 选项。

选项

pg_createsubscriber 接受以下命令行参数

-a
--all

在目标服务器上为每个数据库创建一个订阅。模板数据库和不允许连接的数据库除外。要发现所有数据库的列表,请使用 --publisher-server 连接字符串中指定的数据库名称连接到源服务器,或者如果未指定,则使用 postgres 数据库,或者如果不存在,则使用 template1 数据库。指定此选项时,将使用自动生成的订阅、发布和复制槽名称。此选项不能与 --database--publication--replication-slot--subscription 一起使用。

-d dbname
--database=dbname

创建订阅的数据库名称。可以通过编写多个 -d 开关来选择多个数据库。此选项不能与 -a 一起使用。如果未提供 -d 选项,则数据库名称将从 -P 选项中获取。如果数据库名称未在 -d 选项或 -P 选项中指定,并且未指定 -a 选项,则会报告错误。

-D directory
--pgdata=directory

包含来自物理副本的集群目录的目标目录。

-n
--dry-run

执行所有操作,但实际上不修改目标目录。

-p port
--subscriber-port=port

目标服务器监听连接的端口号。默认为在端口 50432 上运行目标服务器,以避免意外的客户端连接。

-P connstr
--publisher-server=connstr

到发布者的连接字符串。有关详细信息,请参阅 第 32.1.1 节

-s dir
--socketdir=dir

用于目标服务器上的 postmaster 套接字的目录。默认值为当前目录。

-t seconds
--recovery-timeout=seconds

等待恢复结束的最长秒数。设置为 0 则禁用。默认值为 0。

-T
--enable-two-phase

为订阅启用 two_phase 提交。当指定多个数据库时,此选项统一应用于在这些数据库上创建的所有订阅。默认值为 false

-U username
--subscriber-username=username

在目标服务器上连接的用户名。默认为当前操作系统用户名。

-v
--verbose

启用详细模式。这将导致 pg_createsubscriber 将进度消息和每个步骤的详细信息输出到标准错误。重复使用该选项会导致其他调试级别的消息显示在标准错误中。

--clean=objtype

从目标服务器上的指定数据库中删除指定类型的​​所有对象。

  • publications:为该订阅者建立的 FOR ALL TABLES 发布总是被删除;指定此对象类型会导致从源服务器复制的所有其他发布也被删除。

要删除的对象会单独记录,包括在 --dry-run 期间。没有机会影响或停止删除选定的对象,因此请考虑使用 pg_dump 备份它们。

--config-file=filename

为目标数据目录使用指定的服务器主配置文件。pg_createsubscriber 内部使用 pg_ctl 命令启动和停止目标服务器。它允许您指定实际的 postgresql.conf 配置文件,如果它存储在数据目录之外。

--publication=name

用于设置逻辑复制的发布名称。可以通过编写多个 --publication 开关来指定多个发布。发布名称的数量必须与指定的数据库数量匹配,否则会报告错误。多个发布名称开关的顺序必须与数据库开关的顺序匹配。如果未指定此选项,则为发布名称分配一个生成的名称。此选项不能与 --all 一起使用。

--replication-slot=name

用于设置逻辑复制的复制槽名称。可以通过编写多个 --replication-slot 开关来指定多个复制槽。复制槽名称的数量必须与指定的数据库数量匹配,否则会报告错误。多个复制槽名称开关的顺序必须与数据库开关的顺序匹配。如果未指定此选项,则将订阅名称分配给复制槽名称。此选项不能与 --all 一起使用。

--subscription=name

用于设置逻辑复制的订阅名称。可以通过编写多个 --subscription 开关来指定多个订阅。订阅名称的数量必须与指定的数据库数量匹配,否则会报告错误。多个订阅名称开关的顺序必须与数据库开关的顺序匹配。如果未指定此选项,则为订阅名称分配一个生成的名称。此选项不能与 --all 一起使用。

-V
--version

打印 pg_createsubscriber 版本并退出。

-?
--help

显示关于 pg_createsubscriber 命令行参数的帮助信息,然后退出。

注释

先决条件

pg_createsubscriber 将目标服务器转换为逻辑副本需要满足一些先决条件。如果未满足这些条件,将报告错误。源服务器和目标服务器的主版本必须与 pg_createsubscriber 相同。给定的目标数据目录必须与源数据目录具有相同的系统标识符。给定的目标数据目录的用户必须具有创建 订阅 和使用 pg_replication_origin_advance() 的权限。

目标服务器必须用作物理备用服务器。max_active_replication_originsmax_logical_replication_workers 的配置值必须大于或等于指定数据库的数量。目标服务器的 max_worker_processes 配置值必须大于指定数据库的数量。目标服务器必须接受本地连接。如果您计划使用 --enable-two-phase 开关,您还需要适当设置 max_prepared_transactions

源服务器必须接受来自目标服务器的连接。源服务器不得处于恢复模式。wal_level 必须设置为 logical。源服务器的 max_replication_slots 配置值必须大于或等于指定数据库的数量加上现有的复制槽数量。源服务器的 max_wal_senders 配置值必须大于或等于指定数据库的数量加上现有的 WAL 发送器进程数量。

警告

如果 pg_createsubscriber 在目标服务器已提升为主服务器后失败,则数据目录很可能处于无法恢复的状态。在这种情况下,建议创建一个新的备用服务器。

pg_createsubscriber 在转换过程中通常会使用不同的连接设置来启动目标服务器。因此,对目标服务器的连接应该会失败。

由于 DDL 命令不由逻辑复制复制,因此在运行 pg_createsubscriber 时,请避免执行更改数据库模式的 DDL 命令。如果目标服务器已被转换为逻辑副本,DDL 命令可能不会被复制,这可能会导致错误。

如果 pg_createsubscriber 在处理过程中失败,则在源服务器上创建的对象(发布、复制槽)将被删除。如果目标服务器无法连接到源服务器,删除可能会失败。在这种情况下,警告消息将通知保留的对象。如果目标服务器正在运行,它将被停止。

如果复制正在使用 primary_slot_name,它将在逻辑复制设置后从源服务器中删除。

如果目标服务器是同步备用服务器,则在运行 pg_createsubscriber 时,主服务器上的事务提交可能会等待复制。

除非指定了 --enable-two-phase 开关,否则 pg_createsubscriber 会设置不启用两阶段提交的逻辑复制。这意味着任何预备事务将在 COMMIT PREPARED 时被复制,而无需提前准备。设置完成后,您可以手动删除并重新创建订阅,并启用 two_phase 选项。

pg_createsubscriber 使用 pg_resetwal 更改系统标识符。这将避免目标服务器使用源服务器的 WAL 文件的情况。如果目标服务器有备用服务器,复制将会中断,应该创建一个新的备用服务器。

如果所需的 WAL 文件丢失,可能会发生复制失败。为防止这种情况,源服务器必须将 max_slot_wal_keep_size 设置为 -1,以确保不会过早删除必需的 WAL 文件。

工作原理

基本思路是有一个来自源服务器的复制起点,并设置一个从该起点开始的逻辑复制。

  1. 使用指定的命令行选项启动目标服务器。如果目标服务器已在运行,pg_createsubscriber 将以错误终止。

  2. 检查目标服务器是否可以转换。对源服务器也有一些检查。如果任何先决条件未满足,pg_createsubscriber 将以错误终止。

  3. 在源服务器上为每个指定的数据库创建一个发布和复制槽。每个发布都是使用 FOR ALL TABLES 创建的。如果未指定 --publication 选项,则发布具有以下名称模式:pg_createsubscriber_%u_%x(参数:数据库 oid,随机 int)。如果未指定 --replication-slot 选项,则复制槽具有以下名称模式:pg_createsubscriber_%u_%x(参数:数据库 oid,随机 int)。这些复制槽将在后续步骤中由订阅使用。最后一个复制槽 LSN 用作 recovery_target_lsn 参数中的停止点,并作为订阅的复制起点。它保证不会丢失任何事务。

  4. 将恢复参数写入目标数据目录并重新启动目标服务器。它指定一个 LSN(recovery_target_lsn),表示恢复将进行到的写前日志位置。它还将 promote 指定为服务器达到恢复目标后应采取的操作。添加了额外的 恢复参数,以避免在恢复过程中出现意外行为,例如一旦达到一致状态就结束恢复(WAL 应应用到复制起点位置)以及可能导致失败的多个恢复目标。此步骤在服务器结束备用模式并接受读写事务后完成。如果设置了 --recovery-timeout 选项,如果恢复未在给定的秒数内结束,pg_createsubscriber 将终止。

  5. 在目标服务器上为每个指定的数据库创建一个订阅。如果未指定 --subscription 选项,则订阅具有以下名称模式:pg_createsubscriber_%u_%x(参数:数据库 oid,随机 int)。它不从源服务器复制现有数据。它不创建复制槽。而是使用上一步创建的复制槽。订阅已被创建,但尚未启用。原因是必须在开始复制之前将复制进度设置为复制起点。

  6. 删除目标服务器上已复制的发布,因为它们是在复制起点之前创建的。它在订阅者上没有用。

  7. 将每个订阅的复制进度设置为复制起点。当目标服务器启动恢复过程时,它会赶上复制起点。这是每个订阅的初始复制位置的确切 LSN。复制原点名称是在创建订阅时获得的。复制原点名称和复制起点在 pg_replication_origin_advance() 中用于设置初始复制位置。

  8. 为目标服务器上的每个指定数据库启用订阅。订阅将从复制起点开始应用事务。

  9. 如果备用服务器正在使用 primary_slot_name,则从现在起将不再使用它,因此将其删除。

  10. 如果备用服务器包含 故障转移复制槽,则它们无法再同步,因此将它们删除。

  11. 更新目标服务器上的系统标识符。将运行 pg_resetwal 来修改系统标识符。目标服务器将根据 pg_resetwal 的要求停止。

示例

要从物理副本 foo 为数据库 hrfinance 创建逻辑副本

$ pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance

另请参阅

pg_basebackup

提交更正

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