MySQLのエラー『エラー2006: MySQL Server Has Gone Away』の解決方法
MySQLで「MySQL Server Has Gone Away(エラーコード2006)」というエラーが発生するのは、サーバーとの接続が切断されたことを意味している。これは多くの原因で起こるため、再現条件や対応方法を明確に特定することが重要。長時間の接続維持、大きなクエリ送信、パケットサイズ超過、タイムアウトなどの要因が重なると頻出する。
1. エラーが発生する主な条件
- MySQLがクライアントの接続をタイムアウトした
- 非常に大きなクエリやデータ(BLOBなど)を送信し、パケットサイズ制限を超えた
- 不正または不完全なSQL文を送信した
- MySQLサーバーの再起動やクラッシュ
2. エラーメッセージの例
ERROR 2006 (HY000): MySQL server has gone awayこのエラーはMySQLクライアントやプログラムで発生し、接続を再利用しようとしたときにサーバーから応答がないことで返される。
3. クエリが大きすぎる場合の対処方法
BLOBや長大なINSERT文を扱う際には、MySQLの最大パケットサイズを超えると接続が切断される。
SET GLOBAL max_allowed_packet = 1073741824; -- 1GB通常の設定では16MB(16777216)になっている。必要に応じて `my.cnf` に以下を追加。
[mysqld]
max_allowed_packet=256M4. 接続のタイムアウト対策
長時間処理し続けるスクリプトや非同期処理では、接続タイムアウトが問題になる。
[mysqld]
wait_timeout = 28800
interactive_timeout = 28800短すぎるとクライアントが接続を保持していてもサーバー側が切断してしまう。
5. サーバー側のクラッシュや再起動の影響
MySQLサーバーが何らかの理由で再起動またはクラッシュした場合も同様のエラーが発生する。サーバーログ `/var/log/mysql/error.log` や `dmesg` を確認して、OOMキラーやメモリエラー、ディスク障害の兆候を確認する。
6. SQL文が不正な場合の再現例
文法ミスや壊れた構文も「gone away」として返される場合がある。
INSERT INTO users VALUES ('aaa', 'bbb', -- カッコ閉じ忘れなどクエリ送信が完了せず、接続断とみなされる。
7. 接続再試行を行うアプリケーション設計
PHPやNode.jsなどのアプリケーションでは、接続が失われた際に自動再接続処理を加えることでエラー回避が可能。
PHP (PDO) での例:
try {
$dbh = new PDO($dsn, $user, $pass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 再試行ロジック
} catch (PDOException $e) {
if (strpos($e->getMessage(), 'server has gone away') !== false) {
// 再接続処理
}
}8. デーモンやバッチ処理の長時間接続対策
バッチやデーモンが長時間MySQL接続を維持するケースでは、定期的に接続を更新したり、Pingを送信することで切断を防ぐ。
$conn->ping(); // mysqliや一部のORMで使用可9. my.cnfの設定を再確認する
MySQLの設定ファイル my.cnf をチェックし、以下のようなパラメータを調整する。
[mysqld]
max_allowed_packet=256M
wait_timeout=28800
net_read_timeout=60
net_write_timeout=60変更後はMySQLを再起動する。
10. クライアント側のタイムアウト設定も確認
MySQLクライアントやORM、アプリケーションフレームワーク側でもタイムアウトが短く設定されていると、処理中に切断されることがある。
たとえば Node.js の mysql2 モジュールでの設定:
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test',
connectTimeout: 10000
});11. 通信の途中での切断(ネットワーク的な問題)
VPN経由やリバースプロキシ越しの接続では、途中でネットワーク切断が発生している可能性もある。iptablesやNginxのタイムアウト設定、あるいはTCP Keepaliveの設定も確認する。
12. 特定のSQLを疑う(特にLOAD DATAや大規模INSERT)
`LOAD DATA INFILE` や巨大な `INSERT INTO … VALUES …` を実行している際に発生するなら、クエリ自体を分割することで対処できる。
-- 悪い例(巨大なINSERT)
INSERT INTO logs VALUES (...), (...), (...), ... -- 数千行
-- 良い例(分割して複数回送信)
INSERT INTO logs VALUES (...);
INSERT INTO logs VALUES (...);-
前の記事
Rubyのエラー『LocalJumpError: no block given (yield)』の解決方法 2025.05.27
-
次の記事
PHPエラー『Warning: Header Already Sent』の解決方法 2025.05.28
コメントを書く