DM同步报错, failed to create table for in schema tracker\" RawCause:\"[schema:8239]Unknown placement policy 'on_ssd'

设置placement policy后,DM同步报:ailed to create table for in schema tracker\" RawCause:\"[schema:8239]Unknown placement policy 'on_ssd'。而on_ssd这个策略在TiDB中是存在的,另外其他任务也没有出错,就这一个出错了(可能是跟这个任务有建表有关系?)。
请大佬们看下,看我应该如何才能修复这个错误?

请发相关日志和完整的报错信息

[2022/10/31 09:45:11.454 +08:00] [INFO] [syncer.go:1531] ["received ungraceful exit ctx, exit now"] [task=fund_task] [unit="binlog replication"]
[2022/10/31 09:45:11.454 +08:00] [INFO] [subtask.go:356] ["unit process returned"] [subtask=fund_task] [unit=Sync] [stage=Paused] [status="{\"totalEvents\":506,\"totalTps\":2,\"syncerBinlog\":\"(mysql-bin.001200, 635889583)\",\"syncerBinlogGtid\":\"1e787e9a-ea02-11eb-8239-00163e0eb750:1-136252793,1fd7fe20-ea02-11eb-9db6-00163e02d592:1-20195454,3e773ad8-46c1-11ec-992b-0242a9fe7b02:1-139,777234c5-87b7-11ea-9279-00163e1054e6:1-1486672619,784b7fc9-87b7-11ea-a0b7-00163e068fb5:1-1724587847,7e04612e-1c6a-11ed-ac0c-52540048a565:1\",\"binlogType\":\"local\"}"]
[2022/10/31 09:45:11.454 +08:00] [INFO] [local_reader.go:782] ["binlog reader closing"] [task=fund_task] [unit="binlog replication"] [component="binlog reader"]
[2022/10/31 09:45:11.454 +08:00] [WARN] [local_reader.go:288] ["parse relay finished"] [task=fund_task] [unit="binlog replication"] [component="binlog reader"] [error="parse relay log file mysql-bin.001200 from offset 4 in dir relay_log/dm-172.30.241.143-18262/7e04612e-1c6a-11ed-ac0c-52540048a565.000001: context canceled"]
[2022/10/31 09:45:11.454 +08:00] [INFO] [local_reader.go:788] ["binlog reader closed"] [task=fund_task] [unit="binlog replication"] [component="binlog reader"]
[2022/10/31 09:45:11.471 +08:00] [ERROR] [subtask.go:377] ["unit process error"] [subtask=fund_task] [unit=Sync] ["error information"="ErrCode:44003 ErrClass:\"schema-tracker\" ErrScope:\"downstream\" ErrLevel:\"high\" Message:\"startLocation: [position: (mysql-bin|000001.001200, 635890184), gtid-set: 1e787e9a-ea02-11eb-8239-00163e0eb750:1-136252793,1fd7fe20-ea02-11eb-9db6-00163e02d592:1-20195455,3e773ad8-46c1-11ec-992b-0242a9fe7b02:1-139,777234c5-87b7-11ea-9279-00163e1054e6:1-1486672621,784b7fc9-87b7-11ea-a0b7-00163e068fb5:1-1724587847,7e04612e-1c6a-11ed-ac0c-52540048a565:1], endLocation: [position: (mysql-bin|000001.001200, 635898306), gtid-set: 1e787e9a-ea02-11eb-8239-00163e0eb750:1-136252793,1fd7fe20-ea02-11eb-9db6-00163e02d592:1-20195455,3e773ad8-46c1-11ec-992b-0242a9fe7b02:1-139,777234c5-87b7-11ea-9279-00163e1054e6:1-1486672621,784b7fc9-87b7-11ea-a0b7-00163e068fb5:1-1724587847,7e04612e-1c6a-11ed-ac0c-52540048a565:1]: failed to create table for `db`.`table` in schema tracker\" RawCause:\"[schema:8239]Unknown placement policy 'on_ssd'\" "]
[2022/10/31 09:45:11.471 +08:00] [INFO] [subtask.go:379] [paused] [subtask=fund_task] [unit=Sync]

这个可以稳定复现,我把老的任务完全删除掉,把所有表都truncate掉,然后创建一个新服务从MySQL重新导入了一份,还是同样的问题。

» binlog-schema list -s fund-mysql fund_task db table
{
    "result": true,
    "msg": "",
    "sources": [
        {
            "result": true,
            "msg": "CREATE TABLE `table` ( `createtime` datetime DEFAULT CURRENT_TIMESTAMP, `updatetime` datetime DEFAULT CURRENT_TIMESTAMP, `fund_code` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '基金代码', `period` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '周期', `type_name` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '指标名称', `value` double DEFAULT NULL COMMENT '指标数值', `start_date` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '指标开始时间', `end_date` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '指标结束时间', PRIMARY KEY (`fund_code`,`period`,`type_name`) /*T![clustered_index] CLUSTERED */) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci /*T![placement] PLACEMENT POLICY=`on_ssd` */",
            "source": "fund-mysql",
            "worker": "dm-********-18262"
        }
    ]
}
»  

更新最新进展,找到binlog-schema这个命令了,看到update子命令支持从source获取表结构,遇到类似的错误,可以:

  1. 执行binlog-schema update -s fund-mysql fund_task db table --from-source来指定从MySQL获取表结构
  2. resume-task fund_task,任务可以进行下去(不过每遇到一个表,都得执行一下,也不太现实,只能是临时解决方案)

感谢反馈,我们会努力在下一个版本修复。您可以在 https://github.com/pingcap/tiflow/issues/7493 查看进度

if the table structure is not contained in checkpoints, DM will fetch it from downstream, but placement rule information is missing
大佬这句话能否在详细说说,是DM 里没有placement rules信息?

FYI,因为只要涉及到新表的创建,都会导致复制报错。这里补充一个生成修复语句的SHELL命令,可以放到crond里定时跑一下。

#! /bin/bash
PD_ADDR="127.0.0.1:8261"
cmds=$(tiup dmctl --master-addr ${PD_ADDR} query-status --more | jq -r '.sources[] | .sourceStatus.source as $src | .subTaskStatus[] | select(.stage == "Paused") | {name: .name, source: $src, info :.result.errors[].Message | capture("`(?<db>\\S+)`.`(?<table>\\S+)`")} | "binlog-schema update --from-source -s " + .source + " " + .name + " " + .info.db + " " + .info.table + "\nresume-task " + .name') 

echo "${cmds}" | while read cmd; do
    echo "------  $cmd ------"
    echo "$cmd" | tiup dmctl --master-addr  ${PD_ADDR}
    
done

没有复现出来,这边还需要您的 DM 版本以及更多的日志,比如可以第一次出现 Unknown placement policy 的前后几秒的日志

是TiDB 6.1.1版本中的DM。你那里下游同步的表有 placement policy也可以正常同步么?得清理任务缓存后,才能复现。

我测试的是 nightly,明天看一下老版本

DM 从下游加载 CREATE TABLE 语句作为同步表的表结构,这个 CREATE TABLE 引用了下游 TiDB 里面的 placement rule,但是 DM 不会从下游加载 placement rule(因为同步不使用这个)。可惜的是 DM 在自己内部组件执行 CREATE TABLE 时没处理好,报错了

如果,已经确定是DM没有处理号,建议改下官方文档的兼容性说明文档:
https://docs.pingcap.com/zh/tidb/v6.3/placement-rules-in-sql#工具兼容性

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。