summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2019-11-04 20:32:19 +0800
committerantirez <antirez@gmail.com>2019-11-05 09:56:39 +0100
commite542132b07a76c73cd5e1dd067671afbb4c53fe6 (patch)
treec86aeaeb0245a8390c29eb578223a4c895b4da06
parentfdaea2a7a7eed1499f46bb98552f8d8bb8dc7e9d (diff)
downloadredis-e542132b07a76c73cd5e1dd067671afbb4c53fe6.tar.gz
expires: refactoring judgment about whether a key is expired
Calling lookupKey*() many times to search a key in one command may get different result. That's because lookupKey*() calls expireIfNeeded(), and delete the key when reach the expire time. So we can get an robj before the expire time, but a NULL after the expire time. The worst is that may lead to Redis crash, for example `RPOPLPUSH foo foo` the first time we get a list form `foo` and hold the pointer, but when we get `foo` again it's expired and deleted. Now we hold a freed memory, when execute rpoplpushHandlePush() redis crash. To fix it, we can refactor the judgment about whether a key is expired, using the same basetime `server.cmd_start_mstime` instead of calling mstime() everytime.
-rw-r--r--src/db.c2
-rw-r--r--src/server.c1
-rw-r--r--src/server.h1
3 files changed, 3 insertions, 1 deletions
diff --git a/src/db.c b/src/db.c
index 2c0a0cdd3..1a272faae 100644
--- a/src/db.c
+++ b/src/db.c
@@ -1199,7 +1199,7 @@ int keyIsExpired(redisDb *db, robj *key) {
* 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. */
- mstime_t now = server.lua_caller ? server.lua_time_start : mstime();
+ mstime_t now = server.lua_caller ? server.lua_time_start : server.cmd_start_mstime;
return now > when;
}
diff --git a/src/server.c b/src/server.c
index 8f165113d..99438ccac 100644
--- a/src/server.c
+++ b/src/server.c
@@ -3596,6 +3596,7 @@ int processCommand(client *c) {
queueMultiCommand(c);
addReply(c,shared.queued);
} else {
+ server.cmd_start_mstime = mstime();
call(c,CMD_CALL_FULL);
c->woff = server.master_repl_offset;
if (listLength(server.ready_keys))
diff --git a/src/server.h b/src/server.h
index f724f7d64..08eb2eef9 100644
--- a/src/server.h
+++ b/src/server.h
@@ -1401,6 +1401,7 @@ struct redisServer {
time_t timezone; /* Cached timezone. As set by tzset(). */
int daylight_active; /* Currently in daylight saving time. */
long long mstime; /* 'unixtime' with milliseconds resolution. */
+ mstime_t cmd_start_mstime;
/* Pubsub */
dict *pubsub_channels; /* Map channels to list of subscribed clients */
list *pubsub_patterns; /* A list of pubsub_patterns */