When a process terminates (either because of its exit, or with its completion using a signal), all files and connections that it keeps open are automatically closed by the operating system. It is not closed clean, using the MySQL protocol to close connections (assuming it is). It just drops at the TCP / IP level, and the server, on the other hand, just detects that it is talking with the door closed. This does not always happen instantly, sometimes it takes some time until the server notices that the discussion partner has disappeared. When this happens, he sees the connection as having fallen and cleans things on his side.
Do not open the MySQL connection in the parent process before using fork() . fork() duplicates the data structures used to control the local side of the connection, and the results are unpredictable. Moreover, when the child finishes (no matter how), it closes the connection (or the OS crashes), the MySQL server also closes its end, and the parent process discovers that it is not talking to anyone.
Close the MySQL connection in the parent process before using fork() , then open separate connections in the parent and child processes, if necessary.
Also, terminate any MySQL communication with the server in the parent process between:
pcntl_sigprocmask(SIG_BLOCK, array(SIGCHLD));
and
pcntl_sigprocmask(SIG_UNBLOCK, array(SIGCHLD));
Otherwise, when the child process ends, the parent process is notified using the SIGCHLD signal. The received signal resumes it from sleep mode (if it was stopped when sleep() was called when the signal arrived). The MySQL library uses sleep() as part of the MySQL protocol to communicate with the server. If such sleep() forced to return earlier than it should (due to the received signal), the MySQL library gets confused, and as a result, it reports strange errors (for example, "the MySQL server is gone"), which are actually incorrect.
See this answer for a detailed explanation.