問題背景
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。