在項目使用中,出現瞭如下報錯:mysql
Error Code: 1118 - Row size too large (> 8126). 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.
上面報錯,這就涉及到了row size的上限,也有可能會涉及到file format的設置。sql
這裏主要講第三種報錯,插入數據的時候觸發的報錯。先要理清file format和row format兩個概念。
我的理解修改這兩個參數都有可能解決掉問題。爲啥是有可能,由於file format只是部分長字段類型的設置。測試
先解釋下file forma。這是用於varchat或者text字段存儲數據的方案。file format有兩種,分別是Antelope和Barracuda。指針
在MySQL 5.6以前的版本,默認file format是Antelope。
意思是,對於varchar和text字段,會將內容的前768字段放置在index record中,後面再接20個字節的指針。
剩下內容會放置在BLOB page中。code
假設有11個text字段,每一個字段都是1000字節。那麼在插入數據的時候,row size = (768+20)* 11 = 8668 > 8126,將會觸發row size too larget > 8126
報錯。
若是使用Antelope模式,不建議使用超過10個text或varchar字段。orm
Barracude會將全部數據放在BLOB page中,在index record裏面只放20個字節的指針。ci
查詢File format設置:get
show variables like "%innodb_file%";
my.cnf 設置innodb
innodb_file_format = Barracuda # innodb_file_per_table = 1 innodb_large_prefix = 1
innodb引擎的行格式(row format)有兩種。分別是compact和dynamic/compressed。table
ALTER TABLE test ROW_FORMAT=COMPRESSED; SHOW TABLE STATUS IN test_db;
這裏仍是之說Antelope模式下使用text的問題。普通的數值類型,其實很難超8126的長度限制,就不說了。在Antelope模式下,text字段的前768會存儲在index record中,會佔用row size的768+2個字節。因此text/varchar字段不能太多。除非肯定不會太長。
# 驗證測試的sql create table text2 ( text1 longtext, text2 longtext, text3 longtext, text4 longtext, text5 longtext, text6 longtext, text7 longtext, text8 longtext, text9 longtext, text10 longtext, text11 longtext ) ENGINE=InnoDB DEFAULT CHARSET=ascii; insert into text2 values( repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000) ); insert into text2 values( repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',197) # repeat('y',198) error ); -------- create table text3 ( text1 longtext, text2 longtext, text3 longtext, text4 longtext, text5 longtext, text6 longtext, text7 longtext, text8 longtext, text9 longtext, text10 longtext, text11 longtext ) ENGINE=INNODB DEFAULT CHARSET=ascii ROW_FORMAT=COMPRESSED; insert into text3 values( repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000), repeat('y',1000) );