pcntl_fork 和 MySQL 连接消失
我有一个在其中分叉的 foreach 循环。进程fork后,访问数据库。我收到一个错误:
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
问题是,我在分叉后连接到数据库。
我的问题:为什么会发生这种情况?
如果发生这种情况,我实际上是在分叉之前访问数据库吗?孩子会继承数据库连接吗?
(注意:我可以发布代码,但它相当大,因为它都在类中,这可能是导致我在访问数据库时感到困惑的原因。您应该知道的另一件事是我正在使用 ZF。)
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.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
(评论 - >回答每个海报的请求)
阅读更多内容我发现分叉的孩子确实继承了父母的数据库连接,这是一个已知的问题: http://php.net/manual/en/function.pcntl-fork.php#70721
(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
这对我有帮助: http://www.electrictoolbox.com/mysql-connection-php -fork/
特别是
mysql_connect($server, $username, $password, true);
This helped for me: http://www.electrictoolbox.com/mysql-connection-php-fork/
Especially
mysql_connect($server, $username, $password, true);
如果使用 SIGKILL 终止分叉进程,则可以避免在分叉进程退出时关闭连接。
出现此行为的原因是,当 PHP 进程退出时,PHP 会向数据库服务器发送“终止连接”命令。但是只有当套接字的所有链接都关闭时,系统才会关闭套接字。使用SIGKILL可以帮助我们避免向数据库服务器发送“终止连接”命令。
You can avoid closing connection when forked process exit, if you kill forked process with SIGKILL.
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.
但这不是一个问题。这就是 pcntl_fork 的设计方式。任何维护其自己的文件描述符的扩展(如文档明确指出的那样)都会有损坏的描述符,因为所有子级和父级共享相同的文件描述符。
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.
您需要关闭父进程上的 MySQL 连接,然后为每个子进程建立一个新连接。
You need to close the MySQL connection on your parent process and then make a new connection for each child.