Fix KEYSIZES histogram after HGETEX deletes the last hash fields

`HGETEX` could delete the last remaining fields in a hash and remove the key, but still update the KEYSIZES histogram as if an empty hash still existed. That left `INFO KEYSIZES` with a stale hash entry even though the key had already been deleted.

This patch makes `hgetexCommand` treat a zero-length post-operation hash as a removed key when updating the KEYSIZES histogram. Concretely, it reports the new size as `-1` for histogram accounting before deleting the key. A regression test was also added to verify that when `HGETEX PXAT 1` expires all fields in a hash, the corresponding KEYSIZES hash bucket disappears.

Testing:
- Added a regression test in `tests/unit/info-keysizes.tcl` covering `HGETEX` deleting the last hash fields and verifying the histogram entry is removed
- Not tested
This commit is contained in:
erhan1209 2026-04-15 15:44:14 +03:00
parent 2f1a8b2bad
commit d20c6cd50c
2 changed files with 10 additions and 2 deletions

View file

@ -2914,10 +2914,12 @@ void hgetexCommand(client *c) {
}
/* Key may become empty due to lazy expiry in addHashFieldToReply()
* or the new expiration time is in the past.*/
* or the new expiration time is in the past. Keep the KEYSIZES
* histogram aligned with the fact that an empty hash key is removed. */
newlen = hashTypeLength(o, 0);
int64_t hist_newlen = (newlen == 0) ? -1 : newlen;
updateKeysizesHist(c->db, OBJ_HASH, oldlen, newlen);
updateKeysizesHist(c->db, OBJ_HASH, oldlen, hist_newlen);
if (newlen == 0) {
dbDelete(c->db, c->argv[1]);
notifyKeyspaceEvent(NOTIFY_GENERIC, "del", c->argv[1], c->db->id);

View file

@ -753,6 +753,12 @@ proc test_all_keysizes { {replMode 0} } {
run_cmd_verify_hist {$server DEBUG RELOAD} {db0_STR:8=1}
} {} {cluster:skip needs:debug}
test "KEYSIZES - HGETEX deleting the last hash fields removes the histogram entry $suffixRepl" {
run_cmd_verify_hist {$server FLUSHALL} {}
run_cmd_verify_hist {$server HSET myhash f1 v1 f2 v2 f3 v3} {db0_HASH:2=1}
run_cmd_verify_hist {$server HGETEX myhash PXAT 1 FIELDS 3 f1 f2 f3} {}
} {} {cluster:skip}
test "KEYSIZES - Test RDB $suffixRepl" {
run_cmd_verify_hist {$server FLUSHALL} {}
# Write list, set and zset to db0