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.
This commit is contained in:
parent
fdaea2a7a7
commit
e542132b07
2
src/db.c
2
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
|
* only the first time it is accessed and not in the middle of the
|
||||||
* script execution, making propagation to slaves / AOF consistent.
|
* script execution, making propagation to slaves / AOF consistent.
|
||||||
* See issue #1525 on Github for more information. */
|
* 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;
|
return now > when;
|
||||||
}
|
}
|
||||||
|
@ -3596,6 +3596,7 @@ int processCommand(client *c) {
|
|||||||
queueMultiCommand(c);
|
queueMultiCommand(c);
|
||||||
addReply(c,shared.queued);
|
addReply(c,shared.queued);
|
||||||
} else {
|
} else {
|
||||||
|
server.cmd_start_mstime = mstime();
|
||||||
call(c,CMD_CALL_FULL);
|
call(c,CMD_CALL_FULL);
|
||||||
c->woff = server.master_repl_offset;
|
c->woff = server.master_repl_offset;
|
||||||
if (listLength(server.ready_keys))
|
if (listLength(server.ready_keys))
|
||||||
|
@ -1401,6 +1401,7 @@ struct redisServer {
|
|||||||
time_t timezone; /* Cached timezone. As set by tzset(). */
|
time_t timezone; /* Cached timezone. As set by tzset(). */
|
||||||
int daylight_active; /* Currently in daylight saving time. */
|
int daylight_active; /* Currently in daylight saving time. */
|
||||||
long long mstime; /* 'unixtime' with milliseconds resolution. */
|
long long mstime; /* 'unixtime' with milliseconds resolution. */
|
||||||
|
mstime_t cmd_start_mstime;
|
||||||
/* Pubsub */
|
/* Pubsub */
|
||||||
dict *pubsub_channels; /* Map channels to list of subscribed clients */
|
dict *pubsub_channels; /* Map channels to list of subscribed clients */
|
||||||
list *pubsub_patterns; /* A list of pubsub_patterns */
|
list *pubsub_patterns; /* A list of pubsub_patterns */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user