dm 同步失败解决办法

张映 发表于 2021-01-08

分类目录: tidb

标签:, ,

通过dm,把mysql的数据同步到tidb中,到目前为止发生二次同步失败的情况

一,mysql修改表字段报错

"errors": [
{
"ErrCode": 44006,
"ErrClass": "schema-tracker",
"ErrScope": "internal",
"ErrLevel": "high",
"Message": "startLocation: [position: (mysql-bin.000022, 545530809), gtid-set: ], endLocation: [position: (mysql-bin.000022, 545530999), gtid-set: ]: cannot track DDL: ALTER TABLE `test`.`test` MODIFY COLUMN `advertiser_id` BIGINT(11) NOT NULL DEFAULT _UTF8MB4'0' COMMENT ''",
"RawCause": "[ddl:8200]Unsupported modify column: type bigint(11) not match origin varchar(36), and tidb_enable_change_column_type is false",
"Workaround": ""
}
],

解决办法:

1,把tidb中报错的表,只导出数据

2,把mysql中对应的表,导出结构

3,登录tidb数据库,把报错的表删除,导入mysql导出的表结构,然后在导入tidb导出的表数据

4,通过handle-error [task_name] skip跳过错误

  1. [tidb@jiankong task]$ tiup dmctl --master-addr 10.0.10.18:8261 handle-error mysql57-task skip  
  2. Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v2.0.1/dmctl/dmctl --master-addr 10.0.10.18:8261 handle-error mysql57-task skip  
  3. {  
  4.     "result": true,  
  5.     "msg""",  
  6.     "sources": [  
  7.         {  
  8.             "result": true,  
  9.             "msg""",  
  10.             "source""mysql57",  
  11.             "worker""dm-10.0.10.15-8262"  
  12.         }  
  13.     ]  
  14. }  

这种方式个人觉得是最快的恢复的方式了。也有其他的方式,不过不推荐使用。例如:新建task,然后重新同步。

二,tidb报主键冲突

1,通过匹配报错来找出错误

{
"ErrCode": 10006,
"ErrClass": "database",
"ErrScope": "not-set",
"ErrLevel": "high",
"Message": "startLocation: [position: (, 0), gtid-set: ], endLocation: [position: (mysql-bin.000026, 535844593), gtid-set: ]: execute statement failed: commit",
"RawCause": "Error 1062: Duplicate entry '96000' for key 'PRIMARY'",
"Workaround": ""
},

从上面报错看,没有表名和数据名,startLocation为0,endLocation是有的,mysql的binlog文件也有,就好办了。

  1. # mysqlbinlog --base64-output=DECODE-ROWS --stop-position=535844593 -v -d test ./mysql-bin.000026 |grep -B 3 96000  

如果知道数据名就加上-d,不确定就拿掉

查找mysql binlog的日志

查找mysql binlog的日志

一般来说都在最后,因为发错就会中止同步。确定表了以后,对比tidb中的表数据和mysql表数据,如果数据不一样,就可以确定不同步了。

2,通过show binlog events,更方便

  1. //找到执行sql的position  
  2. # mysqlbinlog --base64-output=DECODE-ROWS --stop-position=535844593 -v ./mysql-bin.000026|grep Query  
  3.   
  4. 。。。。。。。。。。。。。。。。。。。。。。。。省略。。。。。。。。。。。。。。。。。。。。。。。。。。。。  
  5.   
  6. #210123 17:35:00 server id 1001020  end_log_pos 535652987 CRC32 0xc15382e9  Query   thread_id=156492    exec_time=0 error_code=0  
  7. #210123 18:00:00 server id 1001020  end_log_pos 535727785 CRC32 0x09652fdb  Query   thread_id=156603    exec_time=0 error_code=0  
  8.   
  9. //根据最后一个position来找sql,并确定表  
  10. mysql> show binlog events in 'mysql-bin.000026' from 535727785 limit 5;  

解决办法:

删除tidb表中的报错id。然后重新启动

  1. # tiup dmctl --master-addr 10.0.10.18:8261 start-task ./mysql57-task.yaml  

handle-error是不能解决问题的。

  1. [tidb@jiankong task]$ tiup dmctl --master-addr 10.0.10.18:8261 handle-error mysql57-task skip  
  2. Starting component `dmctl`: /home/tidb/.tiup/components/dmctl/v2.0.1/dmctl/dmctl --master-addr 10.0.10.18:8261 handle-error mysql57-task skip  
  3. {  
  4.     "result": true,  
  5.     "msg""",  
  6.     "sources": [  
  7.         {  
  8.             "result": false,  
  9.             "msg""only support to handle ddl error currently, see https://docs.pingcap.com/tidb-data-migration/stable/error-handling for other errors",  
  10.             "source""mysql57",  
  11.             "worker"""  
  12.         }  
  13.     ]  
  14. }  

handle-error [task_name] skip只支持跳过ddl的错误



转载请注明
作者:海底苍鹰
地址:http://blog.51yip.com/tidb/2476.html