ZF-11640: SQLite backend fails using ":memory:" database
Description
With default "automatic_cleaning_factor" (10, from Core) and "automatic_vacuum_factor" (10, from Backend_Sqlite), the SQLite cache backend, using in-memory databases (":memory:") will fail 1 time out of 100 (100 = 10 * 10, 1%) when attempting a "clean()" operation.
$failures = 0; $attempts = 100000;
foreach (range(1, $attempts) as $i) {
$cache = Zend_Cache::factory(
'Core', 'Sqlite',
array(),
array('cache_db_complete_path' => ':memory:') // in-memory database
);
$success = $cache->save('cache_data', $id = 'cache_id');
$failures += ($success ? 0 : 1);
}
printf('Failures: %d (%.1f %%)', $failures, ($failures / $attempts) * 100);
(100000 attempts) Failures: 1008 (1.0 %)
The problem comes from Sqlite::_automaticVacuum(), where a call to "sqlite_close()" will remove all tables from the database, but the value of "$this->_structureChecked", set by "$this->_checkAndBuildStructure()", in "clean()" (previous to the "automaticVacuum" call), *will still be "true"*. So the SQLite backend will re-open a new connection, but the *tables will not be created again*. Thus the occasional "table not found" errors while "_query()"ing, 1 time out of 100.
Disabling automatic vacuum "patches" the immediate problem, but a real fix would look a little bit more like this :
diff --git a/Zend/Cache/Backend/Sqlite.php b/Zend/Cache/Backend/Sqlite.php
index 5b964a1..427f13d 100644
--- a/Zend/Cache/Backend/Sqlite.php
+++ b/Zend/Cache/Backend/Sqlite.php
@@ -68,7 +68,7 @@ class Zend_Cache_Backend_Sqlite extends Zend_Cache_Backend implements Zend_Cache
private $_db = null;
/**
- * Boolean to store if the structure has benn checked or not
+ * Boolean to store if the structure has been checked or not
*
* @var boolean $_structureChecked
*/
@@ -531,6 +531,7 @@ class Zend_Cache_Backend_Sqlite extends Zend_Cache_Backend implements Zend_Cache
if ($rand == 1) {
$this->_query('VACUUM');
@sqlite_close($this->_getConnection());
+ $this->_structureChecked = false;
}
}
}
(Sorry about the in-line patch, could not figure out how to attach it and the Contributors Guide was down.)
Comments
Posted by Marc Bennewitz (private) (mabe) on 2011-08-04T17:53:22.000+0000
There is no need to close db connection after VACUUM
fixed in r24347 (trunk) and r24348 (1.11 branch)