diff --git a/src/db.c b/src/db.c index 5bea8db8..a5088195 100644 --- a/src/db.c +++ b/src/db.c @@ -770,13 +770,21 @@ void propagateExpire(redisDb *db, robj *key) { } int expireIfNeeded(redisDb *db, robj *key) { - long long when = getExpire(db,key); + mstime_t when = getExpire(db,key); + mstime_t now; if (when < 0) return 0; /* No expire for this key */ /* Don't expire anything while loading. It will be done later. */ if (server.loading) return 0; + /* If we are in the context of a Lua script, we claim that time is + * blocked to when the Lua script started. This way a key can expire + * only the first time it is accessed and not in the middle of the + * script execution, making propagation to slaves / AOF consistent. + * See issue #1525 on Github for more information. */ + now = server.lua_caller ? server.lua_time_start : mstime(); + /* If we are running in the context of a slave, return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. @@ -784,12 +792,10 @@ int expireIfNeeded(redisDb *db, robj *key) { * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */ - if (server.masterhost != NULL) { - return mstime() > when; - } + if (server.masterhost != NULL) return now > when; /* Return when this key has not expired */ - if (mstime() <= when) return 0; + if (now <= when) return 0; /* Delete the key */ server.stat_expiredkeys++;