ticdc主备集群同步,经常出问题,是不是bug?

通过ticdc搭建tidb主备集群,同步运行2个月出现同步故障,版本8.5.5,是不是这个版本有bug,报错日志如下
cdc.log (67.0 KB)

已经出现2次了,第一次出现没定位到问题,重新搭建,运行1个多月又出问题了,这是第二次,请大佬们帮忙定位到问题

@王军 补充判断依据的完整版:


社区问题 topic/1057704 — TiCDC v8.5.5 主备集群同步反复故障

结论

不是 TiCDC 代码 bug。 是下游连接周期性被杀 + TiCDC 连接池缺少主动回收 + changefeed 被外部停止的复合运维问题。


判断依据

依据 1:重试远未耗尽,changefeed 被外部停止

源码 mysql.go:56 定义 DML sink 最大重试 8 次,退避区间 500ms → 60s 指数抖动。

客户 cdc.log(30 条,410 行):

指标 实际值 自然耗尽应达到
invalid connection WARN 11 次(5 个 worker 各自若干次) 8 × 5 = 40 次
时间跨度 22:05:54 ~ 22:09:00(3 分钟 ~6 分钟(8 次退避累计)
结束方式 22:09:00.263 统一时刻 context canceled 最后一次重试失败 → changefeed failed
worker 受影响 5 个(0, 2, 5, 6, 10)

关键铁证:22:09:00.263 这同一毫秒内,5 个 worker 同时收到 context canceled,同时出现 Sink manager exists [error="context canceled"]。源码 txn_dml_sink.go:133-138 过滤 context.Canceled 不上报 errCh,changefeed 不会自动进入 failed 状态。只有外部信号(用户 pause、CDC server 重启、SIGTERM)才能在同一毫秒取消所有 worker 的 context。

依据 2:下游连接被杀的根因链

日志时间线反推:

[~22:03:54] 下游 TiDB 连接首次失效(22:05:54 首次 WARN - duration 2m0.001s 反推)
     ↓
[22:05:54 ~ 22:07:55] 5 个 worker 各自重试,11 次 WARN "invalid connection"
     ↓ 每次 duration=2m0s~2m5s(与源码退避策略吻合)
[22:07:51 ~ 22:07:57] 5 次 "failed to rollback txn"(连接已断,rollback 也失败)
     ↓
[22:09:00.263] 外部 context canceled → 6 次 ERROR "can not retry" + 5 次 flush fail + 2 worker exit

所有 DML 操作均报 invalid connectionBEGINCOMMITSET SESSION tidb_cdc_write_source = 1REPLACEDELETE — 说明不是特定 SQL 导致,是连接本身已死。

依据 3:TiCDC 连接池缺少主动回收机制

源码 mysql.go:131-132

db.SetMaxIdleConns(cfg.WorkerCount + 1)
db.SetMaxOpenConns(cfg.WorkerCount + 1)
// 缺少 db.SetConnMaxLifetime()
// 缺少 db.SetConnMaxIdleTime()

TiCDC 连接池不主动回收旧连接。当下游 MySQL wait_timeout 或中间 LB/NAT/Firewall 的 idle timeout 关闭连接后,TiCDC 不感知,下次复用该死连接 → driver.ErrBadConninvalid connection)。

运行 2 个月故障 2 次的周期性:如果 LB/NAT idle timeout 为 1~2 小时,低流量时段连接空闲被杀;CDC 复用死连接时刚好触发故障。这个模式与"间歇性、周期性"完全吻合。

依据 4:nightly build 版本风险

cdc.log 堆栈中 tiflow 版本:v0.0.0-20251226072601-0cb0aaf25061(2025-12-26 nightly),不是 v8.5.5 正式 release。nightly 可能包含未发布的变更或回归。

依据 5:历史工单验证(@wiki_ticket KB 反查)

历史工单中 invalid connection 的根因均为下游/网络层问题,无 TiCDC 代码 bug 先例。


对客回复建议

P0 排查(回复用户时先问)

  1. 22:09:00 前后是否手动 stop/pause 了 changefeed 或重启了 CDC server?
  2. 确认实际版本:tiup cluster display,nightly 切回正式 release
  3. 下游 TiDB:SHOW VARIABLES LIKE 'wait_timeout',确保 ≥ 28800
  4. 主备间网络设备:LB/NAT/Firewall 的 idle timeout 配置
  5. 下游是否设了 tidb_restricted_read_only

P1 预防措施

  1. sink-url 加 read-timeout=2h 延长超时(官方文档建议)
  2. 下游计划维护:先 tiup ctl cdc changefeed pause → 维护完成 → resume → 观察 checkpoint lag 归零
  3. gc-ttl 默认 24h:下游停机超 24h 会导致上游 GC → 链路失效需重做
  4. 停机超 3 天建议重做同步链路

P2 故障恢复

tiup ctl cdc changefeed resume --changefeed-id=default.ly-to-fs
# 观察 checkpoint lag 是否回落到 0
1 个赞

仅凭“运行两个月后故障”和版本号不能判定为 v8.5.5 的 bug。先在故障未重启时执行 cdc cli changefeed query --server=http://<cdc>:8300 --changefeed-id=<id>,记录 error、checkpoint-ts/resolved-ts,并截取 cdc.log 中第一次报错前后的日志;同时核对下游连通性、磁盘空间、PD/TiKV Region 状态与 GC safepoint。若能稳定复现,再对照 v8.5 最新补丁的 TiCDC 修复项并先在测试环境升级,不能只靠重启得出结论。

任务已经稳定运行了 2 个月,版本应该没问题

看日志像是网络波动导致的同步中断,8.5.5版本这块有过优化,但大概率不是bug。建议先检查下网络延迟和带宽,ping一下对端看看丢包率。另外可以试试调整TiCDC的worker数量,在cdc配置里加:

[sink]
worker-count = 16

同时调大内存限制:

[gc]
gc-ttl = "24h"

如果还出现,贴一下完整的cdc.log和tidb.log,帮你定位具体原因。