When troubleshooting long-running database or network connections in Apache HTTPD processes, identifying the responsible PHP scripts becomes crucial. Here's a comprehensive approach for Linux systems:
sudo strace -p $(pgrep -f 'httpd|apache2' | head -1) -s 200 -e trace=file
This command will show file operations including PHP script execution. Look for lines containing ".php" in the output.
ps auxf | grep 'hp'
ps -ef | grep '[a]pache2' | awk '{print $2}' | xargs -I{} sh -c 'echo {}; lsof -p {}'
The second command shows open files for each Apache process, often revealing the executed script.
Enable mod_status in your Apache configuration:
<Location "/server-status">
SetHandler server-status
Require host localhost
</Location>
Then access http://localhost/server-status?notable to see current requests.
For PHP-FPM setups, check the process status:
sudo /path/to/php-fpm -tt
sudo kill -USR2 $(cat /var/run/php-fpm.pid)
This will generate a status report showing active scripts.
Combine netstat with process inspection:
sudo netstat -tnp | grep ':3306' | awk '{print $7}' | cut -d'/' -f1 | xargs -I{} sh -c 'echo -n "PID {}: "; ps -p {} -o cmd='
Create a monitoring script:
#!/bin/bash
while true; do
for pid in $(pgrep 'httpd|apache2'); do
script=$(lsof -p $pid | grep \.php | awk '{print $9}')
[ -z "$script" ] || echo "$(date) - PID $pid: $script"
done
sleep 5
done
When debugging persistent database connections or network sockets in Apache HTTPD, it's crucial to identify which specific PHP scripts are responsible. This typically occurs when you notice certain processes holding resources longer than expected through tools like netstat
or ss
.
The most direct approach combines ps
and lsof
to pinpoint scripts:
# Find Apache processes running PHP ps aux | grep 'httpd\|apache2' | grep php # Then inspect a specific process (replace PID) lsof -p PID | grep '\.php'
For batch processing all Apache processes:
for pid in $(pgrep -f 'httpd|apache2'); do echo "Process $pid:"; lsof -p $pid | grep '\.php' | awk '{print $9}'; done
When you need to catch scripts as they execute:
strace -f -p $(pgrep -f 'httpd|apache2') 2>&1 | grep -E 'open.*\.php'
This outputs PHP files as they're accessed by Apache threads.
If using PHP-FPM, check the process status:
sudo /path/to/php-fpm -tt
Or query the status page (when configured):
curl http://localhost/status | grep 'script:'
For complex environments, SystemTap provides script-level visibility:
probe process("libphp7.so").function("zend_execute_scripts") { printf("PID %d executing: %s\n", pid(), user_string($filename)) }
Save as php_scripts.stp
and run with stap
.
To specifically trace database-holding scripts:
# MySQL connections lsof -i :3306 | grep 'httpd\|apache2' | awk '{print $2}' | xargs -I {} lsof -p {} | grep '\.php'
Here's how we traced a persistent MySQL connection:
- Identified hanging connection with
mysqladmin processlist
- Found Apache PID with
lsof -i :3306
- Located script:
lsof -p 28421 | grep '\.php'
- Discovered missing
mysql_close()
in legacy code
- Implement PHP's
register_shutdown_function()
for resource cleanup - Use connection pooling where available
- Set reasonable timeouts in php.ini:
mysql.connect_timeout = 5 default_socket_timeout = 60