mirror of
https://github.com/redis/redis.git
synced 2026-01-10 12:58:13 -05:00
This PR is based on https://github.com/valkey-io/valkey/pull/1303 This PR introduces a DEBUG_DEFRAG compilation option that enables activedefrag functionality even when the allocator is not jemalloc, and always forces defragmentation regardless of the amount or ratio of fragmentation. ## Using ``` make SANITIZER=address DEBUG_DEFRAG=<force|fully> ./runtest --debug-defrag ``` * DEBUG_DEFRAG=force * Ignore the threshold for defragmentation to ensure that defragmentation is always triggered. * Always reallocate pointers to probe for correctness issues in pointer reallocation. * DEBUG_DEFRAG=fully * Includes everything in the option `force`. * Additionally performs a full defrag on every defrag cycle, which is significantly slower but more accurate. --------- Co-authored-by: Ran Shidlansik <ranshid@amazon.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: oranagra <oran@redislabs.com>
102 lines
4.4 KiB
Tcl
102 lines
4.4 KiB
Tcl
set testmodule [file normalize tests/modules/defragtest.so]
|
|
|
|
start_server {tags {"modules external:skip debug_defrag:skip"} overrides {{save ""}}} {
|
|
r module load $testmodule
|
|
r config set hz 100
|
|
r config set active-defrag-ignore-bytes 1
|
|
r config set active-defrag-threshold-lower 0
|
|
r config set active-defrag-cycle-min 99
|
|
|
|
# try to enable active defrag, it will fail if redis was compiled without it
|
|
catch {r config set activedefrag yes} e
|
|
if {[r config get activedefrag] eq "activedefrag yes"} {
|
|
|
|
test {Module defrag: simple key defrag works} {
|
|
r config set activedefrag no
|
|
wait_for_condition 100 50 {
|
|
[s active_defrag_running] eq 0
|
|
} else {
|
|
fail "Unable to wait for active defrag to stop"
|
|
}
|
|
|
|
r flushdb
|
|
r frag.resetstats
|
|
r frag.create key1 1 1000 0
|
|
|
|
r config set activedefrag yes
|
|
wait_for_condition 200 50 {
|
|
[getInfoProperty [r info defragtest_stats] defragtest_defrag_ended] > 0
|
|
} else {
|
|
fail "Unable to wait for a complete defragmentation cycle to finish"
|
|
}
|
|
|
|
set info [r info defragtest_stats]
|
|
assert {[getInfoProperty $info defragtest_datatype_attempts] > 0}
|
|
assert_equal 0 [getInfoProperty $info defragtest_datatype_resumes]
|
|
assert_morethan [getInfoProperty $info defragtest_datatype_raw_defragged] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
} {} {tsan:skip}
|
|
|
|
test {Module defrag: late defrag with cursor works} {
|
|
r config set activedefrag no
|
|
wait_for_condition 100 50 {
|
|
[s active_defrag_running] eq 0
|
|
} else {
|
|
fail "Unable to wait for active defrag to stop"
|
|
}
|
|
|
|
r flushdb
|
|
r frag.resetstats
|
|
|
|
# key can only be defragged in no less than 10 iterations
|
|
# due to maxstep
|
|
r frag.create key2 10000 100 1000
|
|
|
|
r config set activedefrag yes
|
|
wait_for_condition 1000 50 {
|
|
[getInfoProperty [r info defragtest_stats] defragtest_defrag_ended] > 0 &&
|
|
[getInfoProperty [r info defragtest_stats] defragtest_datatype_resumes] > 10
|
|
} else {
|
|
fail "Unable to wait for a complete defragmentation cycle to finish"
|
|
}
|
|
|
|
set info [r info defragtest_stats]
|
|
assert_equal 0 [getInfoProperty $info defragtest_datatype_wrong_cursor]
|
|
assert_morethan [getInfoProperty $info defragtest_datatype_raw_defragged] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
} {} {tsan:skip}
|
|
|
|
test {Module defrag: global defrag works} {
|
|
r config set activedefrag no
|
|
wait_for_condition 100 50 {
|
|
[s active_defrag_running] eq 0
|
|
} else {
|
|
fail "Unable to wait for active defrag to stop"
|
|
}
|
|
|
|
r flushdb
|
|
r frag.resetstats
|
|
r frag.create_frag_global 50000
|
|
r config set activedefrag yes
|
|
|
|
wait_for_condition 1000 50 {
|
|
[getInfoProperty [r info defragtest_stats] defragtest_defrag_ended] > 0
|
|
} else {
|
|
fail "Unable to wait for a complete defragmentation cycle to finish"
|
|
}
|
|
|
|
set info [r info defragtest_stats]
|
|
assert {[getInfoProperty $info defragtest_global_strings_attempts] > 0}
|
|
assert {[getInfoProperty $info defragtest_global_dicts_attempts] > 0}
|
|
assert {[getInfoProperty $info defragtest_global_dicts_defragged] > 0}
|
|
assert {[getInfoProperty $info defragtest_global_dicts_items_defragged] > 0}
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_started] 0
|
|
assert_morethan [getInfoProperty $info defragtest_defrag_ended] 0
|
|
assert_morethan [getInfoProperty $info defragtest_global_dicts_resumes] [getInfoProperty $info defragtest_defrag_ended]
|
|
assert_morethan [getInfoProperty $info defragtest_global_subdicts_resumes] [getInfoProperty $info defragtest_defrag_ended]
|
|
} {} {tsan:skip}
|
|
}
|
|
}
|