PHP OCI8 Signal Handling and --enable-sigchild
By cj on Mar 23, 2009
I am no longer blindly recommending using --enable-sigchild when configuring PHP with the OCI8 extension. I used to do this as a catch-all. It might have saved some users grief, and did little harm. With changes in recent versions of Oracle and my gut feel about common usage, it will be less confusing not to mention it as a general suggestion.
Excuse me only offering guidelines here and not a definitive best-practice: signal handling is port specific; there are many ways to configure PHP; there is much choice in which extensions to include; and there are many different web servers that PHP can run under.
The old heuristic for OCI8 users was to configure PHP with --enable-sigchild if you saw defunct Oracle server processes - the process that handle the work for each connected user. Each PHP process communicates with its own server process.
There are some side effects with --enable-sigchild. On my OS I know pclose() returns failure; several PHP bug reports exist for this and PHP code has been patched and broken (?) in this area.
My New --enable-sigchild Usage Heuristic:
Only if you see defunct "zombie" Oracle server processes then start PHP/Apache with the Oracle Net option BEQUEATH_DETACH=YES in your sqlnet.ora, or, to keep the setting specific to PHP, set your environment starting Apache:
If this doesn't help, then consider building PHP with --enable-sigchild.
Defunct processes might happen if the Oracle code in PHP forks the Oracle server process (called "bequeathing") and the signal handlers in PHP, as the parent of the server process, do not correctly clean up the server process when a database connection is closed. The BEQUEATH_DETACH=YES option causes the server processes to do a double fork and be inherited by "init", which prevents defunct zombies. Oracle 10g onwards check for signal handler clashes and automatically turn on BEQUEATH_DETACH, reducing the need for you to set it. It's not on by default because it adds a few extra CPU cycles and the OS parent process id becomes 1, making it slightly harder to identify the relationship between a server process and the application process using it. You might need to manually set it on if signal handlers are changed after Oracle has done its heuristic check.
You should never need to configure PHP with --enable-sigchild or set BEQUEATH_DETACH=YES if PHP is "remote" from the DB server. PHP can be "remote" physically or because PHP is linked with Oracle Instant Client or linked with different Oracle libraries to those used by the DB - where you use an Easy Connect or tnsnames.ora connection string. You also don't need to change signal handling if you use Shared (MTS) or Pooled Oracle servers. These are the cases where PHP does not fork the Oracle server process directly. The Oracle Net listener does the forking instead and PHP's signal handling won't affect Oracle server process cleanup.
So the new heuristic is the same as the old heuristic. But the suggested remedy is different, and I feel the frequency of seeing zombies is low because of the uptake in improved versions of Oracle and because of the common separation of the PHP mid-tier from the database servers.
Customers with metalink.oracle.com accounts might care to look at Note 452122.1, "The use of Client signal handlers and Oracle BEQUEATH Connections" which explains more about BEQUEATH_DETACH and forking.
Let me know your experiences.