The "implicit DEL operation" is not the same as a DEL command called by a user.
You can config it to use async or sync delete. The reason behind it is to probably give the user more control.
In the redis config file, on the part of LAZY FREEING, it says
DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled.
It's up to the design of the application to understand when it is a good
idea to use one or the other. However the Redis server sometimes has to
delete keys or flush the whole database as a side effect of other operations.**
Specifically Redis deletes objects independently of a user call in the
following scenarios:
....
For example the RENAME command may delete the old key content when it is replaced with >another one.
....
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.
Then there's the config
lazyfree-lazy-server-del no
Just switch it to YES then it will behave like UNLINK
I checked the source code,
For Redis version 5.0, this function is called when you call RENAME command
void renameGenericCommand(client *c, int nx) {
// some code....
// When source and dest key is the same, no operation is performed,
// if the key exists, however we still return an error on unexisting key.
if (sdscmp(c->argv[1]->ptr,c->argv[2]->ptr) == 0) samekey = 1;
// some code ...
if (samekey) {
addReply(c,nx ? shared.czero : shared.ok);
return;
}
...
/* Overwrite: delete the old key before creating the new one
* with the same name. */
dbDelete(c->db,c->argv[2]);
}
This is the dbDelete function it called
int dbDelete(redisDb *db, robj *key) {
return server.lazyfree_lazy_server_del ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
}
As you can see, it does refer to the config of lazyfree-lazy-server-del