案例背景
本文将分享使用DTP将Mysql数据库迁移至磐维数据库时遇到的一个主键冲突案例。
【环境描述】
硬件平台:Intel X86_64
操作系统及版本:BCLinux for Euler 21.10
产品及版本:dtp 2.0
作业配置:dtp全量迁移 源库mysql,目标库panwedb ,ddl+数据一起迁移,ascii0选项为空串
【问题描述】
DTP迁移数据时,选择DDL+数据迁移时,在创建索引环节报错,dtp报告中显示迁移表在创建联合主键时,主键冲突错误,但数据全部迁移成功。
dtp报告错误:在目标库执行失败: ERROR: could not create unique index "aiops_conf_asset_detail_v2_pk" Detail: Key (unit id, kpi id)=(, PM-00-04-920-01) is duplicated
1. 迁移表信息如下:
CREATE TABLE `aiops_conf_asset_detail_v2` (
`unit_id` varchar(256) NOT NULL,
`kpi_id` varchar(128) NOT NULL,
`ext_unit_id` varchar(256) NOT NULL,
`dbtime` datetime NOT NULL,
`rid` varchar(37) NOT NULL,
`re_ext_unit_id` varchar(256) DEFAULT NULL,
PRIMARY KEY (`unit_id`,`kpi_id`) USING BTREE,
KEY `ext_index` (`ext_unit_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
2. mysql查询总数
mysql> select count(*) from aiops_conf_asset_detail_v2;
+----------+
| count(*) |
+----------+
| 1386543 |
+----------+
3. 迁移后查询panweidb总数
zjj_test_iopas=# select count(*) from aiops_conf_asset_detail_v2;
count
---------
1386543
(1 row)
4. 重复数据查询sql
4.1 panweidb数据库查询结果
select * from aiops_conf_asset_detail_v2 where (unit_id,kpi_id) in ( select unit_id,kpi_id from (select unit_id,kpi_id, count(*) as count from aiops_conf_asset_detail_v2 group by unit_id,kpi_id having count(*) > 1)) order by kpi_id,dbtime;
unit_id | kpi_id | ext_unit_id | dbtime | rid | re_ext_unit_id
---------+-----------------+----------------------+---------------------+----------------------------------+----------------
// | PM-00-04-920-01 | 98f9217c6dba03fc3158 | 2022-07-25 04:45:27 | 7BC0EE636B3B83484FC3B9348863BD22 |
/ | PM-00-04-920-01 | b734f17c742a948c8263 | 2022-07-25 04:46:06 | 6B92BB2C65A19276DF9388E936CCD25C |
// | PM-00-04-920-01 | fe7ea17c743169bc6822 | 2022-07-25 04:56:02 | 509D1C1795EFDF95F63916B54A65205E |
/ | PM-00-04-920-01 | 8fbb317c49aabf801005 | 2022-08-20 11:56:10 | 6666CD76F96956469E7BE39D750CC7D9 |
// | PM-00-04-920-02 | 98f9217c6dba03fc3158 | 2022-07-25 04:45:27 | 7BC0EE636B3B83484FC3B9348863BD22 |
/ | PM-00-04-920-02 | a5ee317c742a477e2492 | 2022-07-25 04:46:06 | 6B92BB2C65A19276DF9388E936CCD25C |
// | PM-00-04-920-02 | 7f95517c7431f7bc5928 | 2022-07-25 04:56:01 | 509D1C1795EFDF95F63916B54A65205E |
/ | PM-00-04-920-02 | 8fbb317c49aabf801005 | 2022-08-20 11:56:10 | 6666CD76F96956469E7BE39D750CC7D9 |
// | PM-00-04-920-03 | 57ddc17e8d6f34ed9881 | 2022-01-25 03:07:52 | 7BC0EE636B3B83484FC3B9348863BD22 |
/ | PM-00-04-920-03 | 5375617e8d7296686374 | 2022-01-25 03:16:44 | 6B92BB2C65A19276DF9388E936CCD25C |
// | PM-00-04-920-03 | 5391c17e8d7ed1e66675 | 2022-01-25 03:27:47 | 509D1C1795EFDF95F63916B54A65205E |
/ | PM-00-04-920-03 | 4e64717f118d47247467 | 2022-02-19 18:53:35 | 6666CD76F96956469E7BE39D750CC7D9 |
// | PM-00-04-920-04 | 57ddc17e8d6f34ed9881 | 2022-01-25 03:07:52 | 7BC0EE636B3B83484FC3B9348863BD22 |
/ | PM-00-04-920-04 | 5375617e8d7296686374 | 2022-01-25 03:16:44 | 6B92BB2C65A19276DF9388E936CCD25C |
// | PM-00-04-920-04 | 5391c17e8d7ed1e66675 | 2022-01-25 03:27:47 | 509D1C1795EFDF95F63916B54A65205E |
/ | PM-00-04-920-04 | 4e64717f118d47247467 | 2022-02-19 18:53:35 | 6666CD76F96956469E7BE39D750CC7D9 |
4.2 mysql数据库查询结果为空
5. 部分重复数据查询
select unit_id,kpi_id,ext_unit_id from aiops_conf_asset_detail_v2 where unit_id='/';
5.1 panweidb数据库查询结果
unit_id | kpi_id | ext_unit_id
---------+-----------------+----------------------
/ | PM-00-04-920-01 | 8fbb317c49aabf801005
/ | PM-00-04-920-01 | b734f17c742a948c8263
/ | PM-00-04-920-02 | 8fbb317c49aabf801005
/ | PM-00-04-920-02 | a5ee317c742a477e2492
/ | PM-00-04-920-03 | 4e64717f118d47247467
/ | PM-00-04-920-03 | 5375617e8d7296686374
/ | PM-00-04-920-04 | 4e64717f118d47247467
/ | PM-00-04-920-04 | 5375617e8d7296686374
5.2 mysq查询结果
+---------+-----------------+----------------------+
| unit_id | kpi_id | ext_unit_id |
+---------+-----------------+----------------------+
| / | PM-00-04-920-01 | 8fbb317c49aabf801005 |
| / | PM-00-04-920-02 | 8fbb317c49aabf801005 |
| / | PM-00-04-920-03 | 4e64717f118d47247467 |
| / | PM-00-04-920-04 | 4e64717f118d47247467 |
+---------+-----------------+----------------------+
综上所述:可见迁移数据数量正确,但是panweidb unit_id='/' 有8条,mysql有4条,且panweidb查询结果中unit_id和kpi_id有重复数据,unit_id和kpi_id是联合主键
6. 在mysql和panweidb中查询重复数据数据长度和ascii码值
sql: select length(unit_id), ascii(unit_id),kpi_id,ext_unit_id from aiops_conf_asset_detail_v2 where ext_unit_id in ('8fbb317c49aabf801005','b734f17c742a948c8263')
mysql 查询结果:unit_id长度不同,分别是1和2。 ascii结果是0。
panweidb 查询结果:unit_id长度相同,是1。 ascii结果是0。
说明:推断unit_id列值存在不可见的空白符,迁移中的ascii0选项替换为空串,所以panweidb数据重复,但是mysql数据 不重复。
7. 测试环境重新复测:
复测用例1
CREATE TABLE `t3` (
`unit_id` varchar(256) NOT NULL,
`kpi_id` varchar(128) NOT NULL,
`ext_unit_id` varchar(256) NOT NULL,
PRIMARY KEY (`unit_id`,`kpi_id`) USING BTREE,
KEY `ext_index` (`ext_unit_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
插入第一条:insert into t3 values('/', 'PM-00-04-920-01'.'1');
插入第二条:insert into t3 values('/\0', 'PM-00-04-920-01'.'1');
panweidb第二条插入失败,主键冲突
mysql都插入成功
select * from t3 where unit_id='/';
mysql只能查出第一条。
说明:mysql支持\0的插入,并且主键索引识别可以区别是否包含\0 不会导致冲突。并且\0在查询结果中不可见,和所遇问题符合。panweidb不支持\0主键索引,无法区分无\0的数据
复测用例2
重新迁移,ascii选择空格,迁移成功。
select * from aiops_conf_asset_detail_v2 where unit_id='/';结果无重复数据
结论
mysql aiops_conf_asset_detail_v2表 unit_id字段包含\0,以前后因为ascii被替换为空串,所以panweidb数据重复,迁移时数据库出现主键索引冲突错误
8. 解决方案
DTP迁移时选择ASCII0处理




