我们在生产环境中遇到了一个 REPLACE TABLE 导致表级 CCR 同步异常的问题。经过初步分析,问题可能与 Doris 侧 REPLACE_TABLE binlog 只关联部分 table id 有关。想请帮忙看一下这个分析是否合理,以及是否可以考虑在 Doris 侧调整相关 binlog 生成逻辑。
问题背景
表级 CCR 任务会记录源端同步表的 table id,并通过 Doris FE GetBinlog(tableId=...) 拉取该表 binlog。
对于 REPLACE TABLE ... PROPERTIES('swap'='true'),Doris 的语义是两张表交换名字。但当前 Doris 生成 REPLACE_TABLE binlog 时,tableIds 只关联 SQL 左侧的 origTblId。如果 CCR 表任务监听的是 SQL 右侧表的 table id,就可能收不到这条 replace binlog。
示例
CCR 表任务同步:
执行前:
A01_INFO -> table id = F
A01_INFO_tmp -> table id = T
上游执行:
ALTER TABLE A01_INFO_tmp
REPLACE WITH TABLE A01_INFO
PROPERTIES('swap'='true');
执行后:
A01_INFO -> table id = T
A01_tmp -> table id = F
Doris 生成的 REPLACE_TABLE binlog 数据大致为:
origTblId = T
origTblName = A01_INFO_tmp
newTblId = F
newTblName = A01_INFO
swapTable = true
但该 binlog 当前只挂在:
CCR 表任务仍在拉:
GetBinlog(tableId = F, prevCommitSeq = ...)
因此它可能收不到这条 REPLACE_TABLE binlog,无法感知正式表名背后的 table id 已经从 F 变成 T。
影响
- 表级 CCR 任务可能继续追踪旧 table id。
- 任务可能仍处于 running,但不再同步用户期望的正式表对象。
- 日志中不一定能直接看出是 replace 后 table id 漂移导致。
- 可能需要手动 full sync 或重建任务恢复。
推荐方案
更合理的修复应从 Doris binlog 语义上处理。
对于 REPLACE_TABLE 且 swap=true 的场景,建议 Doris 生成 binlog 时同时关联两张受影响表:
tableIds = [origTblId, newTblId]
潜在修改点:
fe/fe-core/src/main/java/org/apache/doris/binlog/BinlogManager.java
addReplaceTable(...)
逻辑示例:
List<Long> tableIds = Lists.newArrayList();
tableIds.add(info.getOrigTblId());
if (info.isSwapTable()) {
tableIds.add(info.getNewTblId());
}
这样无论 CCR 表任务监听 SQL 左侧表还是右侧表,都能收到 replace 事件。
ccr-syncer 配套优化
Doris 修复后,ccr-syncer 的表级 replace 处理也可以进一步按 swap=true 的真实映射更新 Src.TableId:
如果 j.Src.Table == origTblName:
replace 后 table id = newTblId
如果 j.Src.Table == newTblName:
replace 后 table id = origTblId
此外,为了兼容旧版本 Doris,ccr-syncer 可以增加表级任务兜底检查:如果当前源表名对应的 table id 与 j.Src.TableId 不一致,则记录 warning 并触发 full sync。
我们在生产环境中遇到了一个
REPLACE TABLE导致表级 CCR 同步异常的问题。经过初步分析,问题可能与 Doris 侧REPLACE_TABLEbinlog 只关联部分 table id 有关。想请帮忙看一下这个分析是否合理,以及是否可以考虑在 Doris 侧调整相关 binlog 生成逻辑。问题背景
表级 CCR 任务会记录源端同步表的 table id,并通过 Doris FE
GetBinlog(tableId=...)拉取该表 binlog。对于
REPLACE TABLE ... PROPERTIES('swap'='true'),Doris 的语义是两张表交换名字。但当前 Doris 生成REPLACE_TABLEbinlog 时,tableIds只关联 SQL 左侧的origTblId。如果 CCR 表任务监听的是 SQL 右侧表的 table id,就可能收不到这条 replace binlog。示例
CCR 表任务同步:
执行前:
上游执行:
执行后:
Doris 生成的
REPLACE_TABLEbinlog 数据大致为:但该 binlog 当前只挂在:
CCR 表任务仍在拉:
因此它可能收不到这条
REPLACE_TABLEbinlog,无法感知正式表名背后的 table id 已经从F变成T。影响
推荐方案
更合理的修复应从 Doris binlog 语义上处理。
对于
REPLACE_TABLE且swap=true的场景,建议 Doris 生成 binlog 时同时关联两张受影响表:潜在修改点:
逻辑示例:
这样无论 CCR 表任务监听 SQL 左侧表还是右侧表,都能收到 replace 事件。
ccr-syncer 配套优化
Doris 修复后,ccr-syncer 的表级 replace 处理也可以进一步按
swap=true的真实映射更新Src.TableId:此外,为了兼容旧版本 Doris,ccr-syncer 可以增加表级任务兜底检查:如果当前源表名对应的 table id 与
j.Src.TableId不一致,则记录 warning 并触发 full sync。