Navicat 15报“Row size too large”错误主因是innodb_strict_mode=ON触发InnoDB硬限制,解决方法是关闭严格模式或改用ROW_FORMAT=DYNAMIC行格式。
为什么Row size too large错误总在Navicat 15里冒出来
不是navicat 15的问题,是它默认用严格模式执行sql——只要innodb_strict_mode=on,innodb就会卡死在两个硬限制上:65535(整行含开销上限)和8126(页内存储上限)。而navicat 15的导入流程不自动降级警告为提示,一碰到超限就直接报错中断。你手动在mysql命令行里跑同一段create table,可能只收到warning,照样建表成功。
innodb_strict_mode=OFF是最快见效的开关
这不是“绕过问题”,而是让InnoDB按实际能力工作:当行太大时,自动把TEXT/BLOB列前缀(默认768字节)存到页外,其余部分留在页内。操作只需两步:
- 进MySQL执行:
SET GLOBAL innodb_strict_mode = OFF;(临时生效,重启失效) - 或改配置文件
my.cnf或my.ini,在[mysqld]下加一行:innodb_strict_mode=0,然后重启MySQL服务 - 验证是否生效:
SHOW VARIABLES LIKE 'innodb_strict_mode';,返回OFF即成功
注意:如果MySQL是云数据库(如阿里云RDS、腾讯云CDB),innodb_strict_mode通常不可修改,得走其他路径。
改ROW_FORMAT=DYNAMIC比换引擎更稳妥
别急着把InnoDB换成MyISAM——后者不支持事务、崩溃恢复弱、且同样受65535行大小限制。真正起作用的是行格式。InnoDB的DYNAMIC格式允许长字段(TEXT/VARCHAR超过255字节)整列溢出到页外,只留20字节指针在页内。
建表时显式指定即可:
CREATE TABLE `logs` ( `id` BIGINT PRIMARY KEY, `content` TEXT, `meta` JSON ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARSET=utf8mb4;
已有表可在线修改:
ALTER TABLE `logs` ROW_FORMAT=DYNAMIC;
- 必须确保
innodb_file_format=Barracuda(MySQL 5.7+ 默认满足) - 必须开启
innodb_file_per_table=ON(现代MySQL默认开启) - 不依赖
innodb_large_prefix(MySQL 5.7.7+ 已废弃该参数)
合并字段或改类型?先看是不是真需要
“合并字段”听起来省空间,但容易埋坑:比如把first_name、last_name、title全塞进一个profile_info JSON,后续想查姓氏、建索引、做校验都变麻烦。不如直击根源:
- 检查报错语句里哪些
VARCHAR定义过大——例如VARCHAR(4000)却只存几十字符,缩到VARCHAR(500)更合理 - 把确实存长文本的列明确改成
TEXT或MEDIUMTEXT,InnoDB会自动按DYNAMIC规则处理溢出 - 避免堆砌20+个
VARCHAR(255)字段,哪怕单个不长,加起来也轻松破8KB页内限额
真正容易被忽略的是:同一个表里混用COMPACT和DYNAMIC行格式会导致ALTER TABLE隐式重建失败;只要动过ROW_FORMAT,后续所有ALTER操作最好都带上ROW_FORMAT=DYNAMIC显式声明。


















