CDC 新建任务 TSO 不推进
可以查看 cdc 同步监控中,TiKV unresolved region count 监控。当这个监控面板为 0 时,同步开始推进。
当前 cdc 的行为中,新建的同步任务和重启同步任务都会触发扫一遍 region。后续相关行为会优化。
CDC 同步延迟越来越大
发现有两个 CDC 同步任务延迟越来越大,无法追赶上同步进度。
初步排查: 查看 Checkpoint 没有推进,怀疑是遇到非预期情况导致任务卡住。
排查上游: 发现集群 GC 卡住 2 天以上,但同步任务没有报错。判断情况异常。因为默认 cdc 异常任务是卡 gc 24h
查看任务配置: 发现两个任务存在重叠的表。在这种情况下,当前 ticdc 的机制为:
- CDC 同步任务会触发主键冲突,但 CDC 自身有修复机制。当前逻辑是:重试 8 次 → 失败则重启 Sink → 进入安全模式(replace into) → 成功推进 Checkpoint → 关闭安全模式 → 继续同步(。因此,CDC 任务本身没有报错,但是进入了一个自我修复的一个循环中。
- GC 卡住原因: CDC 正常任务会向 PD 注册一个 Service Safepoint,保证 Safepoint 后的数据不会被 GC 回收。因此,没有报错的 CDC 任务,如果延迟越大,就会导致 GC 卡住的时间越长。
关键字:
查看 cdc 日志发现:
[xxxx] [WARN] [manager.go:270] ["Sink manager backend sink fails"] [namespace=default] [changefeed=2xxxx] [error="[CDC:ErrReachMaxTry]reach maximum try: 8, error: [CDC:ErrMySQLTxnError]MySQL txn error: Error 1062: Duplicate entry 'xxxx' for key 'xxx.PRIMARY': [CDC:ErrMySQLTxnError]MySQL txn error: Error 1062: Duplicate entry 'xxxx' for key 'xxxx.PRIMARY'"]
因此当前情况部分符合产品预期。需要调整 CDC 同步配置,去除重叠的表即可解决问题。
CDC 删除 changefeed 后,仍然报 ticdc_changefeed_failed
版本 v6.5.6.
这个有一个已知 BUG,https://github.com/pingcap/tiflow/issues/10449。
大体理解就是如果删除一个失败的 cdc 任务,大概率是删不干净的。虽然 cdc cli 查看是看不到相关任务了。
也就是失败的 cdc 任务,正常删除,query 查不到,但是告警还在。
处理方法就是:创建同名任务,不同步任何表,然后删除即可。
TiCDC 任务报错、checkpoint 不推进
版本为 6.5.5,做了 tidb 同步 tidb 操作。用 BR 做的备份还原。
看了 CDC 日志,发现关键报错(已经脱敏):
2024/06/27 17:36:24.826 +08:00] [ERROR] [mysql.go:772] ["execute DMLs with error, can not retry"] [error="[CDC:ErrMySQLTxnError]MySQL txn error: context deadline exceeded"] [errorVerbose="[CDC:ErrMySQLTxnError]MySQL txn error: context deadline exceeded\ngithub.com/pingcap/errors.AddStack\n\tgithub.com/pingcap/errors@v0.11.5-0.20220729040631-518f63d66278/errors.go:174\ngithub.com/pingcap/errors.(*Error).GenWithStackByArgs\n\tgithub.com/pingcap/errors@v0.11.5-0.20220729040631-518f63d66278/normalize.go:164\ngithub.com/pingcap/tiflow/pkg/errors.WrapError\n\tgithub.com/pingcap/tiflow/pkg/errors/helper.go:34\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql.(*mysqlBackend).multiStmtExecute\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql/mysql.go:636\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql.(*mysqlBackend).execDMLWithMaxRetries.func1.3\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql/mysql.go:708\ngithub.com/pingcap/tiflow/cdc/sinkv2/metrics.(*Statistics).RecordBatchExecution\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/metrics/statistics.go:74\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql.(*mysqlBackend).execDMLWithMaxRetries.func1\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql/mysql.go:696\ngithub.com/pingcap/tiflow/pkg/retry.run\n\tgithub.com/pingcap/tiflow/pkg/retry/retry_with_opt.go:57\ngithub.com/pingcap/tiflow/pkg/retry.Do\n\tgithub.com/pingcap/tiflow/pkg/retry/retry_with_opt.go:34\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql.(*mysqlBackend).execDMLWithMaxRetries\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql/mysql.go:685\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql.(*mysqlBackend).Flush\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/mysql/mysql.go:176\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn.(*worker).doFlush\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/worker.go:179\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn.(*worker).runLoop\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/worker.go:135\ngithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn.newSink.func1\n\tgithub.com/pingcap/tiflow/cdc/sinkv2/eventsink/txn/txn_sink.go:109\ngolang.org/x/sync/errgroup.(*Group).Go.func1\n\tgolang.org/x/sync@v0.1.0/errgroup/errgroup.go:75\nruntime.goexit\n\truntime/asm_amd64.s:1594"] [duration=2m5.005272856s] [query="DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` = ? AND `column3` = ? LIMIT 1;DELETE FROM `database_name`.`table_name` WHERE `column1` = ? AND `column2` ="] [count=359] [changefeed=default.feed_name]
可以看到,SQL 在下游执行了 2m5s。这个时候去看了下游相关 SQL 执行计划和表结构后发现:
- 不符合 cdc 同步最佳实践,未满足有效索引(当期调整了参数强行同步的):https://docs.pingcap.com/zh/tidb/stable/ticdc-overview#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5
- br 导入数据库,需要手动收集下所有表的统计信息(没有统计信息,SQL 走了全表扫)。当前 BR 备份还原带统计信息后续版本也会优化。
分区表写入热点导致 CDC 延迟
版本为 6.5.3.
实际上这个问题要分析两个地方:
- 热点问题是否会导致 cdc 延迟,什么会优先成为瓶颈。
- 分区表为何会带来热点问题。
关于 1.的结论是:写热点会导致 cdc 延迟。 CDC endpoint CPU 会更快的 100%,cdc endpoint 是指 TiKV 里服务 CDC 的 gRPC 接口,正常处理 gRPC 要么很快完成、要么丢给 cdc worker 跑,所以 cdc endpoint 是单线程的。
关于 2.分区表为何带来热点问题:默认参数下,一张表连续创建新分区 Region Leader 会集中在一个 TiKV ,tidb 中一个分区相当于一个表,他有独立的 table id(partition id),在新建的时候他会从同一个 region 分裂出来(split table 参数控制,默认会开)。也就是新建一个表就会 new 一个新 region。但是默认 scatter 是不开启的,因此新分裂的 region 会在一个 TiKV 上。处理方法:
- 可以尝试开启 tidb scatter region 配置, https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_scatter_region
- 手动 scatter:curl http://{TiDBIP}:10080/tables/{db}/{table}/scatter ,关闭:curl http://{TiDBIP}:10080/tables/{db}/{table}/stop-scatter
cdc no owner 告警误报
版本是 6.5.9
问题是告警误报:instance: cdc cluster has no owner for more than 10 minutes,
有做过:
- 检查 Prometheus 和 cdc 节点时钟,没有问题
- 尝试在 Prometheus 中调试公式,发现结果正确。但是观察判断上有问题,初步判断是 Prometheus bug
处理方法是:
Prometheus 单独升级:
https://docs.pingcap.com/zh/tidb/stable/upgrade-monitoring-services#%E5%8D%87%E7%BA%A7-prometheus
用 patch 的方式升级到了 Prometheus 最新版本。
并且升级前,扩容了一个 Prometheus,复现了告警,然后升级扩容的 Prometheus 后问题消失。
这个问题比较奇怪,很多 TiDB 用户一样告警公式是没有遇到相关问题的。不确定触发条件到底是什么。