29.6 多集群迁移环境
Pigsty 能把两个 PostgreSQL 集群、服务发现、连接池、监控和配置组织在同一个管理面里, 但迁移的数据面仍跨越两个独立系统。最危险的自动化错误,往往不是 SQL 写错,而是把 命令发到了正确环境中的错误 cluster、database 或 service。
本节把端点身份、凭据、观测和退出窗口做成多集群迁移的硬边界。
29.6.1 源、目标、验证端点与隔离凭据
给每类动作一个明确端点
| 端点 | 连接对象 | 允许动作 | 不应承担 |
|---|---|---|---|
| source migration | 源 primary/direct-write service | 建 publication/slot、读快照、写 marker | 普通应用写 |
| source runtime | 源业务 service | 迁移前业务读写,冻结后负向 canary | 管理 slot |
| target migration | 目标 primary/direct-write service | 建 schema/subscription、装载、sequence | 源端管理 |
| target runtime | 目标业务 service | 影子读、切流后业务读写 | 超级用户迁移 DDL |
| verification | 两端只读连接 | manifest、目录、业务不变量 | 修复或路由变更 |
| monitoring | exporter/API/dashboard | 采集两端与代理指标 | 作为业务正确性的唯一证据 |
源 logical replication 连接必须到能够创建 slot、持续发送 WAL 的 primary。目标 subscription 在目标 database 中创建,apply 写目标表。不要把“read service”名称当作 复制端点,也不要把 HA service 的自动切换能力误认为 slot 已具备 failover 语义。
每次 run 先打印并保存非秘密身份:
并断言 source 与 target system_identifier 不同。database 名称相同不等于同一个
数据源,IP 不同也不保证不是同一 cluster 的两个实例。
凭据按职责和环境隔离
至少拆分:
replication 角色需要源端 LOGIN REPLICATION,initial copy 还需要 published table
的 SELECT;它不需要目标端 DDL。目标 runtime 不应能回写源。验证角色不应因为要比较
数据而获得修复权限。
连接合同还包括:
- TLS mode、CA 与 hostname verification;
- 精确 HBA source CIDR 和 role classification;
CONNECT、schemaUSAGE、table privilege;- secret manager 引用、有效期和轮换 owner;
- conninfo 禁止出现在公开证据、进程参数或 shell trace;
- 迁移完成后的 revoke/rotate 清单。
本章第一次候选实验在插入 fixture 之前就被 Pigsty HBA 拒绝:临时登录角色没有加入
HBA 所使用的平台分类角色。实验没有放宽成全网 trust,而是把 runtime 与 replication
账号分别加入 dbrole_readwrite / dbrole_readonly,并使用
INHERIT FALSE, SET FALSE,只满足成员分类,不继承平台对象权限。失败候选随后按 marker
精确清理,确认两端 database、role、slot 与 subscription 都不存在。
这条失败很有价值:HBA 的“能否建立连接”和 SQL grant 的“连上后能做什么”是两道 独立门。
Pigsty 迁移上下文是编排模板,不是控制平面替身
Pigsty 的 pgsql-migration.yml 可以围绕 source/target inventory 生成并组织:
以及需要 operator 落实的 source disable 和 re-routing 步骤。使用时应:
- 固定 Pigsty/模板版本;
- 审阅生成的变量、端点和 SQL;
- 把生成物与迁移 ticket 绑定;
- 在 disposable database 完整演练;
- 由实际应用/网络 owner 实施写围栏与切流;
- 用 PostgreSQL catalog 和应用身份反向复核。
本章正式实验在本地开发环境以 pg-test 为源、pg-meta 为目标,各自创建一次性
database 和角色。这只是为了在有限实验环境里证明真正的双 cluster 边界。生产中不应
因为教程这样做,就把承担 Pigsty 管理面的 pg-meta 当成默认业务迁移目标。
29.6.2 观察槽、WAL、延迟与切换流量
先用原生视图定义信号
源端:
目标端:
再加上 pg_subscription_rel table state、PostgreSQL log 和业务 marker。不同版本的
视图列会变化,自动化应先断言 server major,而不是对未知列 SELECT * 后按位置解析。
关键关系是:
正式实验禁用 subscription 后确认 slot inactive,生成 3,000 条变化:
重新启用后才追平。这个小规模实验不能给生产容量一个固定阈值,却证明“subscriber 不工作”会转化为 publisher 的磁盘风险。
max_slot_wal_keep_size 可以限制 checkpoint 时 slot 允许保留的 WAL;超过后 slot
可能失去继续消费所需的 WAL,而不是自动帮 consumer 修好。PostgreSQL 18 的
idle_replication_slot_timeout 可以在 checkpoint 时使长期闲置 slot 失效,synced
slot 有例外。二者都是保险丝,不能代替 owner、告警、rebootstrap 方案和容量预算。
Pigsty 视图负责聚合,catalog 负责定案
Pigsty 的 PGSQL、Replication、Persist、Service 与 Proxy 等 dashboard 可以统一观察:
dashboard 适合关联趋势和告警;切流门禁仍应把关键 catalog query、时间范围和截图/导出 写入证据包。监控抓取间隔可能错过瞬时状态,面板也不会知道 marker 是否已被应用查询 读到。
logical slot failover 需要一整组前提
PostgreSQL 18 支持 failover logical slot,但不能只设置 failover = true 就宣称源端
primary 可无缝切换。完整设计还涉及:
- primary 上 slot 标记为 failover;
- standby 启用
sync_replication_slots; - standby 配置
primary_slot_name和可用的 physical replication slot; primary_conninfo包含可连接到正确 database 的配置;- physical standby 向上游提供所需 feedback;
- 对需要的同步边界使用
synchronized_standby_slots; - 切换前确认目标 standby 上对应 slot 已
synced且位置安全; - connector/subscriber 重新连接后的 endpoint 与 timeline 测试。
这些参数影响可用性、WAL 保留和复制反馈,必须在与生产同构的故障切换演练中验证。 未做这套设计时,源 primary failover 可能要求重新 bootstrap;迁移窗口要把它列为明确 故障分支。
路由观测与数据复制是两条链
publication/subscription 不知道业务连接走 DNS、HAProxy、PgBouncer 还是配置中心。 切流证据至少包括:
监控图中的目标 TPS 上升只是旁证。最强证据是使用真实 runtime 凭据建立一个新连接, 验证目标系统身份并完成可回读 canary。
29.6.3 保留源环境直到退出观察窗口
保留不是继续双主写入
切流后的源环境应进入受保护状态:
这样它既能支持调查和条件回退,又不会继续产生与目标分叉的新事实。若业务需要 reverse replication,应把它作为独立的数据合同:方向、冲突、sequence、DDL、RPO 和停止点都要 明确,不能把两个方向各建一个 subscription 就叫 active-active。
退出窗口用条件,不只用日期
观察窗口可以有最短时长,但退出还应同时满足:
- 所有应用、worker、ETL、BI 和管理入口已迁到目标;
- 旧 service/pool 不再产生业务连接;
- 目标 SLO 经历了至少一个代表性高峰和关键批任务;
- manifest、分桶和业务不变量连续通过;
- 目标独占写边界与备份恢复已验证;
- 告警、值班、容量和灾备 runbook 已移交;
- 迁移临时 slot/subscription/reject 已有保留或清理决策;
- source 回退 SLA 已到期,并有 owner 签收;
- 资产、CMDB、DNS、secret 与文档已更新。
如果月末关账是系统最关键路径,只观察一个低峰小时即使所有图都绿色,也没有覆盖真实 业务周期。
清理按依赖方向进行
正常 subscription 与远端 slot 仍关联且源端可达时,DROP SUBSCRIPTION 会尝试删除
远端 slot。若先断网络或删除源 database,目标端 drop 可能失败,源端还可能留下孤儿
slot。退出流程应:
- 记录 subscription、publication、slot、owner 和最终位置;
- 停止/确认 consumer 不再需要;
- 在两端都可达时正常删除 subscription;
- 在源端确认 main slot 与 table-sync slot 均不存在;
- 再删除 publication 和迁移临时角色/权限;
- 轮换生产凭据;
- 将 source decommission 作为独立、可审计且明确不可逆的变更。
不要使用“删除所有 inactive slot”“终止所有连接”或 DROP DATABASE ... WITH (FORCE)
作为通用收尾。正式实验的清理只匹配本 run 创建的 database、role、subscription 和
slot;没有终止无关 session,普通 database drop 即成功。
保留窗口结束后,旧源也不应无限期成为影子生产系统。无限保留会继续消耗备份、补丁、 监控与安全治理成本,还让团队误以为随时能回到一个早已过期的数据副本。退出签收就是 把“临时可回退”正式转化为“目标为唯一权威,恢复走新体系”。
上一节:异构同步的语义损失 · 返回本章目录 · 下一节:实战:迁移 pg36_shop ·
查看全书目录 · 查看索引中心