errorVerbose="Error 1071: Specified key was too long; max key length is 767 bytes

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:V3.0.9
  • 【问题描述】:tidb执行SQL语句导致drainer意外退出。drainer下游为MySQL8.0.18,执行的SQL语句为:DROP TABLE IF EXISTS student; CREATE TABLE **student** ( student_id varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘学生编号’, student_code varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘学生编码’, student_name varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘学生名称’, student_type_id varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT ‘分类编号’, PRIMARY KEY (student_id) USING BTREE, UNIQUE INDEX ak_key_2(student_code, student_name) USING BTREE, INDEX idx_report_type_id(student_type_id) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = ‘学生定义’ ROW_FORMAT = Compact;

drainer日志:drainer.log (4.3 KB)

您好:

   1. 这里的报错,看起来是超过了下游mysql的key最大长度限制, 这个是打算新建的表吗?
   2. tidb集群版本是初始建立就是3.0.9还是,升级到3.0.9?

你好,目前我们 TiDB 对 “ROW_FORMAT” 属性只是语法支持,在 MySQL 中有这样的约束:“ Prefixes can be up to 767 bytes long for InnoDB tables that use the REDUNDANT or COMPACT row format”。但是 TiDB 目前没有做这个约束。 如果对业务没有影响的话,可以将此 create 语句中的 “ROW_FORMAT = Compact” 约束去掉。先人工在下游执行一下不带 “ROW_FORMAT = Compact” 的 create 语句,然后 drainer 配置一下跳过这个 create 语句。具体是在 drainer 配置文件一下 ignore-txn-commit-ts 值,里面填写的是 create table 语句在上游执行的 commit ts,这个值应该在 drainer log 里面能找到。如果遇到问题可以再提问。

1赞

初始建立就是3.0.9

如果我下游的MySQL版本改为5.6.是否还是会造成这样的问题

您好, 关于您的问题在官方文档中有具体回复: Prefix support and lengths of prefixes (where supported) are storage engine dependent. For example, a prefix can be up to 767 bytes long for InnoDB tables or 3072 bytes if the innodb_large_prefix option is enabled. For MyISAM tables, the prefix length limit is 1000 bytes.

官方文档及论坛:

https://dev.mysql.com/doc/refman/5.6/en/create-index.html

具体问题产生是因为:我在tidb中执行力一段tidb执行正确的SQL,而当drainer同步到下游MySQL8.0.18时,下游的MySQL执行失败了。drainer产生了错误 :errorVerbose=“Error 1071: Specified key was too long; max key length is 767 bytes

  1. 在8.0的时候,由于tidb不支持ROW_FORMAT = Compact,所以建议您安装zimuxia的回答操作
  2. 您咨询5.6, 在5.6的时候。 767/4=191,你的字段已经超过了,还是报错。 mysql在5.7把这个值从767增大到了3072.

我的这段SQL在tidb中是没有任何问题的。但是在drainer同步到下游的MySQL8中出现的错误。导致了drainer意外退出。经过测试。我把这段出错的SQL放到MySQL8中运行将ROW_FORMAT = Compact改为ROW_FORMAT = Dynamic。MySQL8可以运行。是否TiDB的ROW_FORMAT与MySQL中不一致?

我这里的业务部署了两个drainer,一个下游为file、一个为MySQL8。如果我跳过出错的SQL commit ts。那下游为file的drainer该怎么操作?还是不进行任何操作。使用 Reparo进行增量恢复的时候。恢复一个4G的库。我这里感觉很耗时。

  1. 上面已经答复您了,tidb只是语法兼容,所以没有这方面的限制。
  2. 根据您的描述,是两个不同的drainer,那么下游跳过的是mysql8的commit,不影响file,4G恢复应该很快的. https://pingcap.com/docs-cn/stable/reference/tidb-binlog/faq/

4G的库,使用Reparo开了16个线程,耗时一个半小时多

这里可以观察下资源使用情况,如果资源充足,重试调大线程数。 另外备份恢复,BR工具很快会在新版本上线,到时备份和恢复速度会大幅提升,感谢。

后续的BR工具是否支持3.0.9的版本。又或者是否支持从下游为file的drainer备份

您好: BR会在3.1版本支持, 原理和binlog不相同,所以互相不支持。

BR的备份是增量的还是全量?

BR是全量备份,也支持单表备份

有没啥增量备份,并且还原速度很快的?

目前增量备份工具是 TiDB-binlog 的 file type 模式,通过 Reparo 工具解析 SQL 然后写入到 TiDB 里面。这个已经是可以满足增量备份和快速还原的需求。

当然也可以考虑 Recover Table ,通过设置 gc_life_time 来增加删除的历史数据保留时间。如果是 drop table ,可以通过 Recover Table 恢复,风险:需要预留更多空间来存储未过期的数据。

目前我使用的增量备份为TiDB-binlog 的 file type 模式,然后通过Reparo工具开启32个线程还原一个4G的数据库,耗时117分钟。请问这方面可以有什么优化吗?