症状
MySQLで大きなデータを INSERT/UPDATE しようとすると「Packet too large」または「Got a packet bigger than ‘max_allowed_packet’ bytes」エラーが表示される。
結論:まずこれを確認
SHOW VARIABLES LIKE 'max_allowed_packet';で現在の設定値を確認- 送信しようとしているデータサイズと比較
- 設定値が小さければ
my.cnfで増やす
トラブルシューティングフロー
flowchart TD
A[Packet too large エラー発生] --> B{エラー発生箇所は?}
B -->|クライアント側| C[クライアントの max_allowed_packet 確認]
B -->|サーバー側| D[サーバーの max_allowed_packet 確認]
C --> E{設定値 < データサイズ?}
D --> E
E -->|Yes| F[設定値を増やす]
E -->|No| G[データ分割を検討]
F --> H{一時的な変更?}
H -->|Yes| I[SET GLOBAL で変更]
H -->|No| J[my.cnf を編集]
J --> K[MySQL 再起動]
I --> L[動作確認]
K --> L
よくある原因
- max_allowed_packet のデフォルト値が小さい - MySQL 5.7 以前はデフォルト 4MB、8.0 は 64MB
- BLOB/TEXT カラムに大きなファイルを格納 - 画像・PDF などのバイナリデータ挿入時に発生しやすい
- 大量の行を一括 INSERT - VALUES が多すぎてパケットサイズ超過
- クライアントとサーバーで設定が異なる - 両方の設定が必要な場合がある
- レプリケーション環境での設定漏れ - マスター/スレーブで設定が異なる
- mysqldump のリストア時 - ダンプファイルに大きなデータが含まれている
確認手順
ステップ1: 現在の設定値を確認する
mysql -u root -p -e "SHOW VARIABLES LIKE 'max_allowed_packet';"
🔍 チェックポイント: 値がバイト単位で表示される(例: 67108864 = 64MB)
ステップ2: 送信データのサイズを確認する
# ファイルの場合
ls -la 対象ファイル
# SQL文の場合
wc -c 対象ファイル.sql
🔍 チェックポイント: データサイズが max_allowed_packet より大きければ原因特定
ステップ3: 一時的に設定を変更する(テスト用)
mysql -u root -p -e "SET GLOBAL max_allowed_packet=256*1024*1024;"
🔍 チェックポイント: 新しいセッションで SHOW VARIABLES して反映を確認
ステップ4: 永続的に設定を変更する
# my.cnf の場所を確認
mysql --help | grep my.cnf
設定ファイルに追記:
[mysqld]
max_allowed_packet=256M
[mysql]
max_allowed_packet=256M
🔍 チェックポイント: [mysqld] と [mysql] の両方に記載が必要
ステップ5: MySQL を再起動する
# systemd の場合
sudo systemctl restart mysql
# service の場合
sudo service mysql restart
🔍 チェックポイント: 再起動後に SHOW VARIABLES で設定が反映されているか確認
ステップ6: 動作確認
元の操作(INSERT/UPDATE/リストア)を再実行してエラーが解消されたか確認する。
NG行動(やってはいけないこと)
- 上限なしに max_allowed_packet を増やす - メモリ消費が増加し、DoS攻撃に脆弱になる
- SET SESSION で変更して終わりにする - セッション切断で設定がリセットされる
- サーバー側だけ変更してクライアント側を忘れる - クライアント側でも制限される場合がある
- 再起動せずに永続化されたと思い込む - my.cnf 変更は再起動まで反映されない
- レプリカの設定を忘れる - レプリケーション環境では全ノードで設定が必要
よくある質問(FAQ)
Q1: max_allowed_packet の推奨値は?
A: 用途による。一般的には 64MB〜256MB。BLOB を多用するなら 512MB〜1GB も検討。ただしメモリ消費とのトレードオフがある。
Q2: SET GLOBAL と my.cnf 編集の違いは?
A: SET GLOBAL は即時反映だが MySQL 再起動でリセットされる。my.cnf は再起動後に反映され永続化される。両方行うのが確実。
Q3: クライアントツール(mysqldump、mysql)でも設定が必要?
A: 必要な場合がある。[mysql] や [mysqldump] セクションにも max_allowed_packet を追加するか、コマンドラインで --max_allowed_packet=256M を指定する。
関連するエラー・症状
準備中
解決しない場合
- 公式ドキュメント: MySQL :: max_allowed_packet
- 確認すべきログ:
/var/log/mysql/error.logまたはmysqld.log - 次に調べるキーワード:
mysql memory limit,mysql bulk insert,mysql blob size limit