pg_createsubscriber — 将物理副本转换为新的逻辑副本
pg_createsubscriber [option...] { -d | --database }dbname { -D | --pgdata }datadir { -P | --publisher-server }connstr
pg_createsubscriber从物理备库创建新的逻辑副本。 指定数据库中的所有表都会包含在逻辑复制配置中。 每个数据库都会创建一对发布和订阅对象。 该工具必须在目标服务器上运行。
成功运行后,目标服务器的状态类似于一个全新的逻辑复制配置。 逻辑复制配置与pg_createsubscriber之间的主要区别在于 数据同步的完成方式。pg_createsubscriber 不会复制初始表数据。它只执行同步阶段,以确保每个表都达到同步状态。
pg_createsubscriber主要面向大型数据库系统, 因为在逻辑复制配置中,大部分时间都花在复制初始数据上。 此外,在数据同步上花费较长时间的一个副作用通常是,会有大量在初始数据复制期间产生的更改需要应用, 这会进一步延后逻辑副本可用的时间。对于较小的数据库,建议建立带初始数据同步的逻辑复制。 详见CREATE SUBSCRIPTION的 copy_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_replication_slots和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-phase, pg_createsubscriber会在禁用两阶段提交的情况下建立逻辑复制。 这意味着任何预备事务都会在COMMIT PREPARED时被复制, 而不会事先进行预备。配置完成后,你可以手动删除并重新创建订阅, 并启用two_phase 选项。
pg_createsubscriber会使用pg_resetwal 修改系统标识符。 这样可以避免目标服务器可能使用源服务器的 WAL 文件。 如果目标服务器还有备库,复制将会中断,应创建一个新的备库。
若缺少必需 WAL 文件,复制可能失败。 为避免该问题,源服务器应将 max_slot_wal_keep_size设置为-1, 以确保必需 WAL 文件不会被提前移除。
基本思路是从源服务器获得复制起点,并从该位置开始建立逻辑复制:
使用指定命令行选项启动目标服务器。 若目标服务器已在运行,pg_createsubscriber会报错终止。
检查目标服务器是否可以转换,同时也会对源服务器进行一些检查。 若任一前置条件不满足,pg_createsubscriber会报错终止。
在源服务器上为每个指定的数据库创建一个发布和一个复制槽。 每个发布都以FOR ALL TABLES创建。 若未指定--publication,发布名称模式为 “pg_createsubscriber_%u_%x” (参数:数据库oid、随机int)。 若未指定--replication-slot,复制槽的名称模式如下: “pg_createsubscriber_%u_%x” (参数:数据库oid、随机int)。 这些复制槽将在后续步骤中被订阅使用。最后一个复制槽的 LSN 会在 recovery_target_lsn参数中用作停止点,也会被订阅用作复制起点。 这样可以保证不会丢失任何事务。
将恢复参数写入目标数据目录并重启目标服务器。 它指定了恢复将推进到的预写式日志位置的 LSN(recovery_target_lsn)。 它还将promote指定为服务器在达到恢复目标后应执行的动作。 为了避免恢复过程中出现意外行为,还会添加其他恢复参数,例如在达到一致状态后就结束恢复 (实际上 WAL 应继续应用到复制起始位置)以及因多个恢复目标而导致失败。 当服务器退出备库模式并接受读写事务时,该步骤结束。 如果设置了--recovery-timeout选项,而恢复在给定秒数内没有结束, pg_createsubscriber就会终止。
在目标服务器上为每个指定数据库创建订阅。 若未指定--subscription,名称模式为 “pg_createsubscriber_%u_%x” (参数:数据库oid、随机int)。 该订阅不会复制源服务器上的现有数据,也不会创建复制槽, 而是使用前一步中创建的复制槽。订阅会被创建,但尚不启用, 因为必须在启动复制之前先将复制进度设置到复制起点。
删除在目标服务器上被复制过来的发布(这些发布是在复制起点前创建的), 它们在订阅者上没有用途。
将每个订阅的复制进度设置为复制起点。 当目标服务器开始恢复过程时,它会追赶到复制起点。 这正是每个订阅要用作初始复制位置的 LSN。 由于订阅已经创建,因此可以取得复制源名称。 使用复制源名称和复制起点调用 pg_replication_origin_advance() 以设置初始复制位置。
在目标服务器上启用每个指定数据库的订阅。 订阅将从复制起点开始应用事务。
若备库使用了primary_slot_name, 该复制槽之后不再有用,故将其删除。
若备库包含故障切换复制槽, 它们后续无法继续同步,故将其删除。
更新目标服务器上的系统标识符。会运行pg_resetwal 来修改系统标识符。由于pg_resetwal的要求,目标服务器会被停止。
要从位于foo的物理副本为数据库 hr和finance创建逻辑副本:
$pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。