since Redis 2.2.7 we introduced a new kind of dictionary (hash table)
iterator in order to reduce copy-on-write while a child is saving.
I severely underestimated the complexity of porting all the code to
the new iterator without bugs, so Redis experienced a number of bugs
starting from 2.2.7 due to misuses of the new iterator API in
different spots of the code.
The latest bug I found of this kind, hopefully the last, is
particularly critical as it is in the persistence code.
I audited this part of the code multiple times, I simply completely
overlooked the fact that the getExpire() function could contain an
assert performing a lookup, breaking the iterator semantics. So even
if this bug was never reported, Redis 2.2.7 to Redis 2.2.10 can
corrupt an .rdb database or a log rewrite, causing the same key to be
saved multiple times in the DB.
The Redis instance will have troubles loading a corrupted DB, but a
patched version of Redis able to load it can be distributed if ever
However I discovered the bug since *I run into it* myself while
performing a test with "DEBUG POPULATE".
The suggested way to upgrade the Redis instance is to save the .rdb
file, then test if the dump can be loaded correctly by another
instance, then copy this dump in a safe place and proceed with the
usual procedure you use to upgrade your Redis instance.
Sorry for this bug... I don't like this as we never had critical bugs
in Redis 1.x, 2.x, but the 2.2.x is showing a lot of bugs all due to
the same problem.
The new iterator is better and saves a lot of memory with some kind of
dataset, but this change really belonged to 2.4, not to the stable
Something I'll take in mind in the future...
Salvatore 'antirez' Sanfilippo
open source developer - VMware
"We are what we repeatedly do. Excellence, therefore, is not an act,
but a habit." -- Aristotele