環境: MySQL 5.0 (追記)
某CMSにて、1つのテーブルにTEXT型のフィールドをたくさん(10前後)作ったところ、次のようなエラーが出てデータを保存できなくなった。
Got error 139 from storage engine
このエラーメッセージで検索すればいろいろと情報が出てくるが、こういうことらしい:
- InnoDBの行サイズの上限はページサイズの約半分で、デフォルトでは約8000バイト
- 可変長カラム(VARBINARY, VARCHAR, BLOB, TEXT)のデータは行の外部に保存されるが、先頭の768バイトだけは行の内部に保存される
- よって例えば一つのテーブルに11個のTEXT型フィールドを作り、それぞれに768バイト以上のデータを入れようとすると、768*11=8448 > 8000 なので保存できない
ページサイズは8〜64KBまで設定できるが、変更するためにはMySQL本体をコンパイルし直した上でテーブルスペースとログファイルを再作成する必要があるらしく、運用途中での変更は難しい。よってどうしてもInnoDBでなければならない場合は、テーブルを分割するなどして対処するしかない。
件のCMSの場合は特にInnoDBでなくても良かったので、テーブルをMyISAMに変換することで回避できた。
ALTER TABLE TABLE_NAME ENGINE=MyISAM;
MyISAMの場合、行サイズの上限は64KBで、かつTEXTやBLOBの保存に要するのは9〜12バイトなので、同じ問題はまず起こらない。最近は特に何も考えずにInnoDBを使っていたので、ヒヤリとさせられた。
参考にしたサイト:
- 13.2.11.2. File Space Management – MySQL 5.0 Reference Manual
- 10.5. Data Type Storage Requirements – MySQL 5.0 Reference Manual
- 限界までMySQLを使い尽くす!! – 漢(オトコ)のコンピュータ道
- Nix::WebLab : Got error 139 from storage engine
追記
SH2さんからのコメントで、MySQL 5.1+InnoDB Plugin/MySQL 5.5以降で新たなファイルフォーマット(Barracuda)を使用すれば状況は改善される、と教えていただきました。どうやらTEXT/BLOB一つあたり20バイトだけになるようです。詳細は以下のリンクなどを参照してください(私もまだ読んでいる途中ですが)。