应将表的ROW_FORMAT改为DYNAMIC并确保InnoDB引擎,同时检查innodb_file_per_table、innodb_large_prefix及innodb_default_row_format配置,并在mysqldump中显式指定--row-format=dynamic或手动补全建表语句中的ROW_FORMAT=DYNAMIC。
MySQL 导入报错 ERROR 1118 (42000): Row size too large 怎么办
这是 innodb 表单行数据超长的硬限制错误,不是数据本身“太大”,而是字段定义(尤其 text/varchar)叠加后,innodb 计算出的“潜在最大行宽”超过 65535 字节。即使你只插几字节,只要表结构允许撑到超限,就会被拦在导入前。
- 真正触发点常是多个
VARCHAR(2000)或混用TEXT+JSON+ 大字段,默认ROW_FORMAT=COMPACT时容易中招 - 别急着删字段或改类型——先看
SHOW CREATE TABLE输出里有没有隐式ROW_FORMAT=DYNAMIC被覆盖 - 导入选项如
mysql --max-allowed-packet=512M对这个错误完全无效,它管的是网络包,不是行存储限制
怎么改表引擎和 ROW_FORMAT 才生效
ALTER TABLE 必须显式指定 ROW_FORMAT,且引擎得是 InnoDB;MyISAM 不支持该参数,强行加会静默忽略。
- 安全做法:
ALTER TABLE `t_name` ENGINE=InnoDB ROW_FORMAT=DYNAMIC; - 如果已有大量数据,加
ALGORITHM=INPLACE可避免锁表(但需 MySQL 5.6+ 且满足条件) - 注意:MySQL 5.7.7+ 默认
innodb_file_format=Barracuda,但旧库可能还是Antelope,后者不支持COMPRESSED和部分DYNAMIC特性,得先确认:SELECT @@innodb_file_format;
导入前要检查的三个配置项
光改表不够,mysqld 启动时的全局设置会影响新建表默认行为,也影响 mysqldump 导出时是否带 ROW_FORMAT 声明。
-
innodb_file_per_table=ON:必须开启,否则ROW_FORMAT修改对系统表空间无效 -
innodb_large_prefix=ON(MySQL 5.7.7+ 默认开):允许索引前缀超 767 字节,配合DYNAMIC才能存长字符串索引 -
innodb_default_row_format:MySQL 8.0.13+ 可设为DYNAMIC,让新表默认就用它,避免每次手工写
CSV 或 SQL 文件导入时的格式陷阱
用 LOAD DATA INFILE 或 source 执行 SQL 文件时,如果原始 dump 里没声明 ROW_FORMAT,哪怕目标库已调好配置,建表语句仍按老规则走。
- mysqldump 加
--row-format=dynamic(MySQL 8.0.21+)或手动在 dump 文件建表语句后补ROW_FORMAT=DYNAMIC - 如果用
LOAD DATA INFILE导 CSV,错误通常出在字段分隔符被内容里的换行/引号破坏,导致 MySQL 解析错行——这时报的也是 1118,但根源是格式混乱,得先用head -n 1120 file.csv | tail -n 3看真实第 1118 行附近内容 - 临时方案:把大字段改成
MEDIUMTEXT或拆成TEXT+TEXT,比硬调配置更快验证是不是真超限
真正卡住的往往不是改哪一行配置,而是没意识到 ROW_FORMAT 是表级属性,而 dump 文件、客户端连接、服务端默认值三者可能各用各的规则。










