Make KEYS can visit expired key in import-source state (#1326)
After #1185, a client in import-source state can visit expired key both in read commands and write commands, this commit handle keyIsExpired function to handle import-source state as well, so KEYS can visit the expired key. This is not particularly important, but it ensures the definition, also doing some cleanup around the test, verified that the client can indeed visit the expired key. Signed-off-by: Binbin <binloveplay1314@qq.com>
This commit is contained in:
parent
5d08149e72
commit
db7b7396ff
10
src/db.c
10
src/db.c
@ -390,7 +390,7 @@ robj *dbRandomKey(serverDb *db) {
|
||||
if (allvolatile && (server.primary_host || server.import_mode) && --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 repilca, so the function cannot stop because
|
||||
* expired in the replica, so the function cannot stop because
|
||||
* expireIfNeeded() is false, nor it can stop because
|
||||
* dictGetFairRandomKey() returns NULL (there are keys to return).
|
||||
* To prevent the infinite loop we do some tries, but if there
|
||||
@ -1808,7 +1808,13 @@ int keyIsExpiredWithDictIndex(serverDb *db, robj *key, int dict_index) {
|
||||
/* Check if the key is expired. */
|
||||
int keyIsExpired(serverDb *db, robj *key) {
|
||||
int dict_index = getKVStoreIndexForKey(key->ptr);
|
||||
return keyIsExpiredWithDictIndex(db, key, dict_index);
|
||||
if (!keyIsExpiredWithDictIndex(db, key, dict_index)) return 0;
|
||||
|
||||
/* See expireIfNeededWithDictIndex for more details. */
|
||||
if (server.primary_host == NULL && server.import_mode) {
|
||||
if (server.current_client && server.current_client->flag.import_source) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
keyStatus expireIfNeededWithDictIndex(serverDb *db, robj *key, int flags, int dict_index) {
|
||||
|
@ -3617,7 +3617,7 @@ void clientCommand(client *c) {
|
||||
"NO-TOUCH (ON|OFF)",
|
||||
" Will not touch LRU/LFU stats when this mode is on.",
|
||||
"IMPORT-SOURCE (ON|OFF)",
|
||||
" Mark this connection as an import source if server.import_mode is true.",
|
||||
" Mark this connection as an import source if import-mode is enabled.",
|
||||
" Sync tools can set their connections into 'import-source' state to visit",
|
||||
" expired keys.",
|
||||
NULL};
|
||||
|
@ -841,7 +841,7 @@ start_server {tags {"expire"}} {
|
||||
|
||||
r set foo1 bar PX 1
|
||||
r set foo2 bar PX 1
|
||||
after 100
|
||||
after 10
|
||||
|
||||
assert_equal [r dbsize] {2}
|
||||
|
||||
@ -879,22 +879,27 @@ start_server {tags {"expire"}} {
|
||||
assert_equal [r debug set-active-expire 1] {OK}
|
||||
} {} {needs:debug}
|
||||
|
||||
test {RANDOMKEY can return expired key in import mode} {
|
||||
test {Client can visit expired key in import-source state} {
|
||||
r flushall
|
||||
|
||||
r config set import-mode yes
|
||||
assert_equal [r client import-source on] {OK}
|
||||
|
||||
r set foo1 bar PX 1
|
||||
r set foo1 1 PX 1
|
||||
after 10
|
||||
|
||||
set client [valkey [srv "host"] [srv "port"] 0 $::tls]
|
||||
if {!$::singledb} {
|
||||
$client select 9
|
||||
}
|
||||
assert_equal [$client ttl foo1] {-2}
|
||||
# Normal clients cannot visit expired key.
|
||||
assert_equal [r get foo1] {}
|
||||
assert_equal [r ttl foo1] {-2}
|
||||
assert_equal [r dbsize] 1
|
||||
|
||||
# Client can visit expired key when in import-source state.
|
||||
assert_equal [r client import-source on] {OK}
|
||||
assert_equal [r ttl foo1] {0}
|
||||
assert_equal [r get foo1] {1}
|
||||
assert_equal [r incr foo1] {2}
|
||||
assert_equal [r randomkey] {foo1}
|
||||
assert_equal [r scan 0 match * count 10000] {0 foo1}
|
||||
assert_equal [r keys *] {foo1}
|
||||
|
||||
assert_equal [r client import-source off] {OK}
|
||||
r config set import-mode no
|
||||
|
Loading…
x
Reference in New Issue
Block a user