运维手册——Mysql索引字段长度太长报错
声明:这是我在大学毕业后进入第二家互联网公司学习的内容
背景
Mysql执行Create Table语句时报错
Specified key was too long; max key length is 1536 bytes
问题分析
之前遇到过报错信息“ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes”,其实意思就是“索引字段长度太长,超过了767bytes”。
mysql的varchar主键只支持不超过767个字节或者768/2=384个双字节 或者767/3=255个三字节的字段 而GBK是双字节的,UTF8是三字节的。
可是这次居然超过了这个长度1536,仔细发现1536/2=768 为什么是768?
然后我仔细看了下DDL语句
CREATE TABLE `QRTZ_BLOB_TRIGGERS` (`SCHED_NAME` varchar(120) COLLATE utf8mb4_unicode_ci NOT NULL,`TRIGGER_NAME` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,`TRIGGER_GROUP` varchar(190) COLLATE utf8mb4_unicode_ci NOT NULL,`BLOB_DATA` mediumblob,PRIMARY KEY (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) USING BTREE,KEY `SCHED_NAME` (`SCHED_NAME`,`TRIGGER_NAME`,`TRIGGER_GROUP`) USING BTREE,CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`) REFERENCES `QRTZ_TRIGGERS` (`SCHED_NAME`, `TRIGGER_NAME`, `TRIGGER_GROUP`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
我的天,这个联合索引居然长度一共是500个字符,为什么会这么表结构呢?感觉不伦不类,开发同事回复说是引用第三方表的DDL,好吧,为了保持这个表结构,我只能从数据库底层优化查起。
因为 InnoDB 表引擎的限制:
默认情况下,索引前缀长度限制为 767 字节,当开启了 innodb_large_prefix 选项时,索引前缀长度扩展到 3072 字节。
查询资料发现直接下面语句即可更改
set global innodb_large_prefix=1;
set global innodb_file_format=BARRACUDA;
补充一个额外知识
如果表的字符集是 utf8mb4 时,一个字符将占用 4 个字节。这意味着这个表的索引需要占500*4=2000个字节 超过了1536,然后我们再来看看1536是怎么来的。
由于之前优化过my.cnf,其中有这么一个参数innodb_page_size
我设置的是8kb
innodb_page_size 选项默认是 16KB 的时候,最长索引前缀长度是 3072 字节,如果是 8KB 的时候,最长索引前缀长度是 1536 字节,4KB 的时候,是 768 字节。
解决问题
- 修改DDL语句
解决根本原因,即使用的是第三方提供的,明明有问题为啥不尝试改改呢?
更改innodb_large_prefix,不需要重启数据库
更改innodb_page_size,需要重启数据库
其中第三种方法又引出了另一个问题,重启Mysql报错
Data file './ibdata1' uses page size 8192, but the innodb_page_size start-up parameter is 16384
查找网上资料发现原因
当innodb已经运行时,innodb_page_size为只读,因为必须在启动InnoDB之前设置该参数,并创建一个新的表空间系统。当InnoDB在数据目录中找不到ibdata1时,会发生这种情况。
解决办法:
备份原数据库,重建数据库,在启动命令的etc/my.cnf里添加innodb_page_size的值,启动,导入原数据库。(其实这种方法很蠢,但是当前数据库是测试环境的,所以这样操作没啥问题,要是生产出现这个问题,只能GG)
参考资料
错误#88746 简化InnoDB页面大小的配置
版权声明:
原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。
运维手册——Mysql索引字段长度太长报错相关推荐
- MySQL数据库字段类型 text 超长报错问题解决方案
把 字段类型 改为 longtext 即可,因为: 1.text字段类型:text字段类型的字节限制为65535字节. 2.longtext字段类型:longtext字段类型的字节限制为2147483 ...
- Laravel 5.4: 特殊字段太长报错 420000 字段太长
laravel 5.4 改变了默认的数据库字符集,现在utf8mb4包括存储emojis支持.如果你运行MySQL v5.7.7或者更高版本,则不需要做任何事情. 当你试着在一些MariaDB或者一些 ...
- MySQL运维(二)MySQL分库分表概念及实战、读取分离详解
MySQL运维(二)MySQL分库分表详解.读取分离详解 1.MySQL分库分表相关概念 1.1 分库分表概念 1.1.1 分库的原因 分库:就是一个数据库分成多个数据库,部署到不同机器. 如果业务量 ...
- 查询mysql数量_Linux 运维基础 Mysql性能优化
1, 查看MySQL服务器配置信息 mysql> show variables; 2, 查看MySQL服务器运行的各种状态值 mysql> show global status; 3, 慢 ...
- Oracle运维手册
Oracle运维手册 20070718李玲斌 [修订稿] 版本:V1.00S.200718 恒生电子证券事业部 二○○七年七月 本文所述内容(包括文字和图片),恒生电子股份有限公司(以下简称" ...
- 【Ceph】Ceph错误记录 Ceph 运维手册
Ceph 运维手册 第一部分:常用操作 - 12. 日志和调试 - <Ceph 运维手册> - 书栈网 · BookStack 分布式存储ceph运维操作 (摘抄自:https://www ...
- 运维常用Mysql基本命令
运维常用Mysql基本命令 基本命令 #远程连接 mysql -h hostname -u root -p #创建数据库 create database [databasename]; #列出所有数据 ...
- Linux运维课程-Mysql之复制(2)
本视频为老段工作室Linux运维课-Mysql部分 MySQL复制第二讲(随堂视频). 本章详细讲解了master和slave之间复制的注意点,通过本实验能够让大家更容易理解什么是MySQL复制.同 ...
- CloudStack部署运维手册V2 --- 新鲜出炉
CloudStack部署手册V1版本: http://clovemfong.blog.51cto.com/blog/3297559/1198185 CloudStack部署运维手册V2 版本 1. C ...
最新文章
- IDEA 新特性:提前知道代码怎么走
- 推荐8个可以显著提高工作效率的办公神器
- 人机智能既不是人类智能,也不是人工智能
- ActiveX (.ocx)的写法,及在IE里调用
- AddressBookUI.Framwork应用之ABPersonViewController, ABUnknownPersonViewController,ABNewPersonViewContro
- Vue + Spring Boot 项目实战(二):使用 CLI 搭建 Vue.js 项目
- 【Drools三】打工人学习Drools高级语法
- 【4747】java语言程序设计(一)2011年10月考试复习资料_全国2011年10月自考Java语言程序设计(一)试题3...
- 如何使用 Laravel Facades ?
- 10条设计推荐系统的经验和教训
- 微信小程序 图片上传+php后台源码
- c语言程序设计景点售票系统,c语言售票系统.docx
- ExtJS 快速反入门指南
- Java初学笔记30-【MiniQQ聊天部分代码】
- 开发者新手指南:一文汇总 Web3 开发工具
- 开山斧 0.3.5版本
- python语音转文字库_有没有语音转文字的APP?
- java里人带狗散步,不想带狗狗出门散步,告诉你5个遛狗的好处,不仅仅只有狗狗受益...
- python操作Excel设置打印标题时碰到的一个小问题
- day05循环结构while循环嵌套控制条件语句方法(函数)