基于Debezium的新旧数据库双向同步如何规避无限循环?
无需修改旧库的Debezium双向同步防循环方案
针对你的新旧库双向同步场景,无需修改旧库结构的前提下,有以下几种可靠方案规避无限循环:
1. 基于数据库会话标识的事件过滤(推荐)
核心思路:让同步应用在写入目标库时,设置一个专属的会话标识(比如应用名称),然后在Debezium连接器中过滤掉来自该标识的变更事件,避免同步操作触发反向同步。
操作步骤:
- 同步应用配置:连接数据库时,设置会话级的应用名称标识。以MySQL为例,在JDBC URL中添加参数:
PostgreSQL可通过jdbc:mysql://host:port/db?initConnect=SET @@session.appname='debezium-sync'application_name参数设置:jdbc:postgresql://host:port/db?application_name=debezium-sync - Debezium连接器配置:添加事件过滤规则,跳过来自
debezium-sync应用的变更。以MySQL连接器为例,添加以下transform配置:
同步应用写入产生的CDC事件会被直接过滤,不会进入事件流触发反向同步,从根源避免循环。transforms=filterSyncOps transforms.filterSyncOps.type=io.debezium.transforms.Filter transforms.filterSyncOps.language=jsr223.groovy transforms.filterSyncOps.condition=!record.source().get("appname").equals("debezium-sync")
2. 基于事务上下文的标记过滤
如果数据库支持在CDC事件中携带事务上下文信息,可让同步应用在执行同步操作时,设置一个自定义的事务标记,然后在Debezium中过滤包含该标记的事件。
比如PostgreSQL中,可通过SET LOCAL sync_operation = 'true'在事务内设置本地变量,再通过Debezium的自定义扩展捕获该变量,编写过滤规则跳过标记为同步操作的事件。这种方案需要数据库支持自定义上下文的捕获,配置复杂度稍高,但无需修改表结构。
3. 基于操作来源的事件路由
利用Debezium事件中的source字段(包含数据库服务器、实例等信息),在你的同步应用中做路由判断:
- 收到来自旧库的事件时,仅同步至新库;
- 收到来自新库的事件时,先判断该事件是否由新应用写入(可通过新应用的专属会话标识、写入逻辑特征判断),只有新应用产生的变更才同步至旧库,同步操作产生的新库变更直接跳过。
这种方案无需修改Debezium配置,完全在同步应用中实现逻辑判断,适合对Debezium配置修改受限的场景。
注意事项
- 所有方案的核心都是区分业务操作和同步操作,避免同步操作触发反向同步;
- 优先选择会话标识过滤方案,实现简单、可靠性高,且对业务无侵入;
- 若使用事件路由方案,需确保新应用的写入操作有明确可识别的特征,避免误判。
内容的提问来源于stack exchange,提问作者universeasteroid
相关产品推荐
相关产品推荐

