2006 php network_error ai_generated true

PDOException: SQLSTATE[HY000] [2006] MySQL server has gone away in /var/www/app/src/Database/Connection.php:42

ID: php/pdo-mysql-server-has-gone-away

Also available as: JSON · Markdown · 中文
85%Fix Rate
88%Confidence
1Evidence
2023-11-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
PHP 7.4 active
PHP 8.1 active
PHP 8.2 active
MySQL 5.7 active
MySQL 8.0 active

Root Cause

The MySQL server closed the connection due to a timeout (wait_timeout or interactive_timeout), a packet size exceeding max_allowed_packet, or a server crash/restart, and the PHP PDO connection was not re-established.

generic

中文

MySQL服务器因超时(wait_timeout或interactive_timeout)、数据包大小超过max_allowed_packet或服务器崩溃/重启而关闭连接,且PHP PDO连接未重新建立。

Official Documentation

https://dev.mysql.com/doc/refman/8.0/en/gone-away.html

Workarounds

  1. 75% success Increase MySQL's wait_timeout and interactive_timeout in my.cnf, e.g., set wait_timeout=28800; interactive_timeout=28800. Then restart MySQL.
    Increase MySQL's wait_timeout and interactive_timeout in my.cnf, e.g., set wait_timeout=28800; interactive_timeout=28800. Then restart MySQL.
  2. 70% success Increase max_allowed_packet in my.cnf to handle large queries, e.g., set max_allowed_packet=64M. Restart MySQL.
    Increase max_allowed_packet in my.cnf to handle large queries, e.g., set max_allowed_packet=64M. Restart MySQL.
  3. 90% success Implement connection retry logic in PHP: catch the exception and reconnect using a new PDO instance. Example: try { $stmt = $pdo->query('SELECT 1'); } catch (\PDOException $e) { if ($e->getCode() == 2006) { $pdo = new PDO($dsn, $user, $pass); $stmt = $pdo->query('SELECT 1'); } }
    Implement connection retry logic in PHP: catch the exception and reconnect using a new PDO instance. Example:
    try {
        $stmt = $pdo->query('SELECT 1');
    } catch (\PDOException $e) {
        if ($e->getCode() == 2006) {
            $pdo = new PDO($dsn, $user, $pass);
            $stmt = $pdo->query('SELECT 1');
        }
    }

中文步骤

  1. Increase MySQL's wait_timeout and interactive_timeout in my.cnf, e.g., set wait_timeout=28800; interactive_timeout=28800. Then restart MySQL.
  2. Increase max_allowed_packet in my.cnf to handle large queries, e.g., set max_allowed_packet=64M. Restart MySQL.
  3. Implement connection retry logic in PHP: catch the exception and reconnect using a new PDO instance. Example:
    try {
        $stmt = $pdo->query('SELECT 1');
    } catch (\PDOException $e) {
        if ($e->getCode() == 2006) {
            $pdo = new PDO($dsn, $user, $pass);
            $stmt = $pdo->query('SELECT 1');
        }
    }

Dead Ends

Common approaches that don't work:

  1. 70% fail

    The error is caused by MySQL's timeout, not PHP's execution time; changing PHP settings does not prevent the server from closing idle connections.

  2. 50% fail

    Persistent connections can mask the issue but may lead to stale connections being reused, causing the same error later; they also consume server resources.

  3. 80% fail

    Restarting temporarily reopens connections, but the underlying timeout or packet size issue remains, causing the error to recur.