pcntl_fork and the MySQL connection is gone

12,418

Solution 1

(comment --> answer per poster's request)

Reading more into it I see forked children do inherit their parent's db connection, and it is a known problem: http://php.net/manual/en/function.pcntl-fork.php#70721

Solution 2

This helped for me: http://www.electrictoolbox.com/mysql-connection-php-fork/

Especially mysql_connect($server, $username, $password, true);

Solution 3

You can avoid closing connection when forked process exit, if you kill forked process with SIGKILL.

<?php
$dbh = new PDO('pgsql:host=localhost', $username, $password);
$pid = pcntl_fork();
if($pid == 0){
        register_shutdown_function(function(){
                posix_kill(getmypid(), SIGKILL);
        });
        exit;
}
sleep(1);
$statement = $dbh->query('select 1');
var_dump($statement);

The reason of this behavior, that when PHP process is exit, than PHP sends to database server "Terminate connection" command. But socket will be closed by system only when all links to socket is closed. Using SIGKILL help us to avoid sending "Terminate connection" command to database server.

Solution 4

Except it is not a problem. It is the way pcntl_fork was designed. Any extension (as the documentation clearly states) that maintains it's own file descriptors will then have corrupted descriptors because all children an parents share the same file descriptors.

Share:
12,418

Related videos on Youtube

d-_-b
Author by

d-_-b

Updated on October 03, 2020

Comments

  • d-_-b
    d-_-b over 3 years

    I have a foreach loop that forks within it. After the process forks, it accesses the database. I get an error:

    SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
    

    The thing is, I'm connecting to the database after I've forked.

    My question: Why would this be happening?

    If this happens, am I actually accessing the database before forking? Will the child inherit DB connections?

    (note: I can post code, but it's rather large as it's all in classes, which could be what is causing my confusion of when I'm accessing the DB. Another thing you should know is I'm using ZF.)

    • Fanis Hatzidakis
      Fanis Hatzidakis over 13 years
      Thanks, and good luck! On second thought, take a look at gearman.org as a viable option for when forking becomes so complicated.
  • d-_-b
    d-_-b over 13 years
    I just thought I'd clarify: The reason why I got the error even though the child inherited the db connection is that I am forking a bunch of new processes that all need a db connection.
  • RedShift
    RedShift about 3 years
    I'd like to add that this affects all resources, not just MySQL connections. For example all the sockets opened before forking will die if a child exits. So always create resources after forking. The comment link in this answer is very valuable.