diff options
author | antirez <antirez@gmail.com> | 2010-09-07 13:16:39 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2010-09-07 13:16:39 +0200 |
commit | 521cdafafef93cd277a77100d596b861b773505b (patch) | |
tree | 2088ab628517113b82955c97f17e95083f2f8102 | |
parent | 00a90feb0b3dabfab683875ae7d907f1e39cd80e (diff) | |
download | redis-521cdafafef93cd277a77100d596b861b773505b.tar.gz |
avoid actively expiring keys in the cron loop if this keys are being swapped or loaded. This avoids a rare race condition
-rw-r--r-- | redis.c | 11 |
1 files changed, 11 insertions, 0 deletions
@@ -1515,10 +1515,21 @@ static int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientD num = REDIS_EXPIRELOOKUPS_PER_CRON; while (num--) { dictEntry *de; + robj *key; time_t t; if ((de = dictGetRandomKey(db->expires)) == NULL) break; t = (time_t) dictGetEntryVal(de); + key = dictGetEntryKey(de); + /* Don't expire keys that are in the contest of I/O jobs. + * Otherwise decrRefCount will kill the I/O thread and + * clients waiting for this keys will wait forever. + * + * In general this change will not have any impact on the + * performance of the expiring algorithm but it's much safer. */ + if (server.vm_enabled && + (key->storage == REDIS_VM_SWAPPING || + key->storage == REDIS_VM_LOADING)) continue; if (now > t) { deleteKey(db,dictGetEntryKey(de)); expired++; |