Skip to content

[BUG] HINCRBYFLOAT on HFE field removes field expiration on replica #14218

@ShooterIT

Description

@ShooterIT

Describe the bug

When executing HINCRBYFLOAT on a field of HFE, the expiration time of that field is removed on the replica, even though the master retains it. This leads to an inconsistency between master and replica.

To reproduce

  • master
127.0.0.1:6379> hset hash f1 1
(integer) 1
127.0.0.1:6379> hexpire hash 200 fields 1 f1
1) (integer) 1
127.0.0.1:6379> hincrbyfloat hash f1 1
"2"
127.0.0.1:6379> HTTL hash fields 1 f1
1) (integer) 187
  • replica
127.0.0.1:6380> httl hash fields 1 f1  <== after hexpire
1) (integer) 197
127.0.0.1:6380> httl hash fields 1 f1 <== after hincrbyfloat
1) (integer) -1

Expected behavior

Field expiration metadata should be preserved on the replica after HINCRBYFLOAT

Additional information

the root cause is that we rewrite HINCRBYFLOAT to HSET after executing HINCRBYFLOAT

redis/src/t_hash.c

Lines 2565 to 2572 in f6f1674

/* Always replicate HINCRBYFLOAT as an HSET command with the final value
* in order to make sure that differences in float precision or formatting
* will not create differences in replicas or after an AOF restart. */
robj *newobj;
newobj = createRawStringObject(buf,len);
rewriteClientCommandArgument(c,0,shared.hset);
rewriteClientCommandArgument(c,3,newobj);
decrRefCount(newobj);

maybe we can use HSETEX ... KEEPTTL, but HSETEX is introduced from 8.0, the bug should be introduced from 7.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions