将物理副本转换为逻辑副本

本页目录

在某些情况下,将现有的异步物理副本转换为逻辑副本可能是有利的,或者先创建一个新的物理副本,然后将其转换为逻辑副本。

这种方式:

因此,这种方法非常适用于需要将源数据库中的所有数据呈现在新创建的逻辑副本中的情况,特别是在处理非常大且负载繁重的集群时极为有用。

下面的步骤十分简单。我们使用一个物理副本,通过流复制 primary_conninfo 和复制槽 (比如通过 Patroni 进行控制) 立即从主库复制数据,不涉及级联复制 (尽管也有可能实现)。

步骤1:选择一个用于转换的物理副本

选择一个物理副本进行转换,或者通过 pg_basebackup、从备份恢复或从云快照创建新的物理副本。

确保在转换期间没有用户使用该副本。

步骤2:确保满足要求

首先,确保为逻辑复制配置了相关设置,如逻辑复制配置中所述。

主库设置:

在我们将要转换的物理副本上:

此外:

步骤3:停止物理副本

关闭物理副本,并在下一步执行期间保持其关闭。这确保其位置比我们将在主库上创建的逻辑槽的位置早。

步骤4:创建发布、逻辑槽并记录其LSN

在主库上:

  1. 手动执行一次 CHECKPOINT;
  2. 创建发布;
  3. 创建逻辑复制槽并记录其 LSN 位置。

示例:

SQL
checkpoint;

create publication my_pub for all tables;

select lsn
from pg_create_logical_replication_slot(
  'my_slot',
  'pgoutput'
);

请务必记住最后一条命令返回的 LSN 值 — 稍后我们会使用到它。

步骤5:让物理副本追赶上主库

重新配置物理副本:

现在启动物理副本,监控其延迟情况,直到副本追赶上我们需要的 LSN 并自动提升。这可能需要一些时间。完成之后进行检查:

SQL
select pg_is_in_recovery();

步骤6:创建订阅并启动逻辑复制

在新创建的"克隆"节点上,创建逻辑订阅 copy_data = false 和 create_slot = false:

SQL
create subscription 'my_sub'
connection 'host=.. port=.. user=.. dbname=..'
publication my_pub
with (
  copy_data = false,
  create_slot=false,
  slot_name = 'my_slot'
);

确保复制处于运行中的状态 — 在源主库上检查:

SQL
select * from pg_replication_slots;

确保 active 字段为 t。

完成

额外说明

在这个方案中,我们使用了单个发布和逻辑复制槽。也可以使用多个槽,只需对过程进行一些调整。但是,如果选择这样做,请记住使用多个复制槽/发布的潜在复杂性,首先是这些:

以及无论如何:

我见

看了一下操作流程,确实十分繁琐,17 版本中的 pg_createsubscriber 无疑是个巨大的福音,大大简化了将物理副本转化为逻辑副本的步骤。

pg_createsubscriber to create a logical replica from a physical standby server

另外原文中所说的最后一点,在 17 版本看似也已解决。具体可以参照上面的邮件

以及如下🔗:

讨论与补充

在 GitHub 查看讨论

支持作者

感谢支持 PostgreSQL Howto 的长期维护。

微信赞赏码

读者交流群

二维码若已过期,可通过公众号 PostgreSQL 学徒或邮件联系。

PostgreSQL 学徒读者交流群二维码