Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort out the mess around writable replicas and lookupKeyRead/Write #9572

Merged
merged 24 commits into from
Nov 28, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c09c811
Sort out the mess around writable replicas and lookupKeyRead/Write
zuiderkwast Sep 30, 2021
c002931
Apply suggestions from code review
zuiderkwast Oct 7, 2021
49b2c48
Fixup: Review suggestions
zuiderkwast Oct 11, 2021
710e9d9
Fixup: Add assert in expireIfNeeded
zuiderkwast Oct 11, 2021
ef55207
Fixup: spelling typo
zuiderkwast Oct 11, 2021
068e7a1
Fixup: Modules test commands marked as readonly
zuiderkwast Oct 11, 2021
562b96f
Fixup: Make COPY use plain lookupKeyRead()
zuiderkwast Oct 11, 2021
3b1e307
Fix the assert in expireIfNeeded for eval and debug loadaof + stuff
zuiderkwast Oct 14, 2021
6f01fb0
Add test cases
zuiderkwast Oct 14, 2021
32a7045
Add WRITE flag to all test module write commands
zuiderkwast Oct 14, 2021
cca77ac
Fix review comments
zuiderkwast Oct 21, 2021
a439aa9
Merge remote-tracking branch 'redis/unstable' into writable-replicas
zuiderkwast Oct 21, 2021
aecc32c
Attemt to fix failing test
zuiderkwast Oct 22, 2021
34d1119
Review comments
zuiderkwast Oct 25, 2021
260c454
Fixup: Update test wait timeout messages
zuiderkwast Oct 26, 2021
c78d43e
Delete the LOOKUP_NOEXPIRE flag
zuiderkwast Nov 3, 2021
0ee4d68
Never consider keys expired when client is the master
zuiderkwast Nov 3, 2021
623ca03
Use dictFind instead of lookupKey in scanDatabaseForReadyLists (db.c)
zuiderkwast Nov 4, 2021
323dffc
Add test cases for SWAPDB with blocked client and replication of expi…
zuiderkwast Nov 4, 2021
f5def78
Fix review comments on test cases
zuiderkwast Nov 4, 2021
ae46106
Rename expire_on_replica to force_delete_expired + fix another comment
zuiderkwast Nov 24, 2021
d091ef9
Merge remote-tracking branch 'redis/unstable' into writable-replicas
zuiderkwast Nov 24, 2021
ef10a77
Restore deleted parts of expireIfNeeded comment
zuiderkwast Nov 24, 2021
34676f9
Sleep one extra millisecond in test case
zuiderkwast Nov 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,7 @@ int expireIfNeeded(redisDb *db, robj *key, int expire_on_replica) {
* commands. */
if (expire_on_replica) {
oranagra marked this conversation as resolved.
Show resolved Hide resolved
client *c = server.in_eval ? server.lua_client : server.current_client;
serverAssert(!c || !c->cmd || (c->cmd->flags & CMD_WRITE));
serverAssert(!c || !c->cmd || (c->cmd->flags & (CMD_WRITE|CMD_MODULE)));
zuiderkwast marked this conversation as resolved.
Show resolved Hide resolved
}

if (!keyIsExpired(db,key)) return 0;
Expand Down
9 changes: 8 additions & 1 deletion src/hyperloglog.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,14 @@ void pfcountCommand(client *c) {
/* Case 2: cardinality of the single HLL.
*
* The user specified a single key. Either return the cached value
* or compute one and update the cache. */
* or compute one and update the cache.
*
* Since a HLL is a regular Redis string type value, updating the cache does
* modify the value. We do a lookupKeyRead anyway since this is flagged as a
* read-only command. The difference is that with lookupKeyWrite, a
* logically expired key on a replica is deleted, while with lookupKeyRead
* it isn't, but the lookup returns NULL either way if the key is logically
* expired, which is what matters here. */
o = lookupKeyRead(c->db,c->argv[1]);
zuiderkwast marked this conversation as resolved.
Show resolved Hide resolved
if (o == NULL) {
/* No key? Cardinality is zero since no element was added, otherwise
Expand Down
77 changes: 42 additions & 35 deletions tests/integration/replication-3.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -57,61 +57,68 @@ start_server {tags {"repl external:skip"}} {
} {0}

test {Writable replica doesn't return expired keys} {
r select 5
assert {[r dbsize] == 0}
r debug set-active-expire 0
r set key1 5 px 10
r set key2 5 px 10
r -1 select 5
assert {[r -1 dbsize] == 0}
wait_for_condition 50 100 {
[r -1 dbsize] == 2
} else {
fail "Replication timeout."
zuiderkwast marked this conversation as resolved.
Show resolved Hide resolved
}
after 10
r -1 config set slave-read-only no
r -1 debug set-active-expire 0
r -1 set key1 5 px 10
r -1 set key2 5 px 10
after 50
assert_equal 2 [r -1 dbsize] ; # active expire is off
assert_equal 1 [r -1 incr key1] ; # incr expires and re-creates key1
assert_equal -1 [r -1 ttl key1] ; # incr created key1 without TTL
assert_equal {} [r -1 get key2] ; # key2 expired but not deleted
assert_equal 2 [r -1 dbsize]
# cleanup
r debug set-active-expire 1
r -1 del key1 key2
r -1 debug set-active-expire 1
r -1 dbsize
} {0}
r -1 config set slave-read-only yes
r del key1 key2
}

test {PFCOUNT updates cache on readonly replica} {
r select 5
assert {[r dbsize] == 0}
r pfadd key a b c d e f g h i j k l m n o p q
set strval [r get key]
r -1 select 5
assert {[r -1 dbsize] == 0}
r -1 config set slave-read-only no
r -1 debug set-active-expire 0
r -1 pfadd key a b c d e f g h i j k l m n o p q
set strval [r -1 get key]
r -1 config set slave-read-only yes
wait_for_condition 50 100 {
[r -1 dbsize] == 1
} else {
fail "Replication timeout."
}
assert {$strval == [r -1 get key]}
assert_equal 17 [r -1 pfcount key]
assert {$strval != [r -1 get key]} ; # pfcount updates cache even
; # on readonly replica
assert {$strval != [r -1 get key]}; # cache updated
# cleanup
r -1 config set slave-read-only no
r -1 del key
r -1 config set slave-read-only yes
r -1 debug set-active-expire 1
r -1 dbsize
} {0}
r del key
}

test {PFCOUNT doesn't use expired key on readonly replica} {
r select 5
assert {[r dbsize] == 0}
r debug set-active-expire 0
r pfadd key a b c d e f g h i j k l m n o p q
r pexpire key 10
r -1 select 5
assert {[r -1 dbsize] == 0}
r -1 config set slave-read-only no
r -1 debug set-active-expire 0
r -1 pfadd key a b c d e f g h i j k l m n o p q
r -1 pexpire key 10
r -1 config set slave-read-only yes
after 50
wait_for_condition 50 100 {
[r -1 dbsize] == 1
} else {
fail "Replication timeout."
}
after 10
assert_equal [r -1 pfcount key] 0 ; # expired key not used
assert_equal [r -1 dbsize] 1 ; # but it's also not deleted
# cleanup
r -1 config set slave-read-only no
r -1 del key
r -1 config set slave-read-only yes
r -1 debug set-active-expire 1
r -1 dbsize
} {0}
r debug set-active-expire 1
r del key
}
}
}

Expand Down