MySQLのエラー『エラー1118: Row Size Too Large』の解決方法

MySQLで「エラー1118: Row size too large(行サイズが大きすぎます)」が発生するのは、1つの行のサイズがMySQLの制限を超えてしまった場合。この制限は特にInnoDBストレージエンジンで影響が出やすく、大量のカラムやTEXT/VARCHAR型を多用するテーブル設計時に遭遇しやすい。
- 1. 1. エラーメッセージの例
- 2. 2. 発生条件と背景
- 3. 3. TEXT型やBLOB型を使うとどうなるか
- 4. 4. 解決策1: カラムをTEXTまたはBLOBに変更
- 5. 5. 解決策2: innodb_strict_modeを無効にする(非推奨)
- 6. 6. 解決策3: DYNAMICまたはCOMPRESSEDフォーマットを使用する
- 7. 7. 解決策4: 不要なカラムを削除・分割
- 8. 8. 解決策5: VARCHARのサイズを見直す
- 9. 9. 解決策6: utf8mb4ではなくutf8を使う
- 10. 10. 解決策7: テーブルの再構築と確認
- 11. 11. 使用中のROW_FORMATを確認する方法
- 12. 12. テーブルサイズとカラム長のバランスを意識する
1. エラーメッセージの例
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help.
このメッセージは、1行あたりのバッファページサイズ(通常16KB)の上限を超えたときに表示される。
2. 発生条件と背景
InnoDBでは1ページ16KBの制限があり、1レコードで使えるデータサイズは最大で約8126バイト(行オーバーヘッド含む)に制限されている。多くのVARCHARカラムや長いデータ型があるとこの制限を超えてしまう。
3. TEXT型やBLOB型を使うとどうなるか
VARCHARやCHAR型は固定長・可変長でもページ内に格納されるのに対し、TEXTやBLOB型はオフページ(別領域)に格納され、ページサイズにカウントされにくくなる。
例:
CREATE TABLE example (
col1 VARCHAR(1000),
col2 VARCHAR(1000),
...
col30 VARCHAR(1000) -- 多すぎてエラーになる
);
上記のような場合、colXをTEXT型にすることで回避可能。
4. 解決策1: カラムをTEXTまたはBLOBに変更
ALTER TABLE example MODIFY col5 TEXT;
これにより、そのカラムのデータはオフページに格納され、行サイズ制限の対象外になる。
5. 解決策2: innodb_strict_modeを無効にする(非推奨)
SET GLOBAL innodb_strict_mode = 0;
この方法は強制的にINSERTを許容するが、データが正しく格納されない可能性があり推奨されない。
6. 解決策3: DYNAMICまたはCOMPRESSEDフォーマットを使用する
InnoDBでは、テーブルフォーマットを「DYNAMIC」または「COMPRESSED」に設定することで、大きなVARCHARもオフページに追い出される。
CREATE TABLE example (
col1 VARCHAR(1000),
...
) ROW_FORMAT=DYNAMIC;
既存テーブルに対しては:
ALTER TABLE example ROW_FORMAT=DYNAMIC;
7. 解決策4: 不要なカラムを削除・分割
1テーブルに大量の列を持たせるのではなく、正規化してサブテーブルに分けることで行サイズを減らせる。
8. 解決策5: VARCHARのサイズを見直す
必要以上に大きなVARCHARを指定していないか見直す。たとえばVARCHAR(10000)などは実際の使用量に比べて過大な場合が多い。
9. 解決策6: utf8mb4ではなくutf8を使う
utf8mb4は1文字4バイト、utf8は最大3バイト。もし絵文字などが不要ならutf8で十分な場合もある。
CREATE TABLE example (
name VARCHAR(200) CHARACTER SET utf8
);
文字セットを変更することで、1列あたりのバイト数を削減可能。
10. 解決策7: テーブルの再構築と確認
テーブルを再作成したりOPTIMIZE TABLEを実行して、InnoDBの行フォーマットを見直す。
OPTIMIZE TABLE example;
11. 使用中のROW_FORMATを確認する方法
SELECT TABLE_NAME, ROW_FORMAT
FROM information_schema.tables
WHERE table_name = 'example';
現在のROW_FORMATがCOMPACTになっていればDYNAMICに変更を検討できる。
12. テーブルサイズとカラム長のバランスを意識する
大きなカラムが大量に存在する場合、ページサイズの制限に抵触しやすくなる。全体設計でサイズの上限を意識した設計が必要。
-
前の記事
Rubyのエラー『SocketError: getaddrinfo: Name or service not known』の解決方法 2025.05.19
-
次の記事
“Unexpected token”エラーを克服する方法:Vue.jsでの対策 2025.05.20
コメントを書く