ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes


問題背景

zabbix監控導入schema.sql文件時報錯,經查看找到如下對應的語句。

MySQL數據庫版本:8.0.24

 

創建語句

create database zabbix;

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`type`          integer         DEFAULT '0'     NOT NULL,
	`snmp_oid`      varchar(512)    DEFAULT ''      NOT NULL,
	`hostid`        bigint unsigned                 NOT NULL,
	`name`          varchar(255)    DEFAULT ''      NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB;

CREATE INDEX `index_items_key` ON `items` (`hostid`,`key_info`(1021));

 

報錯信息:指定的key長度超過了3072bytes。

(root@localhost) [zabbix]> CREATE INDEX `index_items_key` ON `items` (`hostid`,`key_info`(1021));
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

解決步驟

查看數據庫默認字符集是utf8mb4

(root@localhost) [zabbix]> select @@global.character_set_server;
+-------------------------------+
| @@global.character_set_server |
+-------------------------------+
| utf8mb4                       |
+-------------------------------+

 

utf8mb4字符集一個字符占4個字節

(root@localhost) [zabbix]> select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME='utf8mb4';
+--------------------+----------------------+---------------+--------+
| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION   | MAXLEN |
+--------------------+----------------------+---------------+--------+
| utf8mb4            | utf8mb4_0900_ai_ci   | UTF-8 Unicode |      4 |
+--------------------+----------------------+---------------+--------+

 

表的行格式(ROW_FORMAT)絕對索引長度:

  • ROW_FORMAT= COMPACT 或 REDUNDANT,單列索引支持的最大長達為767bytes。
  • ROW_FORMAT= COMPRESSED 或 DYNAMIC,單列索引支持的最大長度為3072bytes。

 

索引長度計算:

  • 索引字段如果沒有設置NOT NULL,則需要添加一個字節。
  • 定長字段,如INT占4個字節、DATE占3個字節、CHAR(N)占N個字符。(注意字符與字節的區別,字符的長度取決於當前的字符集)
  • 變長字段,如VARCHAR(N)占用N個字符+2個字節。

 

        MySQL 8.X版本單個索引列支持最大長度是3072bytes。如果創建的索引列是變長字段VARCHAR,所以支持的最大長度是(3072-1-2)/4≈767。然后需要創建的索引index_items_key指定的索引長度是1021,我又不能更改索引的長度,所以將zabbix數據庫的字符集設置成utf8(也可以單獨指定表的字符集,但是需要保證相同業務類型表的字符集都一樣,否則會導致索引失效),然后重新導入SQL。

 

Utf8一個字符占3個字節,單個索引最大長度是(3072-1-2)/3=1023

(root@localhost) [zabbix]> select * from information_schema.CHARACTER_SETS where CHARACTER_SET_NAME='utf8';
+--------------------+----------------------+---------------+--------+
| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION   | MAXLEN |
+--------------------+----------------------+---------------+--------+
| utf8               | utf8_general_ci      | UTF-8 Unicode |      3 |
+--------------------+----------------------+---------------+--------+

 

創建語句

create database zabbix character utf8;

CREATE TABLE `items` (
	`itemid`        bigint unsigned                 NOT NULL,
	`type`          integer         DEFAULT '0'     NOT NULL,
	`snmp_oid`      varchar(512)    DEFAULT ''      NOT NULL,
	`hostid`        bigint unsigned                 NOT NULL,
	`name`          varchar(255)    DEFAULT ''      NOT NULL,
	`key_info`      varchar(2048)   DEFAULT ''      NOT NULL,
	PRIMARY KEY (itemid)
) ENGINE=InnoDB;

CREATE INDEX `index_items_key` ON `items` (`hostid`,`key_info`(1021));

 

索引創建成功

(root@localhost) [zabbix]> CREATE INDEX `index_items_key` ON `items` (`hostid`,`key_info`(1021));
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

PS:

    MySQL 8.X版本單列索引支持的最大長度默認就是3072bytes。

    MySQL 5.7版本單列索引支持的最大長度默認是768bytes,如需單列索引最大長度支持3072bytes,需配置參數innodb_large_prefix=ON。

 

參考:InnoDB Limits


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM