症状

MySQLで大きなデータを INSERT/UPDATE しようとすると「Packet too large」または「Got a packet bigger than ‘max_allowed_packet’ bytes」エラーが表示される。

結論:まずこれを確認

  1. SHOW VARIABLES LIKE 'max_allowed_packet'; で現在の設定値を確認
  2. 送信しようとしているデータサイズと比較
  3. 設定値が小さければ 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