Closed (fixed)
Project:
Memcache API and Integration
Version:
5.x-1.x-dev
Component:
Code
Priority:
Critical
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
1 Oct 2007 at 11:24 UTC
Updated:
26 Mar 2008 at 00:52 UTC
In the cache_get function, there is this section...
// If we have a memcache hit for this, return it.
if ($cache = dmemcache_get($key, $table)) {
return $cache;
}
... which checks if the cache item is in memcache. Thing is, the $cache->data MIGHT be serialized... Therefore you need to change this to:
// If we have a memcache hit for this, return it.
if ($cache = dmemcache_get($key, $table)) {
if ($cache->serialized) {
$cache->data = unserialize($cache->data);
}
return $cache;
}
... Otherwise Drupal complains about arrays not being arrays and so on...
Comments
Comment #1
robertdouglass commented$cache->data should never need to be serialized when coming from memcache. If this is the case then the application code has an unbalanced serialize/unserialize pair... ie the application code is serializing but not unserializing.
The case you refer to is only for database storage. We still serialize objects and arrays when using memcache.db.inc and putting items in database cache. The case for these is covered, though, because if data comes back from the db it gets unserialized.
Please check your application logic or describe better the cases where you're running into problems.
Comment #2
nicholasthompsonHmmm... Well I used a recursive GREP search to find all cases of cache_set and I couldn't see any which were passing their data in a serialized form (same process for cache_get too).
I believe this method is more sensible (you pass an object/array/string/int or whatever else you like into cache_set/get and the cache layer handles the data-type conversions).
My issues were that on a clean load everything was coming out fine. If I disabled my memcache (eg by killing the daemon) then pages all loaded fine (albeit slower). If I restarted the memcache daemon and emptied cache then the page loaded fine (from a clean load) however upon the next load there would be things missing, for example the body of a node (which I think failed due to an un-serialization of non-serialized data coming out of the memcache). I also had issues with blocks not coming out at all (I'm also using block_cache).
I found that by checking the serialization value of an object upon memcache extraction the issues I was having just went away...
Comment #3
robertdouglass commentedI think I'm starting to understand. You're talking specifically about the case where the db cache is populated but memcache has gone offline and then back online, and the db serves the cache but cache_get also calls cache_set (with no db storage flag) to populate memcache, and on the next load, memcache server the cache request but it is broken due to serialization errors. I'll look into that.
Comment #4
nicholasthompsonThat sounds SPOT on!
I can confirm that adding the "if ($cache->serialized)" check fixes the issues - the dev version of our site is running without issue now...
Comment #5
slantview commentedThis scenario can never happen. Even if it were to grab the data from the db, it will unserialize it and only saves it back to memcache after it has been unserialized.