MYSQLでRow size too large (> 8126). エラーに対処

xamppを使ってPHPの作業をしていたところ、以下のようなエラーが発生しました。

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.

PHPのエラーではなく、MYSQLのエラーでした。
いったい何のエラー?

所見では見当もつかず、ググって調べました。

原因は1レコードTEXTカラムが多すぎたこと

MYSQLには1レコードの形をあらかじめ設定します。
ところが、TEXTやBLOBなど容量の大きいカラムが一定数以上1レコードに存在すると、エラーが発生することがわかりました。

ちなみにエラーがでたレコードには、TEXTカラムが20個ありました。
TEXTカラムを減らせば確かにエラーは出なくなりました。

ただ疑問に思いました。
TEXTカラムを減らさないで解決する方法がないものだろうか?

ググって調べたら、解決策がありました。
以下に記載いたします。

ROW_FORMATを実行する

エラーの出ているテーブルで「ROW_FORMAT」を実行すれば直ります。
ちなみに「ROW_FORMAT」は圧縮の方法指定です。

カラムが多すぎて容量が大きい場合に備えて、圧縮してカバーするような感じです。

なるほど圧縮で回避するということで理解できました。
では、具体的にどうやって指定すればよいのでしょうか?

テーブル作成時にROW_FORMATを指定する方法

テーブルを制作する場合は、以下のように記述します。

これを以下のように記述します。

これだけです。
ROW_FORMATを記述してテーブル作成をすれば、圧縮対応のテーブルになり、Row size too large (> 8126). エラーが発生しなくなります。

では既に稼働していて、テーブルを再作成できない場合はどうすればよいのでしょうか?

うまいやり方がありました。

phpmyadminで直接指定する方法

テーブルを再作成ができない場合は、後から指定でROW_FORMATを指定します。

phpmyadminには、SQL文を直接指定することができます。
ここに以下のように記述し実行ます。

ちなみに、PHPファイルに上記分を記述し実行する方法でもOKです。

ROW_FORMATは「DYNAMIC」と「COMPRESSED」のどちらを使用すべきか?

結論はどちらでもOKです。
ただ、今回の場合「COMPRESSED」でやってみたところ、エラーは解消されませんでした。

サーバー環境の影響もあるのかもしれませんが、私は「DYNAMIC」でエラーが解消されました。

ちなみにMYSQL、PHPのバージョンが異なるとエラーが出ないケースもあります。

今回現象が発生した環境は以下の通りです。

  • MYSQL 10.1.38
  • PHP 5.6.40

同じことを以下の環境でやってみたところ、エラーは発生しませんでした。

  • MYSQL 10.4.11
  • PHP 7.4.4

どうやら新しいバージョンの環境であれば現象がでず、古いバージョンの環境ならば現象が発生するようです。

恒久的な修正ならば create table時に記述し、一時的な修正ならばphpmyadmin等で修正でよさそうです。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております