ticdc 同步tidb数据到tidb的时候报错[CDC:ErrReachMaxTry]reach maximum try: 8: [CDC:ErrMySQLTxnError]Error 1406: Data too long for column

【 TiDB 使用环境】生产环境
【 TiDB 版本】 5.2.2/7.5.3

源TiDB 5.2.2 ; 目标TiDB 7.5.3
已经使用 dumpling + lightning 完成了数据库的逻辑备份和导入恢复。
现在使用 tiup cdc:v5.2.2 创建同步任务进行增量数据同步到下游 7.5.3 集群

创建命令

tiup cdc:v5.2.2 cli changefeed create --pd=http://192.168.3.57:2379 --sink-uri="mysql://root:xxx@192.168.1.70:4001" --start-ts=xxxxxx --config=cdc.yml --changefeed-id=yyy

其中cdc.yml 内容如下

case-sensitive=false
[filter]
rules = ["xinyu.*", "social.*"]

[mounter]
worker-num = 16

然后CDC报错

"error": {
      "addr": "192.168.3.132:8300",
      "code": "CDC:ErrProcessorUnknown",
      "message": "[CDC:ErrReachMaxTry]reach maximum try: 8: [CDC:ErrMySQLTxnError]Error 1406: Data too long for column 'content' at row 1: Error 1406: Data too long for column 'content' at row 1"
    },

cdc的日志中错误信息如下

[2024/11/12 11:58:02.428 +08:00] [WARN] [mysql.go:931] ["execute DMLs with error, retry later"] [error="[CDC:ErrMySQLTxnError]Error 1406: Data too long for column 'content' at row 1: Error 1406: Data too long for column 'content' at row 1"] [errorVerbose="[CDC:ErrMySQLTxnError]Error 1406: Data too long for column 'content' at row 1: Error 1406: Data too long for column 'content' at row 1\ngithub.com/pingcap/errors.AddStack\n\tgithub.com/pingcap/errors@v0.11.5-0.20210425183316-da1aaba5fb63/errors.go:174\ngithub.com/pingcap/errors.(*Error).GenWithStackByCause\n\tgithub.com/pingcap/errors@v0.11.5-0.20210425183316-da1aaba5fb63/normalize.go:282\ngithub.com/pingcap/ticdc/pkg/errors.WrapError\n\tgithub.com/pingcap/ticdc/pkg/errors/helper.go:30\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSink).execDMLWithMaxRetries.func1.3\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:981\ngithub.com/pingcap/ticdc/cdc/sink.(*Statistics).RecordBatchExecution\n\tgithub.com/pingcap/ticdc/cdc/sink/statistics.go:112\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSink).execDMLWithMaxRetries.func1\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:968\ngithub.com/pingcap/ticdc/pkg/retry.run\n\tgithub.com/pingcap/ticdc/pkg/retry/retry_with_opt.go:54\ngithub.com/pingcap/ticdc/pkg/retry.Do\n\tgithub.com/pingcap/ticdc/pkg/retry/retry_with_opt.go:32\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSink).execDMLWithMaxRetries\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:960\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSink).execDMLs\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:1121\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSinkWorker).run.func3\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:816\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSinkWorker).run\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:854\ngithub.com/pingcap/ticdc/cdc/sink.(*mysqlSink).createSinkWorkers.func1\n\tgithub.com/pingcap/ticdc/cdc/sink/mysql.go:657\nruntime.goexit\n\truntime/asm_amd64.s:1371"]

问题1
从cdc的日志中怎么判断content报错是那个库的那个表呢?

问题2
确认源库和目标字符集一样,表字段的类型一模一样,为啥出现这个问题

问题3
手动把目标库中varchar的大小调整到 tidb要求的上线,remove任务之后,重新创建还是报错,问题出现在哪里呢?

ticdc 的版本是?

https://docs.pingcap.com/zh/tidb/stable/information-schema-columns#columns
查columns表。另外tidb或者ticdc的日志里面也有可能有报错的sql。

源端和目标端的字符集和字段一模一样,感觉应该不会出现data too long这样的报错,检查检查tidb和cdc的日志看看,应该有相关sql和表的信息的,不过不确定5.2的cdc到7.5会不会有问题

1 个赞

问题很清晰,现在是找不到出问题的表么?
可以按楼上大佬说的,先看看哪些表里有这个字段,然后再逐个排查。

SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
WHERE COLUMN_NAME = 'content'

之前遇到过一次应用里报错的情况,是在tidb.log里找到了对应的sql语句、表和字段。

1 个赞

嗯嗯,只想着在cdc服务日志里面去找了没有到,以为是varchar类型导致的,结构都修改了,还是不行,从server的日志中看到了具体的SQL, 没有想到是 text类型导致,

5.2.2 版本的

CHARACTER_MAXIMUM_LENGTH: 65535
  CHARACTER_OCTET_LENGTH: 262140

5.2.2 如果超过字符数是可以插入的,但是 7.5.3 就不行(上面两个参数值一样)

cdc 只有开启 debug 模式,才能看到是哪个 DML 执行报如上的错误

有没有可能和sql_mode 有关呢

:joy:破防了啊,这个字段还能不一样长。

确认和这个没有关系,就是text 默认的长度,新旧两个版本对同样的配置,行为不一样

啊,上面给出来的是两个性质的配置哈,一个是字符长度,一个是实际字节长度

命令行开启debug 不行,需要 cdc-server 开启debug才行,但是旧集群CDC还跑着很多其他任务,没有开启,

因为同步配置的是 TiDB server,从server日志中找到错误SQL啦

嗯嗯,从server日志中找到了错误SQL ,那会只关注cdc server日志了,没有想到 tidb server 日志,

已确认是两个版本处理超长文本的限制行为不一样导致的

1 个赞

:+1:666

运维经验+1

我的意思是cdc server 开启 debug, :joy:
补充下:

1.开启cdc debug

v6.5及以上

curl -X POST -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v2/log -d '{"log_level":"debug"}'

v6.1

curl -X POST -H "'Content-type':'application/json'" http://127.0.0.1:8300/api/v1/log -d '{"log_level":"debug"}'