Incr expired_keys if the unix-time is already expired for EXPIREAT and other commands(#1517)

Some commands that use unix-time, such as `EXPIREAT` and `SET EXAT`, should include the deleted keys in the `expired_keys` statistics if the specified time has already expired, and notifications should be sent in the manner of expired.

---------

Signed-off-by: Ray Cao <zisong.cw@alibaba-inc.com>
This commit is contained in:
Ray Cao 2025-01-16 16:40:34 +08:00 committed by GitHub
parent cda9eee8c9
commit 921ba19acb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 38 additions and 1 deletions

View File

@ -1850,7 +1850,8 @@ void deleteExpiredKeyFromOverwriteAndPropagate(client *c, robj *keyobj) {
robj *aux = server.lazyfree_lazy_expire ? shared.unlink : shared.del;
rewriteClientCommandVector(c, 2, aux, keyobj);
signalModifiedKey(c, c->db, keyobj);
notifyKeyspaceEvent(NOTIFY_GENERIC, "del", keyobj, c->db->id);
notifyKeyspaceEvent(NOTIFY_EXPIRED, "expired", keyobj, c->db->id);
server.stat_expiredkeys++;
}
/* Propagate an implicit key deletion into replicas and the AOF file.

View File

@ -142,6 +142,31 @@ start_server {tags {"expire"}} {
list $e $f
} {somevalue {}}
test {EXPIRE / EXPIREAT / PEXPIRE / PEXPIREAT Expiration time is already expired} {
r flushall
r config resetstat
r set x somevalue
r expire x -1
assert_equal {0} [r exists x]
assert_equal {1} [s expired_keys]
r set x somevalue
r expireat x [expr [clock seconds] - 1]
assert_equal {0} [r exists x]
assert_equal {2} [s expired_keys]
r set x somevalue
r pexpire x -1000
assert_equal {0} [r exists x]
assert_equal {3} [s expired_keys]
r set x somevalue
r pexpireat x [expr [clock milliseconds] - 1000]
assert_equal {0} [r exists x]
assert_equal {4} [s expired_keys]
}
test {TTL returns time to live in seconds} {
r del x
r setex x 10 somevalue

View File

@ -425,6 +425,17 @@ start_server {tags {"pubsub network"}} {
$rd1 close
}
test "Keyspace notification: expired event (Expiration time is already expired)" {
r config set notify-keyspace-events Ex
r del foo
set rd1 [valkey_deferring_client]
assert_equal {1} [psubscribe $rd1 *]
r set foo 1
r expire foo -1
assert_equal "pmessage * __keyevent@${db}__:expired foo" [$rd1 read]
$rd1 close
}
test "Keyspace notifications: evicted events" {
r config set notify-keyspace-events Ee
r config set maxmemory-policy allkeys-lru