digoal
2024-03-26
PostgreSQL , PolarDB , DuckDB , 从库 , 物理复制 , 逻辑复制
创建逻辑从库时, 耗时最长的是初始数据拷贝的阶段, 为了解决这个问题, 可以使用pg_createsubscriber将物理复制从库转换为逻辑从库.
https://www.postgresql.org/docs/devel/app-pgcreatesubscriber.html
To create a logical replica for databases hr and finance from a physical replica at foo:
$ pg_createsubscriber -D /usr/local/pgsql/data -P "host=foo" -d hr -d finance
基本思想是源服务器有一个复制起点,并设置从该点开始进行逻辑复制:
1、使用指定的命令行选项启动目标服务器。如果目标服务器已经在运行,pg_createsubscriber
将终止并出现错误。
2、检查目标服务器是否可以转换。源服务器上还有一些检查。如果不满足任何先决条件,pg_createsubscriber
将终止并出现错误。
3、为源服务器上的每个指定数据库创建发布和复制槽。每个publication都使用FOR ALL TABLES
创建。如果publication-name
未指定选项,则其名称模式如下:“ pg_createsubscriber_%u_%x
”(参数:database oid
、random int
)。如果replication-slot-name
未指定,则复制槽具有以下名称模式:“ pg_createsubscriber_%u_%x
”(参数:database oid
、random int
)。这些复制槽将在未来的步骤中由订阅使用。最后一个复制槽 LSN
用作recovery_target_lsn
参数中的停止点,并由订阅用作复制起点。它保证不会丢失任何交易。
4、将恢复参数写入目标数据目录并重新启动目标服务器。它指定恢复将继续进行的预写日志位置的LSN
( recovery_target_lsn
)。它还指定promote
一旦达到恢复目标服务器应采取的操作。添加额外的恢复参数是为了避免恢复过程中出现意外行为,例如一旦达到一致状态就结束恢复(应应用 WAL 直到复制开始位置)以及可能导致失败的多个恢复目标。一旦服务器结束待机模式并接受读写事务,此步骤即完成。如果--recovery-timeout
设置了选项,如果恢复在给定秒数之前没有结束,则pg_createsubscriber
将终止。
5、为目标服务器上的每个指定数据库创建订阅。如果subscription-name
未指定,则订阅具有以下名称模式:“ pg_createsubscriber_%u_%x
”(参数:database oid
、random int
)。它不会从源服务器复制现有数据。它不会创建复制槽。相反,它使用在上一步中创建的复制槽。订阅已创建,但尚未启用。原因是在开始复制之前必须将复制进度设置为复制起点。
6、删除目标服务器上已复制的发布,因为它们是在复制开始位置之前创建的。它对订阅者没有任何用处。
7、将复制进度设置为每个订阅的复制起点。当目标服务器开始恢复过程时,它会赶上复制起始点。这是用作每个订阅的初始复制位置的确切 LSN。复制源名称是自创建订阅以来获取的。复制源名称和复制起点用于pg_replication_origin_advance()
设置初始复制位置。
8、为目标服务器上的每个指定数据库启用订阅。订阅从复制起点开始应用事务。
9、如果备用服务器正在使用Primary_slot_name
,那么从现在起它就没有用处了,所以请将其删除。
10、更新目标服务器上的系统标识符。运行 pg_resetwal
来修改系统标识符。根据要求停止目标服务器pg_resetwal
。