一、背景描述
MySQL版本:5.6.28, MySQL引擎 InnoDB。本地环境、开发环境、生产环境数据库版本一模一样。
昨天晚上更新一个项目至生产环境,在本地和开发环境测试的都很正常,但是到生产环境之后,其中一张表中的数据更新有异常。而这张表,不管是MySQL引擎、还是字符集、还是表结构,三个环境一模一样。这就是奇怪的地方。
二、报错内容
关键报错内容为:
Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
完整的报错信息如下:
2021-07-06 21:32:20.331 ERROR [http-nio-6184-exec-6][HvacModelEmbodimentServiceImpl.java:95] - E|HvacModelEmbodimentServiceImpl|updateEmbodimentById()|更新实施方案失败,【原因 =
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: UPDATE hvac_model_embodiment SET model_id = ?, principle_introduce = ?, line_reserved = ?, realize_function = ?, embodiment_attachment = ?, update_user = ?, update_time = ?, principle_introduce_image = ?, realize_function_image = ?, line_reserved_image = ? WHERE id = ?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.】
具体字段类型和长度如下图所示:
三、解决方案
按照报错信息提供的修改建议(Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help)
初步判断为部分字段类型和长度不满足需求,经过测试,只有principle_introduce、line_reserved、realize_function和embodiment_attachment四个字段有问题,然后修改了principle_introduce、line_reserved、realize_function和embodiment_attachment这四个字段,类型修改为text之后,这前三个字段可以正常保存成功,但是 embodiment_attachment 这个字段仍然保存失败,报错信息同上,一模一样。
于是又接着按照报错信息提供的修改建议(using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help),把行格式由Compact改为 DYNAMIC 之后 再次测试,保存成功。很完美的把问题解决了。具体修改内容如下图:
但是具体原因还没有查到。以后再深入研究。
四、拓展
根据报错信息,在网上搜索为什么会出现这样的情况,根据网上提供的一些资料,这个问题可能与不同引擎之间使用的存储格式有关。很多都说把InnoDB引擎改为MyISAM引擎即可。
而MyISAM有3种行存储格式:fixed/dynamic/compressed。InnoDb在MyIASM基础上新引入了Barracuda。至于不同引擎的默认设置,以及各种存储格式之间的区别,我也没有深入研究,以后有时间再去深入了解一下。
完结!