pg_createsubscriber — 将一个物理副本转换成新的逻辑副本
pg_createsubscriber [option...] { -d | --database }dbname { -D | --pgdata }datadir { -P | --publisher-server }connstr
pg_createsubscriber 从一个物理后备服务器创建一个新的逻辑副本。指定数据库中的所有表都会被包含在 logical replication 设置中。会为每个数据库创建一对发布和订阅对象。它必须在目标服务器上运行。
成功运行之后,目标服务器的状态就类似于一个全新的逻辑复制设置。逻辑复制设置与 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 具有相同的主版本号。给定的目标数据目录必须与源数据目录具有相同的系统标识符。目标数据目录的给定数据库用户必须拥有创建 subscriptions 和使用 pg_replication_origin_advance() 的权限。
目标服务器必须被用作物理后备。目标服务器必须将 max_active_replication_origins 和 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 作为服务器在达到恢复目标后应采取的动作。还会添加额外的 recovery parameters,以避免恢复过程中出现意外行为,例如一达到一致状态就结束恢复(WAL 应该被应用到复制起始位置为止),以及可能导致失败的多个恢复目标。一旦服务器结束后备模式并开始接受读写事务,此步骤即告完成。如果设置了 --recovery-timeout 选项,当恢复在给定的秒数内没有结束时,pg_createsubscriber 将会终止。
在目标服务器上为每个指定的数据库创建一个订阅。如果未指定 --subscription 选项,订阅将采用以下名称模式:“pg_createsubscriber_%u_%x”(参数:数据库 oid、随机 int)。它不会从源服务器复制现有数据。它不会创建复制槽,而是使用在前面的步骤中创建的复制槽。订阅会被创建但尚未启用。原因是在开始复制之前,必须将复制进度设置为复制起始点。
删除目标服务器上那些因为创建于复制起始位置之前而被复制过来的发布。它们在订阅者上没有用处。
为每个订阅将复制进度设置为复制起始点。当目标服务器启动恢复过程时,它会追赶到复制起始点。这就是要用作每个订阅初始复制位置的准确 LSN。复制源名称在订阅创建时即已获得。复制源名称和复制起始点被用在 pg_replication_origin_advance() 中,以设置初始复制位置。
在目标服务器上为每个指定的数据库启用订阅。订阅从复制起始点开始应用事务。
如果后备服务器之前在使用 primary_slot_name,那么它从现在起不再有用,因此将其删除。
如果后备服务器包含 failover replication slots,那么它们再也无法被同步,因此将其删除。
更新目标服务器上的系统标识符。运行 pg_resetwal 来修改系统标识符。按照 pg_resetwal 的要求,目标服务器会被停止。
要为数据库 hr 和 finance 从位于 foo 的物理副本创建逻辑副本:
$pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance