【问题标题】:When SIGTERM is sent, does the child process close mysql connection?发送SIGTERM时,子进程是否关闭mysql连接?
【发布时间】:2017-07-14 13:48:03
【问题描述】:

请想象一些子进程是由 pcntl_fork() 生成的,它们分别使用 PDO 打开 mysql 连接。 如果父进程使用 posix_kill() 向子进程发送 SIGTERM 信号,子进程将立即被杀死。

所以,我有一个关于这个的问题。 当子进程终止时,它是否也会自动关闭mysql连接? 还是应该调用 exit() 函数?

如果发送 SIGKILL,我知道子进程会保持连接。 但是,我不知道 SIGTERM 的情况。

【问题讨论】:

    标签: php mysql pdo posix child-process


    【解决方案1】:

    当一个进程完成时(无论是因为它退出还是使用信号终止),它保持打开的所有文件和连接都会被操作系统自动关闭。通过使用 MySQL 协议关闭连接(假设有一个),它不是完全关闭的。它在 TCP/IP 级别很简单,而另一端的服务器只是发现它正在与一扇紧闭的门通话。这并不总是立即发生,有时服务器会需要一些时间才能注意到讨论伙伴已经离开。发生这种情况时,它会认为连接已断开并清理其一侧的内容。

    不要在使用fork()之前在父进程中打开MySQL连接。 fork() 复制了用于管理本地连接的数据结构,结果无法预测。更重要的是,当子进程完成时(无论如何),它会关闭连接(或操作系统断开它),MySQL 服务器也会关闭它的结束,并且父进程发现它正在与任何人交谈。

    在使用 fork() 之前关闭父进程中的 MySQL 连接,然后根据需要在父进程和子进程中打开单独的连接。

    另外,将任何 MySQL 与服务器的通信包装在父进程之间:

    pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
    

    pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
    

    否则,当子进程完成时,会使用SIGCHLD 信号通知父进程。接收到的信号从睡眠中恢复(如果信号到达时它恰好在sleep() 调用中停止)。 MySQL 库使用sleep() 作为与服务器通信的 MySQL 协议的一部分。如果这样的sleep() 强制提前返回(因为接收到的信号),MySQL 库会感到困惑并最终报告实际上不正确的奇怪错误(如“MySQL 服务器已消失”)。

    详细解释请看this answer

    【讨论】:

      【解决方案2】:

      SIGKILL 从内存中删除进程而不进行任何清理。 O/S 应该清理所有打开的句柄,但它可能会发生数据库连接保持打开状态(至少在数据库注意到死连接之前)。

      不应在应用程序中使用它,而只能从控制台使用它作为最后的手段。

      您应该使用 SIGTERM 或 SIGINT 以便子进程正确退出并关闭所有打开的句柄。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-18
        • 1970-01-01
        • 2023-03-16
        • 2016-08-03
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多