Issues

ZF-11640: SQLite backend fails using ":memory:" database

Issue Type: Bug Created: 2011-08-03T14:40:33.000+0000 Last Updated: 2011-08-04T17:53:22.000+0000 Status: Closed Fix version(s): - 1.11.11 (29/Sep/11)

Reporter: Sylvain Bernier (sb_demarque) Assignee: Marc Bennewitz (private) (mabe) Tags: -

Related issues: Attachments:

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.

<pre class="highlight">
$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);



<pre class="literal">
(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 :

<pre class="literal">
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)

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts