简体   繁体   中英

MySQL server has gone away - but no connect error

Consider the following scenario: We have an AWS worker instance (SQS based) which opens persistent MySQL connections to our RDS.

$this->connectRegistry[ $host ][ 'connect' ] = mysqli_connect(
    "p:" . $host ,
    $this->hostCredentials[ $host ][ 'username' ] ,
    $this->hostCredentials[ $host ][ 'password' ]
);

Now sometimes - not on a regular basis - this call genertes the following warning:

PHP Warning: mysqli_connect(): MySQL server has gone away

As AWS worker instances are handling requests with a web-server, the setup basically identical to a usual instance which serves a website. We use the same class in multiple projects but in not a single website this error has even occurred once.

To get an idea where these warnings originates from we have tried to print a stack trace if a connection error occurs but - and now the awkward thing starts to come in - there is no connect error. Please take a look at the whole connect function:

private function connect ( $host )
{
    $this->connectRegistry[ $host ][ 'connect' ] = mysqli_connect(
        "p:" . $host ,
        $this->hostCredentials[ $host ][ 'username' ] ,
        $this->hostCredentials[ $host ][ 'password' ]
    );
    $error = mysqli_connect_error();
    if( $error ) {
        $this->raiseError( "Connect (" . mysqli_connect_errno() . ") " . $error );
        return false;
    }
    return true;
}

The method raiseError builds a complete error message with a stack trace and so on and then calls trigger_error . However, this method is not called if the above-mentioned warning is triggered.

Our first goal is to know in which cronjobs these warnings are triggered - maybe there are some bad performing queries.

There would not be any connection error if you get

mysqli_connect(): MySQL server has gone away

This message means that the existing connection is not usable anymore. Something must have happened and the connection was closed by MySQL server. There could be many reasons for this. The most common one is calling mysqli_close() somewhere else in your code, but as you are using persistent connections here the root cause could be something different altogether. You need to debug what is causing the connection to be dropped.

However, I would strongly recommend to stop using persistent connections altogether . It is highly unlikely that you have a valid technical reason to use them and debugging them can be very problematic.

I had this kind of problem with php daemons: when you start your daemon, the php connection is made and if there are no query for some time, the DB connection actually dies.

In the past I've found two solution

  1. To keep the connection alive, make a simple fast query every n seconds
  2. Create the connection at runtime, not when the daemon start but when the daemon does the work.

I advice the second choice.

The "persistent" connection doesn't mean that the connection will live forever, it is just reused if use the same username, password etc ( doc ), this can help if you use the method 2)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM