Describe the bug
We discovered a potential bug with lazyfree-lazy-server-del. As far as I understand, this feature should implicitly turn DEL calls into UNLINKs -- that is to say, dbAsyncDelete calls.
After enabling this feature, we still saw some very slow DEL calls, which promted us to investigate.
Looking at the code, it appears that the setting may not actually be working as intended.
delCommand calls into delGenericCommand: https://github.com/redis/redis/blob/5.0.7/src/db.c#L486-L488.
And then delGenericCommand directly calls dbSyncDelete: https://github.com/redis/redis/blob/5.0.7/src/db.c#L473-L474.
It does not look at server.lazyfree_lazy_server_del in this code path, and it does not use dbDelete -- which does consult server.lazyfree_lazy_server_del.
A possible solution could be to do something like this:
void delGenericCommand(client *c, int lazy) {
int numdel = 0, j;
if (server.lazyfree_lazy_server_del) {
lazy = 1;
}
...
Or even just pass server.lazyfree_lazy_server_del as an argument from delCommand.
To reproduce
config set lazyfree-lazy-server-del yes
del some-key
It calls dbSyncDelete.
Expected behavior
It calls dbAsyncDelete.
Additional information
Downstream ticket: https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/11018.
It'd be awesome if this could be backported to 5.x.
Comment From: oranagra
@igorwwwwwwwwwwwwwwwwwwww i think you're mixing lazyfree-lazy-server-del with lazyfree-lazy-user-del
Here's a snippet from the documentation in redis.conf
# 3) Because of a side effect of a command that stores data on a key that may
# already exist. For example the RENAME command may delete the old key
# content when it is replaced with another one. Similarly SUNIONSTORE
# or SORT with STORE option may delete existing keys. The SET command
# itself removes any old content of the specified key in order to replace
# it with the specified string.
lazyfree-lazy-server-del no
# It is also possible, for the case when to replace the user code DEL calls
# with UNLINK calls is not easy, to modify the default behavior of the DEL
# command to act exactly like UNLINK, using the following configuration
# directive:
lazyfree-lazy-user-del no
Comment From: igorwwwwwwwwwwwwwwwwwwww
@oranagra Oh, I see. I must have misread this line from the redis 5.x redis.conf as implying it would actually also apply to DEL calls:
# In all the above cases the default is to delete objects in a blocking way,
# like if DEL was called. However you can configure each case specifically
# in order to instead release memory in a non-blocking way like if UNLINK
# was called, using the following configuration directives:
And looks like lazyfree-lazy-user-del was introduced in 6.0 (https://github.com/redis/redis/pull/6243), and the behaviour clarified.
Thanks, this explains it. In this case we will instead opt for explicit UNLINK calls for now, until we are ready to upgrade to redis 6.
Closing. :)