详情

首页手游攻略 PostgreSQL 19序列怎么同步?逻辑复制切换前要做什么

PostgreSQL 19序列怎么同步?逻辑复制切换前要做什么

佚名 2026-11-02 12:20:02

表记录同步完整,换库后新插入仍可能撞主键。例如已有ID到10000,序列发号却停在100,新库继续发旧号码就会冲突。

19提供了序列同步功能,能减少人工调整。但必须把相关序列纳入范围并完成切换前核对,它不会实时复制每次nextval,更不能保证所有突发故障后都无重复。

一、表里的 ID 和序列,是两件东西

序列好比发号器,表里记录的是已使用号码,发号器另外保存进度。搬走表记录,不代表这个进度也同时搬过去。

serial 和 identity 列通常背后都有序列。应用也可能单独使用一个序列给多张表发号,所以只检查每张表的最大 ID,不一定覆盖所有情况。

二、19 新增的能力,实际怎样工作?

发布端可以把序列加入发布范围。订阅建立时复制初始状态;以后可以通过 REFRESH SEQUENCES,再同步订阅已经知道的序列。

关键限制是发布端必须为 PostgreSQL 19 或更高版本。如果从 17/18 向 19 做逻辑复制升级,只升级订阅端并不能获得这个发布端能力,仍要另外安排序列处理。

此外,它不是每发一个号码就持续推送一次。源端继续使用序列,双方仍会再次出现差距。把它当作自动实时跟随,就容易在切换时漏掉最后一步。

三、一个最小示例,先分清在哪边执行

下面只展示序列发布与刷新,假定两边对象已准备好,连接、权限和逻辑复制基础配置已经完成。在 19 发布端执行:

CREATE PUBLICATION app_sequences FOR ALL SEQUENCES;

订阅端需要建立订阅,或把这个发布加入已有订阅。若已有订阅名为 app_sub,可按已规划的发布范围添加:

ALTER SUBSCRIPTION app_sub ADD PUBLICATION app_sequences;

以后需要重新同步已有序列时,在订阅端执行:

ALTER SUBSCRIPTION app_sub REFRESH SEQUENCES;

如果发布范围新增或移除了序列,应先刷新发布信息,再刷新序列值:

ALTER SUBSCRIPTION app_sub REFRESH PUBLICATION;ALTER SUBSCRIPTION app_sub REFRESH SEQUENCES;

命令发出后,会有后台同步工作。不要把命令返回理解成所有序列已经立即完成同步。需要继续检查状态、日志和目标值,确认没有定义不一致等错误。

四、有计划切换时,顺序怎样安排?

  1. 停止旧库所有发号和写入,包括后台任务与外部服务。
  2. 确认表数据的最后一批修改已同步并处理完成。
  3. 刷新需要的序列,等待后台同步完成。
  4. 核对关键序列的值、是否已经调用,以及递增方式等定义。
  5. 确认旧写入端不会恢复,再开放新库写入。

两边序列的步长、边界、循环等设置也要兼容。只比较 last_value,不看 is_called 和步长,可能误判下一次会发出哪个号码。

五、为什么突发故障后仍要检查?

如果旧发布端突然故障,已经无法再读取最新状态,就不能事后补一次刷新并保证拿到最后值。序列缓存、未同步进度以及其他发号来源,都要纳入判断。

序列日志位置也不是每发一个号码都会变化,仅靠位置相同,不能证明当前值完全一致。对关键发号器,要有经过演练的接管规则,而不是临时猜一个偏大的数字。

对只服务一张表的普通递增序列,可停写后同时核对序列与最大ID。倒序、循环及共享序列需要分别处理,不能统一套用一个setval脚本。

六、它解决了什么,又没有解决什么?

内置同步让迁移和计划切换时更容易把已知状态传到目标端,但旧端停写、最终数据检查以及故障接管规则仍需安排。

避免号码冲突需要完整收尾:表数据已追上,序列已核对,旧端不再产生写入。19简化的是其中的序列处理,不是省掉这些步骤。

点击查看更多
推荐专题
热门阅读