2026/6/6 12:47:59
网站建设
项目流程
网站的费用多少,工程网站建设方案,网络营销的特点主要有,易班网站建设一、问题背景在 PostgreSQL 中使用 Debezium CDC#xff08;Logical Replication#xff09; 时#xff0c;为了获取 UPDATE / DELETE 的 before 值#xff0c;通常会设置#xff1a;ALTER TABLE xxx REPLICA IDENTITY FULL;在普通表上#xff0c;这样做往往立刻生效。但…一、问题背景在 PostgreSQL 中使用Debezium CDCLogical Replication时为了获取UPDATE / DELETE 的 before 值通常会设置ALTER TABLE xxx REPLICA IDENTITY FULL;在普通表上这样做往往立刻生效。但当目标表是分区表Partitioned Table时很多人会遇到一个困惑父表已经设置了 REPLICA IDENTITY FULLDebezium 仍然拿不到 beforeUPDATE 事件中 before null。本文就是对这个问题的完整复盘。二、现象描述父表 public.table_mailbox_messageALTER TABLE public.table_message REPLICA IDENTITY FULL;Debezium 正常消费到 UPDATE{ op: u, before: null, after: {...} }Kafka topic、publication、slot 均确认无误Debezium 配置中也已开启include.unchanged.toast: true但 before 始终是 null。三、根因分析分区表的“真实写入表”是谁1️⃣ PostgreSQL 分区表的核心事实在 PostgreSQL 中父表只是逻辑入口真正存数据、执行 UPDATE/DELETE 的是子分区表例如table_mailbox_message ← 父表 ├── table_message_2023 ├── table_message_2024 ├── ... └── table_message_default当你执行UPDATE public.table_message ...实际被修改的是某一个子分区表而不是父表。2️⃣ REPLICA IDENTITY 的判断发生在“被修改的表”上PostgreSQL 在逻辑复制中是否输出 old rowbefore取决于实际被 UPDATE / DELETE 的那张表的 relreplident 设置而不是父表。四、关键验证一步就能看出来SELECT c.relname AS partition, c.relreplident FROM pg_inherits i JOIN pg_class c ON c.oid i.inhrelid WHERE i.inhparent public.table_message::regclass ORDER BY c.relname;典型输出table_message_2026 | d table_message_2027 | d table_message_2028 | d table_message_default | d说明所有分区仍是 DEFAULT逻辑解码不会输出 before五、结论父表 FULL ≠ 分区 FULL❌ 错误理解设置父表 REPLICA IDENTITY FULL就能拿到 before✅ 正确理解必须在“所有可能被写入的分区表”上设置 REPLICA IDENTITY FULL六、解决方案方案一批量设置所有分区为 FULLALTER TABLE public.table_message_2023 REPLICA IDENTITY FULL; ALTER TABLE public.table_message_2024 REPLICA IDENTITY FULL; ... ALTER TABLE public.table_message_default REPLICA IDENTITY FULL;可按年份逐条执行生产更安全方案二只对“当前活跃分区”设置 FULL推荐渐进例如当前写入集中在table_mailbox_message_2028table_mailbox_message_default那只对这两个分区设置 FULL先验证 before 是否正常、WAL 是否可控再决定是否扩展到历史分区。七、Debezium 侧的必要配置对于包含 bytea / text / json 等 TOAST 字段的表建议开启include.unchanged.toast: true否则即便 FULL 生效Debezium 也可能拿不到完整 old row。八、重要风险提示生产必看REPLICA IDENTITY FULL 的代价非常高UPDATE / DELETE 会把整行旧值写入 WAL大字段会显著放大 WALreplication slot 可能积压极端情况下导致磁盘占满因此FULL 是兜底方案不是常规方案有主键时优先用主键若只需要少量字段的 before优先考虑 trigger audit 表九、关于新分区的额外注意事项PostgreSQL不会自动让新建分区继承父表的 REPLICA IDENTITY 设置。这意味着新分区建出来后默认还是 DEFAULT若忘记设置 FULL新分区的 UPDATE again 没 before解决方式在分区创建脚本中显式加ALTER TABLE 新分区 REPLICA IDENTITY FULL;或定期巡检分区的 relreplident十、总结CDC 中 before 是否存在由实际被修改的表决定对分区表父表设置 REPLICA IDENTITY FULL 是不够的必须对子分区逐一设置FULL 有明显的 WAL 与磁盘风险务必评估在 PostgreSQL CDC 场景下分区表的“元数据继承”远没有看起来那么自动。