pcntl_fork и соединение с MySQL пропало - PullRequest
17 голосов
/ 08 сентября 2010

У меня есть цикл foreach, который разветвляется внутри него. После того, как процесс разветвляется, он обращается к базе данных. Я получаю ошибку:

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

Дело в том, что я подключаюсь к базе данных после Я разветвился.

Мой вопрос: с чего бы это?

Если это произойдет, получаю ли я доступ к базе данных до того, как разветвляется? Будет ли ребенок наследовать соединения с БД?

(примечание: я могу опубликовать код, но он довольно большой, так как все в классах, что может быть причиной моего замешательства при доступе к БД. Еще одна вещь, которую вы должны знать, это то, что я использую ZF. )

Ответы [ 4 ]

14 голосов
/ 16 сентября 2010

(комментарий -> ответ на запрос автора)

Читая подробности, я вижу, что раздвоенные дети наследуют связь с БД своих родителей, и это известная проблема: http://php.net/manual/en/function.pcntl-fork.php#70721

6 голосов
/ 07 февраля 2013

Это помогло мне: http://www.electrictoolbox.com/mysql-connection-php-fork/

Особенно mysql_connect($server, $username, $password, true);

2 голосов
/ 05 августа 2011

За исключением того, что это не проблема . Это способ, которым pcntl_fork был разработан. Любое расширение (как четко указано в документации), поддерживающее свои собственные файловые дескрипторы, будет иметь поврежденные дескрипторы, потому что все дочерние элементы и родители имеют одинаковые файловые дескрипторы.

1 голос
/ 11 декабря 2016

Вы можете избежать закрытия соединения при выходе из разветвленного процесса, если убьете разветвленный процесс с помощью 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);

Причина такого поведения в том, что когда процесс PHP завершается, PHP отправляет серверу базы данных "Завершить соединение "команда.Но сокет будет закрыт системой только тогда, когда все ссылки на сокет закрыты.Использование SIGKILL поможет нам избежать отправки команды «Завершить соединение» на сервер базы данных.

...