2016年8月15日 星期一

MySQL Error 1118 : Row Size too large ( > 8126)


簡單說 :

Innodb 下, 如果 innodb_page_size 設定為 16KB
table 每一個 row 最大的 length(size) 為 8126 bytes  ( 大約是 16KB /2 )

(注意: mysql 限制 row size 為 65536,但是每種 engine 還會有自己的限制)
(ref : https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
(Every table (regardless of storage engine) has a maximum row size of 65,535 bytes. Storage engines may place additional constraints on this limit, reducing the effective maximum row size.)



固定欄位的大小就是固定大小
但是變動欄位大小 (blog / text / varchar) 等,在不同的 innodb row_format 下有不同的計算方法

compact :
變動欄位會用 768 bytes, 超過的會放在另一個 page
如果有太多的 column (例如11個 blob),那很容易就超過 8126 bytes,就會出現上述的訊息

dynamic / compress
變動欄位會用 20 bytes,超過的會放在另一個page



解決方法 :

1. 改用 dynamic / compress row_format

這需要啟用 innodb barracuda file-format
同時重新 create table(alter table)
row format可以用 show table status 查看



2. 增加 page_size

提高 innodb_page_size
show variables like "innodb_page_size"

ref :
 http://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html

The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a database page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.

http://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html



3. 把欄位拆到其他 table


4. 把很多個 blob/text 合併,在應用層再去分離