@antirez Currently if you know the SHA1 for a loaded script you can check for its existence with SCRIPT EXISTS. If you don't know the SHA1 value there is no way to get a list of scripts in the cache. It would be useful if it were possible to list the SHA1 values in the cache, and ideally the script associated with the SHA1.
The situation is that scripts get updated/versioned and loaded into Redis. Old ones need to be deleted, but the SHA1 values are not necessarily recorded. With a listing function and the ability to see the script that was loaded, old scripts can be manually deleted.
Secondarily, if the data is available, a SCRIPT GET SHA1 would be useful.
Comment From: usernameisnull
three years later...
Comment From: oranagra
@allanwax @usernameisnull, redis philosophy is that it intentionally doesn't want to let you get the script code back (i.e. SCRIPT GET SHA1), the design is that the scripts are the responsibility of the client application, and are only cached by redis to improve performance.
The application should always fall back to SCRIPT LOAD or EVAL if EVALSHA or SCRIPT EXIST fail.
If you don't know the SHA1 value there is no way to get a list of scripts in the cache
The application must!! know the SHA1 value, and actually have the script code ready to be re-loaded! redis should not be the one that gives you the SHA1 of a script you wish to execute! it's not a coincidence that scripts are not named! doing that would introduce a versioning problem (you'll need to make sure you run the right version of your named script), which is what redis aims to avoid!
You should not attempt or wish to delete old scripts from the cache! so i also don't see any reason for a SCRIPT LIST command.
Please describe what's the use case for your request.
Comment From: dacoaster
When you're troubleshooting/debugging a 3rd party application that uses Redis heavily and trying to determine why it isn't producing the desired output, being able to see what it is creating in Redis would be very helpful. (I can see the SHA from the MONITOR command, so the SCRIPT LIST command isn't as critical... But SCRIPT GET would be great as I don't really know what is in the script.)
Just my 2 cents, but saying it's the application's "philosophy" to intentionally blind you because you should know already doesn't make sense to me in the context of modern app development that depends so heavily on third party libraries/code.
Comment From: oranagra
that makes sense, but i'm afraid it's a slippery slope, and this could be abused.
maybe a viable solution is DEBUG SCRIPT <SHA> which will print the script the the log file?
this will be less likely to be abused.
@yossigo WDYT?
Comment From: yossigo
@oranagra I think your suggestion is a good compromise.
Comment From: oranagra
@rocksteady-david and others. would that solve your problems?
we can add
DEBUG SCRIPT LIST
DEBUG SCRIPT <SHA>
both of which, print their output to the redis log file, and reply +OK
Comment From: dacoaster
Yeah, that seems reasonable to me.
Comment From: mgravell
Why the redis log and not the response? I think that seems a little unusual and arbitrary, and isn't how most command work - even dangerous commands. If this is intended for security reasons, the threat that we're trying to protect against should be explicit - and I wonder whether ACL isn't the more obvious and appropriate solution. Having to access the redis logs is going to make it much harder to make such a command useful, and has some security implications of its own, such as "who has access to the log?", and "how do we correlate specific queries?"
Comment From: oranagra
@mgravell the intention here is NOT to add another command and a capability for client applications, it is actually the opposite. I don't want this command to be used by anyone, note that it'll be under the DEBUG command, (not the SCRIPT command). It's not about security, but rather about preventing people from abusing the philosophy about EVAL scripts, which dictates that they are part of the client application (not hosted by Redis). So such a command is only intended to use for debugging, specifically when one's hosting a 3rd party redis application or a library.
Comment From: enjoy-binbin
play a bit, loaded two script using script load. DEBUG SCRIPT always reply +OK
[root@binblog redis]# cat 1.lua
local is_exist = redis.call("exists", KEYS[1])
if is_exist == 1 then
redis.call("incr", KEYS[1])
else
redis.call("set", KEYS[1], ARGV[1], "ex", ARGV[2])
end
[root@binblog redis]# src/redis-cli -x script load < 2.lua
debug script error_sha
21782:M 20 Apr 2022 17:39:10.074 # script not found: error_sha
debug script 7b61bd2b4d3fc183238f999ba83bf47b8c62a923
21782:M 20 Apr 2022 17:39:20.635 # sha 7b61bd2b4d3fc183238f999ba83bf47b8c62a923
local is_exist2 = redis.call("exists", KEYS[1])
if is_exist2 == 1 then
redis.call("incr", KEYS[1])
else
redis.call("set", KEYS[1], ARGV[1], "ex", ARGV[2])
end
debug script list, there are two script
21782:M 20 Apr 2022 17:39:25.858 # sha c9e1a03257cfd4aa298ef33e2dfd47b1da68b2ca
local is_exist = redis.call("exists", KEYS[1])
if is_exist == 1 then
redis.call("incr", KEYS[1])
else
redis.call("set", KEYS[1], ARGV[1], "ex", ARGV[2])
end
21782:M 20 Apr 2022 17:39:25.858 # sha 7b61bd2b4d3fc183238f999ba83bf47b8c62a923
local is_exist2 = redis.call("exists", KEYS[1])
if is_exist2 == 1 then
redis.call("incr", KEYS[1])
else
redis.call("set", KEYS[1], ARGV[1], "ex", ARGV[2])
end