From: kenny at kennynet dot co dot uk
Operating system: Debian
PHP version: 5.5.15
Package: FPM related
Bug Type: Bug
Bug description:php-fpm: repeatedly spinning many many workers
Description:
------------
After php5-fpm has been running for an amount of time we start to see
log messages spinning round rapidly many many times of second of the
form:-
"""
[06-Aug-2014 12:18:46] NOTICE: [pool pool-1] child 10141 started
[06-Aug-2014 12:18:46] NOTICE: [pool pool-1] child 9764 exited with code
0 after 0.567466 seconds from start
"""
(A side effect of this is that the scoreboard is updated with "idle++"
but if no work is processed that idle counter is never decremented so it
continues to increase)
Attaching gdb and following the fork to the child one can observe that
the accept() call in fcgi_accept_request() returns -1 with errno=EAGAIN.
A result expected from non-blocking sockets but not blocking sockets,
further:-
gdb> print fcntl(listen_socket, 3)
... 2050
Which is O_RDWR | O_NONBLOCK.
So it appears that *somehow* the listen_socket is being put into
non-blocking mode and hence:-
* The loop around fcgi_accept_request() aborts immediately with
exit_status=0.
* The child subsequently exits.
* fpm_children_bury() processes this as restart_child=1
* Round and round it goes spinning up new new children which exit
immediately if there is nothing to accept().
As a test / proof of the above this is fixed by:-
gdb> print fcntl(listen_socket, 4, fcntl(listen_socket, 3) &~ 04000)
... 0
Well, fixed until the next time the socket somehow gets put into
non-blocking mode, I've not yet managed to isolate exactly how that is
happening.
Test script:
---------------
N/A
Expected result:
----------------
N/A
Actual result:
--------------
N/A
--
Edit bug report at https://bugs.php.net/bug.php?id=67796&edit=1
--