SQLSTATE[42000]:  Syntax error or access violation: 1118 Row size too large (> 8126). の解消方法

ローカルでUPDATE文を実行しようとしたときに`SQLSTATE[42000]:  Syntax error or access violation: 1118 Row size too large (> 8126). `というエラーが出て詰まったので、解消方法をまとめます。

# エラー文確認
エラー文全文はこんな感じ。テーブル名とかは適当に変えてます。
私基準で見やすいように改行しています。

``` mysql
SQLSTATE[42000]: 
Syntax error or access violation: 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., query was: 
    UPDATE `user` 
    SET 
        `name` = ?, 
        `memo` = ?
    WHERE (`id` = '1')
```

なんかヒントっぽいことが書いてあるけど、英語が読めないのでGoogle先生に聞いてみます。

＜Google先生による翻訳＞
> 一部の列をTEXTまたはBLOBに変更するか、
  ROW_FORMAT = DYNAMICまたはROW_FORMAT = COMPRESSEDが役立つ場合があります。

なるほど。なんかDBの設定を変えたら治りそうですが、MySQLの知識が弱いのでどうしたらいいのかわかりません。

とりあえずググります。

# 解消方法

ググった結果、こちらの記事に行き当たりました。

https://sawara.me/mysql/2219/

エラー文もだいたい同じだし、なんか行けそう。

記事の通り、DBの設定を確認します。

``` mysql
mysql > SHOW TABLE STATUS Where Name = 'user';

**********************************************
Name: user
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 2
Avg_row_length: 14336
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2020-06-06 15:14:01
Update_time: NULL
Check_time: NULL
Collation: utf8_unicode_ci
Checksum: NULL
Create_options:
Comment:
```

`Row_format=Compact`なので、`DYNAMIC`か`COMPRESSED`に変えたいです。
上記の記事では`DYNAMIC`にしていましたが、ローカルではなくテスト用のDBを確認したら`Row_format=COMPRESSED`だったので、そちらに合わせるように修正します。

記事を参考に、下記のクエリを実行。

``` mysql
ALTER TABLE `user` ROW_FORMAT=Compressed;
```

まあ、これじゃできないって書いてあるから、できないですよね。

というわけで、ファイルフォーマットを`Barracuda`に変更します。
ここで、上記の記事通りにやってもできなくなりました。

以下、記事の引用
> ファイルフォーマットを”Barracuda”にするにはmy.cnfの設定を変更し、MySQLを再起動します。MySQL5.1の場合はInnoDB Pluginを有効にしないとだめなようで。
[code title=”my.cnf”]
innodb_file_per_table
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
[/code]
設定が反映されれば以下の様になります。

弱々エンジニアなので、そもそも`my.cnf`がどこにあるのかわからない。
とりあえずXAMPPのコントロールパネルを開いて、`my.ini`に先程引用した設定をコピペして何度かMysqlを再起動してもできませんでした。

やっぱり`my.cnf`と`my.ini`は違うのかなーと思ったところで、別の記事に出会いました。

https://www.mk-mode.com/blog/2015/07/15/mariadb-innodb-file-format-changing-to-barracuda/#

この記事によると、
> （設定ファイルのパスや名称は環境により異なる）

とのこと。

やっぱり`my.ini`であっているのでは！？

そして、よく見たら設定ファイルに記載する内容が一つ目の記事と若干違うので、こっちの記事に書いてある内容を`my.ini`に記載してみる。

> [mysqld]
innodb_file_per_table = 1
innodb_file_format = Barracuda

ただ、これだと設定が足りないので、一つ足して最終的に記載した内容はこちらです。

``` mysql
[mysqld]
innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
```
これでMySQLを再起動し、SQLの設定を確認してみます。

``` mysql
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        |
+--------------------------+-----------+
```


きちんと変わっていることが確認できました。

ここで、再度設定変更用のクエリを投げ、確認します。

``` mySQL
mysql > ALTER TABLE `user` ROW_FORMAT=Compressed;

mysql > SHOW TABLE STATUS Where Name = 'user';

**************************************************
Name: user
Engine: InnoDB
Version: 10
Row_format: Compressed
Rows: 2
Avg_row_length: 14336
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: NULL
Create_time: 2020-06-06 15:14:01
Update_time: NULL
Check_time: NULL
Collation: utf8_unicode_ci
Checksum: NULL
Create_options: row_format=COMPRESSED 
Comment:
```

きちんと`Row_format`が`Compressed`になっていることを確認できました。

そして、最初にエラーがでたのと同じUPDATE文をなげ、
エラーがでないことと正常にデータが更新されていることを確認して完了です！

少しでも誰かの役に立てれば幸いです。