Skip to content

表级 CCR 任务在 REPLACE TABLE swap=true 场景下可能错过表 id 切换事件 #677

Description

@Ryan19929

我们在生产环境中遇到了一个 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

执行前:

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 当前只挂在:

tableIds = [T]

CCR 表任务仍在拉:

GetBinlog(tableId = F, prevCommitSeq = ...)

因此它可能收不到这条 REPLACE_TABLE binlog,无法感知正式表名背后的 table id 已经从 F 变成 T

影响

  • 表级 CCR 任务可能继续追踪旧 table id。
  • 任务可能仍处于 running,但不再同步用户期望的正式表对象。
  • 日志中不一定能直接看出是 replace 后 table id 漂移导致。
  • 可能需要手动 full sync 或重建任务恢复。

推荐方案

更合理的修复应从 Doris binlog 语义上处理。

对于 REPLACE_TABLEswap=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。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions