受支持版本: 当前版本 (18) / 17 / 16
开发版本: devel

pg_createsubscriber

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

Synopsis

pg_createsubscriber [option...] { -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

到发布者的连接字符串。详情见Section 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_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-phasepg_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

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。