From a26774cee10dcb002d62371e3d01be5e14cff9af Mon Sep 17 00:00:00 2001 From: Benson-li <46148313+li-benson@users.noreply.github.com> Date: Thu, 20 Mar 2025 21:32:12 +0800 Subject: [PATCH] Fix potential infinite loop of RANDOMKEY during client pause (#13863) The bug mentioned in this [#13862](https://github.com/redis/redis/issues/13862) has been fixed. --------- Signed-off-by: li-benson <1260437731@qq.com> Signed-off-by: youngmore1024 Co-authored-by: youngmore1024 --- src/db.c | 2 +- tests/unit/pause.tcl | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/db.c b/src/db.c index 8f9a436b4..58aa2eab5 100644 --- a/src/db.c +++ b/src/db.c @@ -333,7 +333,7 @@ robj *dbRandomKey(redisDb *db) { key = dictGetKey(de); keyobj = createStringObject(key,sdslen(key)); if (dictFind(db->expires,key)) { - if (allvolatile && server.masterhost && --maxtries == 0) { + if (allvolatile && (server.masterhost || isPausedActions(PAUSE_ACTION_EXPIRE)) && --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 diff --git a/tests/unit/pause.tcl b/tests/unit/pause.tcl index e30f922e6..5f4e92cae 100644 --- a/tests/unit/pause.tcl +++ b/tests/unit/pause.tcl @@ -359,6 +359,26 @@ start_server {tags {"pause network"}} { } {bar2} } + test "Test the randomkey command will not cause the server to get into an infinite loop during the client pause write" { + r flushall + + r multi + r set key value px 3 + r client pause 10000 write + r exec + + after 5 + + wait_for_condition 50 100 { + [r randomkey] == "key" + } else { + fail "execute randomkey failed, caused by the infinite loop" + } + + r client unpause + assert_equal [r randomkey] {} + } + # Make sure we unpause at the end r client unpause }