Unverified Commit 2ad25487 authored by debing.sun's avatar debing.sun Committed by GitHub
Browse files

Fixed crashes due to missed slotToKeyInit() and missed expires_cursor reset (#13315)

this PR fixes two crashes:

1. Fix missing slotToKeyInit() when using `flushdb async` under cluster
mode.
    https://github.com/redis/redis/issues/13205

2. Fix missing expires_cursor reset when stopping active defrag in the
middle of defragment.
    https://github.com/redis/redis/issues/13307
If we stop active defrag in the middle of defragging db->expires, if
`expires_cursor` is not reset to 0, the next time we enable active
defrag again, defragLaterStep(db, ...) will be entered. However, at this
time, `db` has been reset to NULL, which results in crash.

The affected code were removed by #11695 and #13058 in usntable, so we
just need backport this to 7.2.
parent f60370ce
...@@ -941,6 +941,7 @@ void activeDefragCycle(void) { ...@@ -941,6 +941,7 @@ void activeDefragCycle(void) {
defrag_later_cursor = 0; defrag_later_cursor = 0;
current_db = -1; current_db = -1;
cursor = 0; cursor = 0;
expires_cursor = 0;
db = NULL; db = NULL;
goto update_metrics; goto update_metrics;
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "bio.h" #include "bio.h"
#include "atomicvar.h" #include "atomicvar.h"
#include "functions.h" #include "functions.h"
#include "cluster.h"
static redisAtomic size_t lazyfree_objects = 0; static redisAtomic size_t lazyfree_objects = 0;
static redisAtomic size_t lazyfreed_objects = 0; static redisAtomic size_t lazyfreed_objects = 0;
...@@ -177,6 +178,10 @@ void emptyDbAsync(redisDb *db) { ...@@ -177,6 +178,10 @@ void emptyDbAsync(redisDb *db) {
dict *oldht1 = db->dict, *oldht2 = db->expires; dict *oldht1 = db->dict, *oldht2 = db->expires;
db->dict = dictCreate(&dbDictType); db->dict = dictCreate(&dbDictType);
db->expires = dictCreate(&dbExpiresDictType); db->expires = dictCreate(&dbExpiresDictType);
if (server.cluster_enabled) {
slotToKeyDestroy(db);
slotToKeyInit(db);
}
atomicIncr(lazyfree_objects,dictSize(oldht1)); atomicIncr(lazyfree_objects,dictSize(oldht1));
bioCreateLazyFreeJob(lazyfreeFreeDatabase,2,oldht1,oldht2); bioCreateLazyFreeJob(lazyfreeFreeDatabase,2,oldht1,oldht2);
} }
......
...@@ -577,4 +577,57 @@ start_server {tags {"defrag external:skip"} overrides {appendonly yes auto-aof-r ...@@ -577,4 +577,57 @@ start_server {tags {"defrag external:skip"} overrides {appendonly yes auto-aof-r
} }
} }
} }
start_cluster 1 0 {tags {"defrag external:skip"} overrides {appendonly yes auto-aof-rewrite-percentage 0 save ""}} {
if {[string match {*jemalloc*} [s mem_allocator]] && [r debug mallctl arenas.page] <= 8192} {
test "Active defrag stability during async flush or mid stopping in cluster mode" {
# Verify that asynchronously empting db doesn't cause defragmentation crashes, see issue #13205.
r flushdb async
r config set hz 100
r config set activedefrag no
r config set active-defrag-threshold-lower 1
r config set active-defrag-cycle-min 65
r config set active-defrag-cycle-max 75
r config set active-defrag-ignore-bytes 100k
# create big keys with 10k items
set rd [redis_deferring_client]
for {set j 0} {$j < 100000} {incr j} {
$rd set $j a
$rd expire $j 99999
}
for {set j 0} {$j < 100000} {incr j} {
$rd read ; # Discard replies
$rd read ; # Discard replies
}
catch {r config set activedefrag yes} e
if {[r config get activedefrag] eq "activedefrag yes"} {
# It repeatedly enables and disables active defragmentation,
# and checks if it crashes, see issue #13307.
for {set i 0} {$i < 10} {incr i} {
r config set activedefrag no
# Wait for the active defrag to start working (decision once a second).
wait_for_condition 50 100 {
[s active_defrag_running] eq 0
} else {
after 120 ;# serverCron only updates the info once in 100ms
puts [r info memory]
puts [r memory malloc-stats]
fail "defrag didn't stop."
}
# Wait for the active defrag to stop working.
r config set activedefrag yes
wait_for_condition 50 100 {
[s active_defrag_running] ne 0
} else {
fail "defrag not started."
}
}
}
r ping
}
}
}
} ;# run_solo } ;# run_solo
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment