问题现象
将大小写敏感的表数据导出后,使用 lightning local/physical 模式导入大小写不敏感的表中,若原表中存在大小写不敏感的重复数据时会有 checksum-failed 报错,并且导入表的索引信息和数据信息将产生不一致现象。
问题复现
启动 v5.4.3 集群,new_collations_enabled_on_first_bootstrap 默认为 false
tiup playground v5.4.3 --tiflash 0
创建一张表,这里虽然尝试创建大小写不敏感的 utf8mb4_unicode_ci,实际上会忽略(若希望真正创建该排序规则的表,需要手动开启 new_collations_enabled_on_first_bootstrap)
USE test;
CREATE TABLE t (
name varchar(20) PRIMARY KEY /*T![clustered_index] NONCLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
在表定义中显示排序规则为 utf8mb4_unicode_ci
mysql> show create table t\G;
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
`name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`name`) /*T![clustered_index] NONCLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.00 sec)
ERROR:
No query specified
实际并不生效,主键中仍可以插入大小写不敏感的重复数据
mysql> insert into t values('a'),('A'),('b'), ('B'), ('c'), ('C');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+
| name |
+------+
| A |
| B |
| C |
| a |
| b |
| c |
+------+
6 rows in set (0.01 sec)
使用 dumpling 导出数据
tiup dumpling:v5.4.3 -h 127.0.0.1 -P 4000 -u root -p '' -o /tmp/test
重新启动 v6.1.3 集群,new_collations_enabled_on_first_bootstrap 默认为 true
tiup playground v6.1.3 --tiflash 0
使用 lightning local/physical 模式将数据导入新库
tiup tidb-lightning:v6.1.3 --config tidb-lightning.toml
此时会报 checksum mismatched
Error: [Lighting:Restore:ErrChecksumMismatch]checksum mismatched remote vs local => (checksum: 18055227285823155031 vs 16161729031548613720) (total_kvs: 9 vs 12) (total_bytes:318 vs 462)
tidb lightning encountered error: [Lighting:Restore:ErrChecksumMismatch]checksum mismatched remote vs local => (checksum: 18055227285823155031 vs 16161729031548613720) (total_kvs: 9 vs 12) (total_bytes:318 vs 462)
在新表中看到由于大小写不敏感的关系,新表中只会显示一半的数据
mysql> select name from t;
+------+
| name |
+------+
| a |
| b |
| c |
+------+
3 rows in set (0.00 sec)
使用默认查询会走主键索引,我们重新使用全表查询来确认表中数据
mysql> select name from t use index();
+------+
| name |
+------+
| a |
| A |
| b |
| B |
| c |
| C |
+------+
6 rows in set (0.00 sec)
此时新表存在索引信息和数据信息不一致的现象
问题解决
问题的根本原因在于原表和新表的排序规则不同,而原表中存在表定义上会在新表重复的数据,在 lightning local/physical 导入时会绕过表定义的逻辑检查,直接生成新表数据,因此造成了新表中违反主键或唯一索引的重复数据。
方法一
参考官网文档,在上游或 dumpling 导出文件中去除问题数据,重新导入
方法二
在新表中查出索引信息匹配的数据信息,以及不在索引信息中的数据信息,由业务侧决定保留和删除哪部分数据,数据处理完毕后,删除当前主键或唯一索引,然后重新生成索引来创建和数据信息的关联信息。