mirror of
https://github.com/fluencelabs/redis
synced 2025-03-31 14:51:04 +00:00
Fix infinite loop in dbRandomKey().
Thanks to @kevinmcgehee for signaling the issue and reasoning about the consequences and potential fixes. Issue #5015.
This commit is contained in:
parent
1e92fde3d3
commit
d6e8fe77af
13
src/db.c
13
src/db.c
@ -223,6 +223,8 @@ int dbExists(redisDb *db, robj *key) {
|
|||||||
* The function makes sure to return keys not already expired. */
|
* The function makes sure to return keys not already expired. */
|
||||||
robj *dbRandomKey(redisDb *db) {
|
robj *dbRandomKey(redisDb *db) {
|
||||||
dictEntry *de;
|
dictEntry *de;
|
||||||
|
int maxtries = 100;
|
||||||
|
int allvolatile = dictSize(db->dict) == dictSize(db->expires);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
sds key;
|
sds key;
|
||||||
@ -234,6 +236,17 @@ robj *dbRandomKey(redisDb *db) {
|
|||||||
key = dictGetKey(de);
|
key = dictGetKey(de);
|
||||||
keyobj = createStringObject(key,sdslen(key));
|
keyobj = createStringObject(key,sdslen(key));
|
||||||
if (dictFind(db->expires,key)) {
|
if (dictFind(db->expires,key)) {
|
||||||
|
if (allvolatile && server.masterhost && --maxtries == 0) {
|
||||||
|
/* If the DB is composed only of keys with an expire set,
|
||||||
|
* it could happen that all the keys are already logically
|
||||||
|
* expired in the slave, so the function cannot stop because
|
||||||
|
* expireIfNeeded() is false, nor it can stop because
|
||||||
|
* dictGetRandomKey() returns NULL (there are keys to return).
|
||||||
|
* To prevent the infinite loop we do some tries, but if there
|
||||||
|
* are the conditions for an infinite loop, eventually we
|
||||||
|
* return a key name that may be already expired. */
|
||||||
|
return keyobj;
|
||||||
|
}
|
||||||
if (expireIfNeeded(db,keyobj)) {
|
if (expireIfNeeded(db,keyobj)) {
|
||||||
decrRefCount(keyobj);
|
decrRefCount(keyobj);
|
||||||
continue; /* search for another key. This expired. */
|
continue; /* search for another key. This expired. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user