Issue
GitHub Issue : #56408
➜ ~ cat /path/to/a.csv
1|aa|beijing
1|aa|beijing
1|aa|beijing
1|aa|beijing
2|bb|shanghai
2|bb|shanghai
2|bb|shanghai
3|cc|guangzhou
在使用load data … replace into … 语法导入数据时,当导入的数据与表中主键发生冲突时,正常情况会替换表中数据。但是在非聚簇主键的表中,执行 load data … replace into … 导入存在重复行的数据时,就会触发该 BUG,不会替换原有数据,而是会违反主键唯一性插入重复的数据,校验数据索引一致性的命令也会报错。
mysql> create table a(id int, name varchar(20), addr varchar(100), primary key (id) nonclustered);
Query OK, 0 rows affected (0.02 sec)
mysql> load data local infile ‘/path/to/a.csv’ replace into table a fields terminated by ‘|’ escaped by ‘’ lines terminated by ‘\n’;
Query OK, 13 rows affected (0.01 sec)
Records: 8 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from a;
+----±-----±----------+
| id | name | addr |
+----±-----±----------+
| 1 | aa | beijing |
| 1 | aa | beijing |
| 1 | aa | beijing |
| 1 | aa | beijing |
| 2 | bb | shanghai |
| 2 | bb | shanghai |
| 2 | bb | shanghai |
| 3 | cc | guangzhou |
+----±-----±----------+
8 rows in set (0.00 sec)
mysql> admin check table a;
ERROR 8223 (HY000): data inconsistency in table: a, index: PRIMARY, handle: 3, index-values:“” != record-values:“handle: 3, values: [KindInt64 1]”
Root Cause
load data … replace into …导入处理重复的 key 的时候逻辑不完整,tidb/executor/insert_common.go at 90c735f56125ed8eebefdee406fa18268f0b5a6c · pingcap/tidb · GitHub removeRow 返回的布尔标记在handleDuplicateKey 中没有被正确处理,导致重复的行仍然插入到了表中。
Diagnostic Steps
如果导入的数据本身存在重复行,或者与表中已存在的数据有重复,都会触发这个 Bug。此时执行 load data … replace into … 不会报错,但在完成后使用 admin check table a; 命令进行一致性检查就会出现下列数据索引不一致的错误信息:
mysql> admin check table a;
ERROR 8223 (HY000): data inconsistency in table: a, index: PRIMARY, handle: 3, index-values:“” != record-values:“handle: 3, values: [KindInt64 1]”
也可以参考 Issue 描述 中的示例。
Resolution
升级到已修复此问题的版本。
Workaround
-
使用聚簇主键可以避免该问题。
-
对于非聚簇主键表,在导入数据前确保文件和表中没有重复行,
-
如果数据已导入且存在重复,可通过如下操作解决:
1. 删除主键
2. 删除重复行
3. 重新创建主键
Affected Version
- v6.5.6 ~ v6.5.11
- v7.1.0 ~ v7.1.5
- v7.5.0 ~ v7.5.3
- v8.1.0 ~ v8.1.1
Fixed Version
- v6.5.12
- v7.1.6
- v7.5.4
- v8.1.2