TiDB3.0.9 转库导表,异常

【TiDB 版本】:

3.0.9

###【问题描述】
1 将数据库表导出结构到本地,test.sql
2 将test.sql 在导入回来发生如下异常

> 1071 - Specified key was too long; max key length is 3072 bytes
> 时间: 0.014s

SQL 语句

CREATE TABLE `inventory` (
  `id` varchar(200) NOT NULL COMMENT '',
  `product_name` varchar(200) NOT NULL COMMENT '',
  `customer_code` varchar(200) DEFAULT NULL COMMENT '',
  `product_standard` varchar(200) NOT NULL COMMENT '',
  `reserve_one` varchar(200) DEFAULT NULL COMMENT '',
  `product_complete` varchar(200) DEFAULT NULL COMMENT '',
  `file_id` decimal(50,2) NOT NULL COMMENT '',
  `inventory_state_complete` date NOT NULL COMMENT '',
  `inventory_state` varchar(200) NOT NULL COMMENT '',
  PRIMARY KEY (`id`),
  KEY `file_id` (`file_id`),
  KEY `product_edi` (`customer_code`,`product_name`,`product_standard`,`reserve_one`,`product_complete`),
  KEY `status_update` (`customer_code`,`inventory_state`,`inventory_state_complete`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='';

如图

麻烦确认一下导出到本地的 TiDB 数据是直接写进去的还是通过工具同步,两个 TiDB 版本都是 3.0.9 吗?

1 我使用一两种方式,一 使用 mydumper 导入,使用 loader 导入,会发生这 个异常

2 直接使用navicat 转出表结构,然后导入执行SQL也会失败

这个问题是因为 product_edi 包含的五个字段长度超出最大 3072 bytes。表的编码是 utf8mb4 则最大占用 4 乘(5* 200)= 4000 byte,超过最大限制会报错。处理方式:1)修改每个单独字段的长度 2)从业务角度考虑是否需要用这个五个字段作为索引字段

现在改已经来不及了啊,马上要部署到客户的 生产环境了, 为什么在 数据库中可以加索引,导入的时候不行?

有没有 什么稍 好一点的解决方案,不影响上线啊

不确定你说的数据库可以加是什么操作,本地测试是不可以的。

上面讲的两种方式可以考虑下

老师,如图,我就是先导出的这个库,然后在导入就出问题

稍等,我看下

3.0.9 的版本是否是从 3.0.8 版本升级上来的?在 3.0.8 版本之前有 bug,之后修复了。如果一定要用这个表结构,可以考虑在 3.0.7 去建表。

1 是从 3.0.8 版本升级上来的

2 在 3.0.7 去建表,在导出语句,在导入到3.0.9吗? 我去试一试看看结果怎么样,谢谢老师

考虑在 3.0.7 利用这个 bug 建表,然后升级到高版本。

那以后怎么办啊? 真的是太让人,苦恼。。。。。。。。。。:rage::rage::rage::rage::rage:

考虑下业务层能否调整一下这个 index

原因: v3.0.8 版本之前,检查 varchar 等字符串类型列的长度时,每个字符都按 1byte 计算,使 index 字符长度容忍的限度变大,与 MySQL 行为不一致。在 v3.0.8 版本修复了此问题, PR -13727 但是会出现与 TiDB v3.0.8 之前版本不兼容问题。

处理方案 我们已经处理了这个兼容性问题,相关 PR: PR-15012PR-15057。 这个功能可以通过升级 TiDB 到 v3.0.11 处理。

不过默认情况下还是与 MySQL 行为一致,即以下语句还是会报错。

tidb> create table t (a varchar(3072) primary key) charset utf8mb4;
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

可以通过将配置文件中 max-index-length 项的值改成 3072*4 来兼容。相关文档我们会尽快补充。

2 个赞

好的谢谢老师

1 个赞

:+1::+1:

应该的~