You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL13.1双Schema双向逻辑复制的无限循环问题咨询

问题1:该双向复制场景是否会触发无限循环?

会触发无限循环。
PostgreSQL逻辑复制的默认机制会将订阅端应用到表上的所有变更写入WAL日志,如果你同时在两侧配置了指向对方的发布-订阅关系,schema1.table1的本地变更同步到schema2.table2后,schema2侧的发布规则会把这条同步产生的变更再次发回schema1,循环往复,直到事务ID耗尽或磁盘空间占满,该问题和是否存在并发修改同一条数据的场景无关,只要双向发布订阅规则未做特殊限制就会触发。

问题2:可行的规避方案(适配PostgreSQL 13.1版本)

以下方案按实施复杂度从低到高排序:

  • 方案1:利用复制起源(Origin)跟踪机制原生规避
    PostgreSQL逻辑复制默认会给所有通过订阅同步过来的变更打上origin标记,发布规则默认不会二次发布带有origin标记的WAL记录,你只需在创建两侧订阅时保持默认参数origin = true即可,无需修改表结构或业务逻辑。
    如果你已经创建了订阅,可以执行以下命令确认配置:

    -- 查看所有订阅的origin配置
    SELECT subname, suborigin FROM pg_subscription;
    -- 如果suborigin为none,修改为启用origin跟踪
    ALTER SUBSCRIPTION 你的订阅名称 SET (origin = true);
    

    注意:同实例跨schema的逻辑复制场景也支持该机制,无需额外适配。

  • 方案2:增加来源标记字段做行过滤
    如果你需要更可控的同步规则,可以通过新增字段结合PostgreSQL 13支持的发布行过滤功能实现:

    1. 给两侧表新增来源标记字段:
    ALTER TABLE schema1.table1 ADD COLUMN data_origin TEXT NOT NULL DEFAULT 'schema1';
    ALTER TABLE schema2.table2 ADD COLUMN data_origin TEXT NOT NULL DEFAULT 'schema2';
    
    1. 调整两侧发布规则,仅发布本地产生的变更:
    -- 修改schema1侧的发布,仅同步origin为schema1的行变更
    ALTER PUBLICATION pub_schema1 SET TABLE schema1.table1 WHERE (data_origin = 'schema1');
    -- 修改schema2侧的发布,仅同步origin为schema2的行变更
    ALTER PUBLICATION pub_schema2 SET TABLE schema2.table2 WHERE (data_origin = 'schema2');
    

    该方案优势是规则透明,适合需要自定义同步逻辑的场景。

  • 方案3:按操作用户过滤发布内容
    如果你的业务只有Django应用用户会写入这两张表,可以直接在发布规则中过滤掉复制用户产生的变更:

    -- 替换为你的Django业务访问用户和发布名称
    ALTER PUBLICATION pub_schema1 SET TABLE schema1.table1 WHERE (current_user = 'django_app_user');
    ALTER PUBLICATION pub_schema2 SET TABLE schema2.table2 WHERE (current_user = 'django_app_user');
    

    该方案无需修改表结构,适合业务写入入口固定的场景。

注意:你当前确认无同一条数据的并发修改场景,无需额外配置冲突处理规则;如果后续业务调整存在冲突可能,可以将订阅的conflict_resolution参数设置为'apply_remote'或自定义冲突触发器解决。

内容的提问来源于stack exchange,提问作者kallada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 08:18:03