I'm running PHP 5.3.3 (the latest in CentOS 6.5) as an Apache module with Prefork.
I found that an SQLite3 database will lock FOREVER until Apache is restarted, if the script runs out of time or memory in a certain way.
Reproducible test:
// Open a connection to the database.
$db = new SQLite3('/path/to/test.db');
// Get a reserved lock.
$db->exec('BEGIN IMMEDIATE TRANSACTION');
// Construct a prepared statement SQLite3Stmt object.
$st = $db->prepare('SELECT value FROM sometable WHERE key=:key');
// Emulate the script running off the rails while calling the prepared statement.
while(true)
{
$st->bindValue(':key', 1);
}
If you run this script, it runs out of execution time and/or memory, of course. From then on, however, the database is locked by the original Apache process. No script can make another reserved lock on the database until Apache is restarted.
Shouldn't PHP close the database connection when the script is terminated? Is this a bug in PHP? Would it be solved by running it as a FastCGI process?
Internally, SQLite uses a POSIX advisory lock on the database file.
The operating system will clean up this lock when the process exits. However, as long as the Apache process that has an active transaction is still running, this lock remains.
If you have misbehaving scripts, you should run them in a way where aborting them kills the entire process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With