For our recent project, we're experimenting with the performance and advantages/disadvantages of different cache backends... again. We're running Magento on multiple servers and so there's always the additional issue if every node should have its own caches, or if they should share a common one (or if they have a local 1st-level cache and a shared 2nd-level cache, or ...).
2-Level-Caching is not bugfree (I've posted that before and filed a patch to Magento's contributors repository before).
Today I've struggled with the database cache backend. And that's a big mess:
Cleaning old cache entries
Magento does not care about cache entries whose lifetime has expired. This is not specific to the database cache backend, but valid for all types of caches leading to exploding database tables or directory sizes. I've created a module that takes care of that and will run Zend Framework's "clear old cache" method regularly in a scheduler task.
Problem is, that the database cache backend's clean old entries method has invalid sql statements. (Showing me, that noone has ever tested that before). I've fixed that some time ago (by adding some "?" to the correct position) and committed that to the contributor's repository. That patch was accepted and found its way into the current Community Edition 188.8.131.52, but it has not arrived to the Enterprise Version 1.11. Not even to the version 184.108.40.206 that was released a couple of days ago.
This leads me to the question: What other (important) patches have not been added to the corresponding Enterprise Edition, and why?
So I patched the sources and ran into another problem:
Enterprise Edition needs redundant cache configuration
If you won't configure the full_page_cache in the local.xml file seperatly (all option as in
The database cache backend supports tagging. In theory. Currently the whole cache backend will throw errors because of a bug with a foreign key constraint in the table _core_cachetag to the table _corecache.
This foreign key contraint was introduced in _app/code/core/Mage/Core/sql/coresetup/mysql4-upgrade-0.8.21-0.8.22.php some time ago and had the name _FK_CORE_CACHETAG. It was supposed to take care of clearing attached tags when a cache entry was deleted. That's why there is no php code taking care of deleting the records in the _core_cachetag table.
Some time later someone has noticed that this foreign key contraint did not work as expected and removed that constraint using the update script _app/code/core/Mage/Core/sql/coresetup/mysql4-upgrade-0.8.26-0.8.27.php.
Fair enough, at least the database backend started working again. But there was still no code taking care of emptying the tags leading into increasing table sizes.
I've created a patch that handles tag record deletion in php. This fixed the problem of tags and allowed to use the database cache backend in production again.
... and the story goes on ...
But then - with version 220.127.116.11 (valid for the community and the enterprise edition) the foreign key contraint was added again in the update script _app/code/core/Mage/Core/sql/coresetup/install-18.104.22.168.php. In the meantime the installer method "getFkName()" was added so the new foreign key got a new name: _FK_CORE_CACHE_TAG_CACHE_ID_CORE_CACHEID instead of _FK_CORE_CACHE_TAG. _Check your databases and you'll find this key in the core_cache_tag table. That of course is not deleted by the update script mysql4-upgrade-0.8.26-0.8.27.php and brings up the same errors they had before removing the key.
So, what now?
You could follow until here? Great! If you really want to use the database cache backend...
- remove those useless and buggy foreign key constraints:
alter table core_cache_tag drop FOREIGN KEY FK_CORE_CACHE_TAG; alter table core_cache_tag drop FOREIGN KEY FK_CORE_CACHE_TAG_CACHE_ID_CORE_CACHE_ID;
or put this in a update script:
$installer->getConnection()->dropForeignKey($installer->getTable('core/cache_tag'), $installer->getFkName('core/cache_tag', 'cache_id', 'core/cache', 'id'));
- have the sql statements in the _Varien_Cache_BackendDatabase->clean() fixed if your're using the Enterprise Edition. (The Community Edition has this patched already). Check this patch.
- add support for cleaning tags to prevent the _core_cachetag table from exploding. Check this patch.
- take care of cleaning old cache entries (that's not restricted to the database backend but valid for all backends). This module takes care of that.
Other foreign key names have also changed in the latest version of Magento, because they are being created using the getFkName() method that returns names using a different convention than before. This might break other parts aswell and will definitly break something if keys had been removed or modified before (or in your modules). We should keep an eye on that and alwys remove foreign keys using both the old and the new name to make sure they're really dropped.
- Magento Two-Level-Caching
- Magento Automatic Cache Cleaner
- Magento Asynchronous Cache
- Meet Magento #5 2011: Performance durch Caching
- Magento Caching Internals
- Magento / Zend Framework's TwoLevels Cache Backend Mess