我有一个包含大量longtext字段(18)的表,以及许多其他各种integer和varchar字段。最近添加了一些额外的longtext字段,这突然迫使我了解所有关于8k行大小限制的信息。数据库运行的是MySQL5.6.34,当前讨论的表是antelope/row\u format=compact。
我的理解是,在这种格式中,每列每行最多占用768字节,直到溢出到单独的存储中。当太多不同的longtext获得大量数据时,这就导致了这个错误:
行大小太大(>8126)。将某些列更改为文本或blob或使用row\u format=dynamic或row\u format=compressed可能会有所帮助。在当前行格式中,768字节的blob前缀是内联存储的。忽略表中其余的字段,所有18个longtext都是768字节,那么主索引将为所有字段存储13824字节。
我尝试将表更新为row\u format=dynamic,希望这样可以将长文本的溢出阈值从768字节降低到20字节,从而将所有长文本字段的最大主索引存储需求降低到18*20=360字节。我尝试了以下更新:
ALTER TABLE mytable ROW_FORMAT=DYNAMIC;
OPTIMIZE TABLE mytable;
无错误和以下输出:
mydb.mytable optimize注解表不支持优化,改为重新创建+分析mydb.mytable optimize status ok
如果我查看表的create table语法,我可以看到设置了row\u format=dynamic。
然后我尝试写一行来填充所有长文本列,每个列大约5.7kb,但是在我阻止保存行之前,我只能填充其中的10个,10*768=7680字节,当考虑其他非长文本必填字段时,这已经接近8kb的限制了,建议row\u format=dynamic指令不应用于现有行。
我并不特别希望必须通过转储/导入来重新创建数据库,但是因为它特别大,并且将代表一个延长的服务停机时间,在其他选项用尽之前,我不确定我是否可以证明这一点。
3条答案
按热度按时间zzwlnbp81#
(这个答案虽然侧重于索引,但很可能解决了表的问题。)
http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes
处理767极限有5种选择。这个似乎就是你需要的
(升级到5.7.7或更高版本是另一种解决方案——但这只会将上述内容设置为默认值;你仍然需要做
ALTER
,我想。)xiozqbni2#
结果发现我需要设置
innodb_file_format=barracuda
在更改/优化之前。出于某种原因,我认为设置dynamic也会隐式地设置barracuda,但这已经不再是事实:pb3skfrl3#
这是mysql的文档。要创建使用压缩或动态barracuda文件格式的表,需要启用。
https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_file_format