【mysql】Row size too large (> 8126) のエラー対処法

mysql で update を実行した際、以下のエラーが出た

-------------------------------------------------
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_FORMATが「Compact」のときに、8126バイト以上のレコードを入力しようとすると出るエラーらしい。

ターミナルの mysql から現在の ROW_FORMAT を確認

-------------------------------------------------
use データベース名 ← データベースを選択

SHOW TABLE STATUS LIKE 'テーブル名'\G
-------------------------------------------------

出力結果
*************************** 1. row ***************************
Name: テーブル名
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 35155
Avg_row_length: 4583
Data_length: 161136640
Max_data_length: 0
Index_length: 0
Data_free: 6291456
Auto_increment: 46319
Create_time: 2018-03-09 16:18:39
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.01 sec)

Row_format の Compact の部分を、DYNAMIC か COMPRESSED に変更すれば消えるらしい。で、変更するには innodb_file_format が Barracuda になっていないといけない。

innodb_file_format を確認

-------------------------------------------------
mysql> SHOW GLOBAL VARIABLES LIKE '%innodb_file_%';
-------------------------------------------------

出力結果
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| innodb_file_format | Antelope |
| innodb_file_format_check | ON |
| innodb_file_format_max | Antelope |
| innodb_file_per_table | ON |
+--------------------------+-----------+
4 rows in set (0.00 sec)

innodb_file_format が Antelope なので Barracuda に変更する必要がある。

my.cnfを編集
-------------------------------------------------
vim /etc/my.cnf
-------------------------------------------------

[mysqld]以下に追記
-------------------------------------------------
[mysqld]
innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
-------------------------------------------------

service mysqld restart で再起動

変更を確認
mysql> SHOW GLOBAL VARIABLES LIKE '%innodb_file_%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| innodb_file_format | Barracuda |
| innodb_file_format_check | ON |
| innodb_file_format_max | Barracuda |
| innodb_file_per_table | ON |
+--------------------------+-----------+
4 rows in set (0.00 sec)

↑一度 mysqld を再起動しても反映されていない時があった。必ず反映していることを確認すること。

ここまでで、Row_format を Compact → DYNAMIC (or COMPRESSED)に変更する下準備ができたことになる。

再度確認
-------------------------------------------------
use データベース名 ← データベースを選択

SHOW TABLE STATUS LIKE 'テーブル名'\G
-------------------------------------------------

まだ Row_format は Compact のまま

今回は ROW_FORMAT を DYNAMIC にするので以下を実行
-------------------------------------------------
mysql> ALTER TABLE `テーブル名` ROW_FORMAT=DYNAMIC;
-------------------------------------------------

無事に変更されていることを確認する
-------------------------------------------------
use データベース名 ← データベースを選択

SHOW TABLE STATUS LIKE 'テーブル名'\G
-------------------------------------------------