diff options
author | Viktor Söderqvist <viktor.soderqvist@est.tech> | 2022-02-22 11:09:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-22 12:09:46 +0200 |
commit | e9ae03787e0a2e0484914737f82bfe216f8e9d52 (patch) | |
tree | 3294c22330518bf2b5681411b36ae042ad32bdcf /tests | |
parent | 47c51d0c7858dc8ce7747b78b73cf8cec2e59ff3 (diff) | |
download | redis-e9ae03787e0a2e0484914737f82bfe216f8e9d52.tar.gz |
Delete key doesn't dirty client who watched stale key (#10256)
When WATCH is called on a key that's already logically expired, avoid discarding the
transaction when the keys is actually deleted.
When WATCH is called, a flag is stored if the key is already expired
at the time of watch. The expired key is not deleted, only checked.
When a key is "touched", if it is deleted and it was already expired
when a client watched it, the client is not marked as dirty.
Co-authored-by: Oran Agra <oran@redislabs.com>
Co-authored-by: zhaozhao.zz <zhaozhao.zz@alibaba-inc.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/multi.tcl | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/tests/unit/multi.tcl b/tests/unit/multi.tcl index 8a0b731d5..70e33b74b 100644 --- a/tests/unit/multi.tcl +++ b/tests/unit/multi.tcl @@ -147,6 +147,45 @@ start_server {tags {"multi"}} { r debug set-active-expire 1 } {OK} {needs:debug} + test {WATCH stale keys should not fail EXEC} { + r del x + r debug set-active-expire 0 + r set x foo px 1 + after 2 + r watch x + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {needs:debug} + + test {Delete WATCHed stale keys should not fail EXEC} { + r del x + r debug set-active-expire 0 + r set x foo px 1 + after 2 + r watch x + # EXISTS triggers lazy expiry/deletion + assert_equal 0 [r exists x] + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {needs:debug} + + test {FLUSHDB while watching stale keys should not fail EXEC} { + r del x + r debug set-active-expire 0 + r set x foo px 1 + after 2 + r watch x + r flushdb + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {needs:debug} + test {After successful EXEC key is no longer watched} { r set x 30 r watch x @@ -245,6 +284,52 @@ start_server {tags {"multi"}} { r exec } {} {singledb:skip} + test {SWAPDB does not touch watched stale keys} { + r flushall + r select 1 + r debug set-active-expire 0 + r set x foo px 1 + after 2 + r watch x + r swapdb 0 1 ; # expired key replaced with no key => no change + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {singledb:skip needs:debug} + + test {SWAPDB does not touch non-existing key replaced with stale key} { + r flushall + r select 0 + r debug set-active-expire 0 + r set x foo px 1 + after 2 + r select 1 + r watch x + r swapdb 0 1 ; # no key replaced with expired key => no change + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {singledb:skip needs:debug} + + test {SWAPDB does not touch stale key replaced with another stale key} { + r flushall + r debug set-active-expire 0 + r select 1 + r set x foo px 1 + r select 0 + r set x bar px 1 + after 2 + r select 1 + r watch x + r swapdb 0 1 ; # no key replaced with expired key => no change + r multi + r ping + assert_equal {PONG} [r exec] + r debug set-active-expire 1 + } {OK} {singledb:skip needs:debug} + test {WATCH is able to remember the DB a key belongs to} { r select 5 r set x 30 |