2011-06-30

MySQL Got error 139 from storage engine.

現在、運用・保守しているシステムの本番環境にて以下のエラーが発生した。
環境:MySQL 5.1.47、innodb plugin 1.0.8
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs

開発環境で同様の操作を行うと以下のエラーが発生。
環境:MySQL 5.1.45、Built-In innodb
ERROR 1030 (HY000): Got error 139 from storage engine

いろいろ検索してみると以下のような原因でエラーが発生している模様。
  • InnoDBの行サイズの上限はページサイズの約半分で、デフォルトでは約8KB。
  • 可変長カラム(VARBINARY、VARCHAR、BLOB、TEXT)のデータは行の外部に保存されるが、先頭の768Bだけは行の内部に保存される。
  • 一つのテーブルに11個のTEXT型フィールドを作り、それぞれに768B以上のデータを入れようとすると、768 * 11 = 8448 > 8000 なので保存できない。

MySQLのリファレンスマニュアルにも「InnoDBテーブルにおける制限」として以下のように記載されていました。
MySQL 5.1 Reference Manual :: 13.6.14. Restrictions on InnoDB Tables
The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a database page. That is, the maximum row length is about 8000 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.

まとめ:行サイズについて
MySQL自体の上限は、64KB。しかし、BLOBのデータは他の領域に格納されるので含みません。さらに、ストレージエンジンごとに制限が存在する場合があります。
InnoDBは、テーブルスペースのページサイズの約半分でが上限となり、ページサイズのデフォルトは16KBなのでデフォルトの行サイズは約8KBとなります。ページサイズを変更することも出来ますが、MySQLをソースからコンパイルして、さらにテーブルスペースとログファイルを再作成する必要があります。ページサイズの変更を行うと、ページサイズの上限は64KBとなるので、その場合の1行の最大サイズは32KBとなります。ちなみに、MySQL Clusterは1行あたり最大8KBです。

設計を見直すか・・・

※また、本ページを作成するのに以下のサイトを参考にしました。
InnoDBの意外な制約: Got error 139 from storage engine | へびにっき
Nix::WebLab : Got error 139 from storage engine
MySQL :: MySQL 5.1 Reference Manual :: 13.6.14 Restrictions on InnoDB Tables

2011-06-29

MySQL Innodb pluginバージョン確認

MySQLのInnodb pluginのバージョン確認方法。
mysql> SELECT @@innodb_version;
+------------------+
| @@innodb_version |
+------------------+
| 1.0.8            |
+------------------+
1 row in set (0.00 sec)