CFG file is missing and source table is found to have row versions报错原因分析

发布时间 2023-08-30 19:24:13作者: 柴米油盐酱醋

参考:
https://docs.percona.com/percona-xtrabackup/8.0/error-message-instant.html
https://dev.mysql.com/doc/refman/8.0/en/innodb-table-import.html
https://jira.mariadb.org/browse/MDEV-20974


环境:mysql 8.0.32
操作:alter table xxx import tablespace
报错:
ERROR 1808 (HY000): Schema mismatch (CFG file is missing and source table is found to have row versions. CFG file is must to IMPORT tables with row versions.)
操作步骤:
先说下正常表迁移流程应该如何操作。
1、在源端执行 flush table xxxx for export 生成 cfg 文件,再执行 unlock tables 解锁。
2、到目标端创建表,并执行 alter table xxx discard tablespace。
3、将源端的 ibd 、cfg 文件同时拷贝到目标端数据目录。
4、修改文件权限。
5、目标端执行 alter table xxx import tablespace

我的操作流程偷懒了,
1、在目标端创建表,并执行 alter table xxx discard tablespace。
2、从源端拷贝单个 ibd 文件到目标端数据目录。
3、修改文件权限,目标端执行 alter table xxx import tablespace。
然后就出现最开始的报错。

分析:
这个 cfg 文件并不是必须的,在 5.7 环境中以偷懒的方式操作过,没有问题,但在 8.0.32 版本中不行了。
提示源端表有 row 版本,开始以为是表 row_format 哪里的不一样,经过确认,都是一样的没有问题。
从 percona 网站上得到了些新思路,就是这个表经历过 DDL( instant )


复现报错:


源端实例操作:


mysql> create table t1(id int ,name varchar(200));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1 select 1,'a';
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t1 select 1,'a';
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into t1 select 1,'a';
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
Empty set (0.00 sec)

mysql> alter table t1 add age int;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> update t1 set age=10;
Query OK, 3 rows affected (0.01 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
+--------+
| NAME   |
+--------+
| czg/t1 |
+--------+
1 row in set (0.01 sec)

目标端实例操作:
mysql>  CREATE TABLE `t1` (
    ->   `id` int DEFAULT NULL,
    ->   `name` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
    ->   `age` int DEFAULT NULL
    -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
    -> ;
Query OK, 0 rows affected (0.02 sec)

mysql> alter table t1 discard tablespace;
Query OK, 0 rows affected (0.01 sec)

--- 拷贝物理文件 t1.ibd 到数据目录

mysql> alter table t1 import tablespace;
ERROR 1808 (HY000): Schema mismatch (CFG file is missing and source table is found to have row versions. CFG file is must to IMPORT tables with row versions.)
mysql> 
mysql> 

解决问题。
因为源端表经历过DDL(INSTANT),表内有带 version 的行。将其转为常规表即可。

源端操作
mysql> alter table t1 engine=innodb;
Query OK, 0 rows affected (0.05 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE TOTAL_ROW_VERSIONS > 0;
Empty set (0.00 sec)


-- 拷贝 t1.ibd 文件到目标端,覆盖旧的 t1.ibd 文件。
mysql> 
mysql> alter table t1 import tablespace;
Query OK, 0 rows affected, 1 warning (0.05 sec)

mysql> select * from t1;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | a    |   10 |
|    1 | a    |   10 |
|    1 | a    |   10 |
+------+------+------+
3 rows in set (0.01 sec)

mysql> 
mysql>