Commit ad94bc31 authored by Vitaly Arbuzov's avatar Vitaly Arbuzov
Browse files

Merge branch 'unstable' into dict-split-by-slot

parents a08686a5 e55568ed
...@@ -323,10 +323,10 @@ jobs: ...@@ -323,10 +323,10 @@ jobs:
./src/redis-cli -p 8080 save > /dev/null ./src/redis-cli -p 8080 save > /dev/null
VMOUT=$(vmtouch -v /tmp/master/dump.rdb) VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
echo $VMOUT echo $VMOUT
grep -q "0%" <<< $VMOUT grep -q " 0%" <<< $VMOUT
CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}') CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
echo "$CACHE" echo "$CACHE"
if [ "$(( $CACHE-$CACHE0 ))" -gt "500000" ]; then exit 1; fi if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
echo "test replication doesn't increase cache" echo "test replication doesn't increase cache"
./src/redis-cli -p 8081 REPLICAOF 127.0.0.1 8080 > /dev/null ./src/redis-cli -p 8081 REPLICAOF 127.0.0.1 8080 > /dev/null
...@@ -334,13 +334,13 @@ jobs: ...@@ -334,13 +334,13 @@ jobs:
sleep 1 # wait for the completion of cache reclaim bio sleep 1 # wait for the completion of cache reclaim bio
VMOUT=$(vmtouch -v /tmp/master/dump.rdb) VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
echo $VMOUT echo $VMOUT
grep -q "0%" <<< $VMOUT grep -q " 0%" <<< $VMOUT
VMOUT=$(vmtouch -v /tmp/slave/dump.rdb) VMOUT=$(vmtouch -v /tmp/slave/dump.rdb)
echo $VMOUT echo $VMOUT
grep -q "0%" <<< $VMOUT grep -q " 0%" <<< $VMOUT
CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}') CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
echo "$CACHE" echo "$CACHE"
if [ "$(( $CACHE-$CACHE0 ))" -gt "500000" ]; then exit 1; fi if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
echo "test reboot doesn't increase cache" echo "test reboot doesn't increase cache"
PID=$(cat /tmp/master/redis.pid) PID=$(cat /tmp/master/redis.pid)
...@@ -351,10 +351,10 @@ jobs: ...@@ -351,10 +351,10 @@ jobs:
sleep 1 # wait for the completion of cache reclaim bio sleep 1 # wait for the completion of cache reclaim bio
VMOUT=$(vmtouch -v /tmp/master/dump.rdb) VMOUT=$(vmtouch -v /tmp/master/dump.rdb)
echo $VMOUT echo $VMOUT
grep -q "0%" <<< $VMOUT grep -q " 0%" <<< $VMOUT
CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}') CACHE=$(grep -w file /sys/fs/cgroup/memory.stat | awk '{print $2}')
echo "$CACHE" echo "$CACHE"
if [ "$(( $CACHE-$CACHE0 ))" -gt "500000" ]; then exit 1; fi if [ "$(( $CACHE-$CACHE0 ))" -gt "8000000" ]; then exit 1; fi
test-valgrind-test: test-valgrind-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
......
...@@ -54,4 +54,5 @@ $TCLSH tests/test_helper.tcl \ ...@@ -54,4 +54,5 @@ $TCLSH tests/test_helper.tcl \
--single unit/moduleapi/postnotifications \ --single unit/moduleapi/postnotifications \
--single unit/moduleapi/async_rm_call \ --single unit/moduleapi/async_rm_call \
--single unit/moduleapi/moduleauth \ --single unit/moduleapi/moduleauth \
--single unit/moduleapi/rdbloadsave \
"${@}" "${@}"
...@@ -32,6 +32,16 @@ loglevel notice ...@@ -32,6 +32,16 @@ loglevel notice
# output for logging but daemonize, logs will be sent to /dev/null # output for logging but daemonize, logs will be sent to /dev/null
logfile "" logfile ""
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident sentinel
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0
# sentinel announce-ip <ip> # sentinel announce-ip <ip>
# sentinel announce-port <port> # sentinel announce-port <port>
# #
......
...@@ -336,18 +336,18 @@ QUIET_INSTALL = @printf ' %b %b\n' $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR) ...@@ -336,18 +336,18 @@ QUIET_INSTALL = @printf ' %b %b\n' $(LINKCOLOR)INSTALL$(ENDCOLOR) $(BINCOLOR)
endif endif
ifneq (, $(findstring LOG_REQ_RES, $(REDIS_CFLAGS))) ifneq (, $(findstring LOG_REQ_RES, $(REDIS_CFLAGS)))
COMMANDS_FILENAME=commands_with_reply_schema COMMANDS_DEF_FILENAME=commands_with_reply_schema
GEN_COMMANDS_FLAGS=--with-reply-schema GEN_COMMANDS_FLAGS=--with-reply-schema
else else
COMMANDS_FILENAME=commands COMMANDS_DEF_FILENAME=commands
GEN_COMMANDS_FLAGS= GEN_COMMANDS_FLAGS=
endif endif
REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX) REDIS_SERVER_NAME=redis-server$(PROG_SUFFIX)
REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX) REDIS_SENTINEL_NAME=redis-sentinel$(PROG_SUFFIX)
REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o $(COMMANDS_FILENAME).o strl.o connection.o unix.o logreqres.o REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o eval.o bio.o rio.o rand.o memtest.o syscheck.o crcspeed.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o lolwut6.o acl.o tracking.o socket.o tls.o sha256.o timeout.o setcpuaffinity.o monotonic.o mt19937-64.o resp_parser.o call_reply.o script_lua.o script.o functions.o function_lua.o commands.o strl.o connection.o unix.o logreqres.o
REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX) REDIS_CLI_NAME=redis-cli$(PROG_SUFFIX)
REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o redisassert.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o ae.o redisassert.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o cli_commands.o
REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX) REDIS_BENCHMARK_NAME=redis-benchmark$(PROG_SUFFIX)
REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o redisassert.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o redisassert.o release.o crcspeed.o crc64.o siphash.o crc16.o monotonic.o cli_common.o mt19937-64.o strl.o
REDIS_CHECK_RDB_NAME=redis-check-rdb$(PROG_SUFFIX) REDIS_CHECK_RDB_NAME=redis-check-rdb$(PROG_SUFFIX)
...@@ -435,13 +435,15 @@ DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ ...@@ -435,13 +435,15 @@ DEP = $(REDIS_SERVER_OBJ:%.o=%.d) $(REDIS_CLI_OBJ:%.o=%.d) $(REDIS_BENCHMARK_OBJ
%.o: %.c .make-prerequisites %.o: %.c .make-prerequisites
$(REDIS_CC) -MMD -o $@ -c $< $(REDIS_CC) -MMD -o $@ -c $<
# The file commands.c is checked in and doesn't normally need to be rebuilt. It # The file commands.def is checked in and doesn't normally need to be rebuilt. It
# is built only if python is available and its prereqs are modified. # is built only if python is available and its prereqs are modified.
ifneq (,$(PYTHON)) ifneq (,$(PYTHON))
$(COMMANDS_FILENAME).c: commands/*.json ../utils/generate-command-code.py $(COMMANDS_DEF_FILENAME).def: commands/*.json ../utils/generate-command-code.py
$(QUIET_GEN)$(PYTHON) ../utils/generate-command-code.py $(GEN_COMMANDS_FLAGS) $(QUIET_GEN)$(PYTHON) ../utils/generate-command-code.py $(GEN_COMMANDS_FLAGS)
endif endif
commands.c: $(COMMANDS_DEF_FILENAME).def
clean: clean:
rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep *.so rm -rf $(REDIS_SERVER_NAME) $(REDIS_SENTINEL_NAME) $(REDIS_CLI_NAME) $(REDIS_BENCHMARK_NAME) $(REDIS_CHECK_RDB_NAME) $(REDIS_CHECK_AOF_NAME) *.o *.gcda *.gcno *.gcov redis.info lcov-html Makefile.dep *.so
rm -f $(DEP) rm -f $(DEP)
......
...@@ -1891,6 +1891,13 @@ void ACLKillPubsubClientsIfNeeded(user *new, user *original) { ...@@ -1891,6 +1891,13 @@ void ACLKillPubsubClientsIfNeeded(user *new, user *original) {
listRewind(original->selectors,&li); listRewind(original->selectors,&li);
while((ln = listNext(&li)) && match) { while((ln = listNext(&li)) && match) {
aclSelector *s = (aclSelector *) listNodeValue(ln); aclSelector *s = (aclSelector *) listNodeValue(ln);
/* If any of the original selectors has the all-channels permission, but
* the new ones don't (this is checked earlier in this function), then the
* new list is not a strict superset of the original. */
if (s->flags & SELECTOR_FLAG_ALLCHANNELS) {
match = 0;
break;
}
listRewind(s->channels, &lpi); listRewind(s->channels, &lpi);
while((lpn = listNext(&lpi)) && match) { while((lpn = listNext(&lpi)) && match) {
if (!listSearchKey(upcoming, listNodeValue(lpn))) { if (!listSearchKey(upcoming, listNodeValue(lpn))) {
......
...@@ -758,6 +758,7 @@ void aofOpenIfNeededOnServerStart(void) { ...@@ -758,6 +758,7 @@ void aofOpenIfNeededOnServerStart(void) {
} }
server.aof_last_incr_size = getAppendOnlyFileSize(aof_name, NULL); server.aof_last_incr_size = getAppendOnlyFileSize(aof_name, NULL);
server.aof_last_incr_fsync_offset = server.aof_last_incr_size;
if (incr_aof_len) { if (incr_aof_len) {
serverLog(LL_NOTICE, "Opening AOF incr file %s on server start", aof_name); serverLog(LL_NOTICE, "Opening AOF incr file %s on server start", aof_name);
...@@ -832,13 +833,14 @@ int openNewIncrAofForAppend(void) { ...@@ -832,13 +833,14 @@ int openNewIncrAofForAppend(void) {
* is already synced at this point so fsync doesn't matter. */ * is already synced at this point so fsync doesn't matter. */
if (server.aof_fd != -1) { if (server.aof_fd != -1) {
aof_background_fsync_and_close(server.aof_fd); aof_background_fsync_and_close(server.aof_fd);
server.aof_fsync_offset = server.aof_current_size;
server.aof_last_fsync = server.unixtime; server.aof_last_fsync = server.unixtime;
} }
server.aof_fd = newfd; server.aof_fd = newfd;
/* Reset the aof_last_incr_size. */ /* Reset the aof_last_incr_size. */
server.aof_last_incr_size = 0; server.aof_last_incr_size = 0;
/* Reset the aof_last_incr_fsync_offset. */
server.aof_last_incr_fsync_offset = 0;
/* Update `server.aof_manifest`. */ /* Update `server.aof_manifest`. */
if (temp_am) aofManifestFreeAndUpdate(temp_am); if (temp_am) aofManifestFreeAndUpdate(temp_am);
return C_OK; return C_OK;
...@@ -952,7 +954,6 @@ void stopAppendOnly(void) { ...@@ -952,7 +954,6 @@ void stopAppendOnly(void) {
if (redis_fsync(server.aof_fd) == -1) { if (redis_fsync(server.aof_fd) == -1) {
serverLog(LL_WARNING,"Fail to fsync the AOF file: %s",strerror(errno)); serverLog(LL_WARNING,"Fail to fsync the AOF file: %s",strerror(errno));
} else { } else {
server.aof_fsync_offset = server.aof_current_size;
server.aof_last_fsync = server.unixtime; server.aof_last_fsync = server.unixtime;
} }
close(server.aof_fd); close(server.aof_fd);
...@@ -962,6 +963,7 @@ void stopAppendOnly(void) { ...@@ -962,6 +963,7 @@ void stopAppendOnly(void) {
server.aof_state = AOF_OFF; server.aof_state = AOF_OFF;
server.aof_rewrite_scheduled = 0; server.aof_rewrite_scheduled = 0;
server.aof_last_incr_size = 0; server.aof_last_incr_size = 0;
server.aof_last_incr_fsync_offset = 0;
server.fsynced_reploff = -1; server.fsynced_reploff = -1;
atomicSet(server.fsynced_reploff_pending, 0); atomicSet(server.fsynced_reploff_pending, 0);
killAppendOnlyChild(); killAppendOnlyChild();
...@@ -1083,10 +1085,19 @@ void flushAppendOnlyFile(int force) { ...@@ -1083,10 +1085,19 @@ void flushAppendOnlyFile(int force) {
* stop write commands before fsync called in one second, * stop write commands before fsync called in one second,
* the data in page cache cannot be flushed in time. */ * the data in page cache cannot be flushed in time. */
if (server.aof_fsync == AOF_FSYNC_EVERYSEC && if (server.aof_fsync == AOF_FSYNC_EVERYSEC &&
server.aof_fsync_offset != server.aof_current_size && server.aof_last_incr_fsync_offset != server.aof_last_incr_size &&
server.unixtime > server.aof_last_fsync && server.unixtime > server.aof_last_fsync &&
!(sync_in_progress = aofFsyncInProgress())) { !(sync_in_progress = aofFsyncInProgress())) {
goto try_fsync; goto try_fsync;
/* Check if we need to do fsync even the aof buffer is empty,
* the reason is described in the previous AOF_FSYNC_EVERYSEC block,
* and AOF_FSYNC_ALWAYS is also checked here to handle a case where
* aof_fsync is changed from everysec to always. */
} else if (server.aof_fsync == AOF_FSYNC_ALWAYS &&
server.aof_last_incr_fsync_offset != server.aof_last_incr_size)
{
goto try_fsync;
} else { } else {
return; return;
} }
...@@ -1253,14 +1264,14 @@ try_fsync: ...@@ -1253,14 +1264,14 @@ try_fsync:
} }
latencyEndMonitor(latency); latencyEndMonitor(latency);
latencyAddSampleIfNeeded("aof-fsync-always",latency); latencyAddSampleIfNeeded("aof-fsync-always",latency);
server.aof_fsync_offset = server.aof_current_size; server.aof_last_incr_fsync_offset = server.aof_last_incr_size;
server.aof_last_fsync = server.unixtime; server.aof_last_fsync = server.unixtime;
atomicSet(server.fsynced_reploff_pending, server.master_repl_offset); atomicSet(server.fsynced_reploff_pending, server.master_repl_offset);
} else if ((server.aof_fsync == AOF_FSYNC_EVERYSEC && } else if (server.aof_fsync == AOF_FSYNC_EVERYSEC &&
server.unixtime > server.aof_last_fsync)) { server.unixtime > server.aof_last_fsync) {
if (!sync_in_progress) { if (!sync_in_progress) {
aof_background_fsync(server.aof_fd); aof_background_fsync(server.aof_fd);
server.aof_fsync_offset = server.aof_current_size; server.aof_last_incr_fsync_offset = server.aof_last_incr_size;
} }
server.aof_last_fsync = server.unixtime; server.aof_last_fsync = server.unixtime;
} }
...@@ -1766,7 +1777,6 @@ int loadAppendOnlyFiles(aofManifest *am) { ...@@ -1766,7 +1777,6 @@ int loadAppendOnlyFiles(aofManifest *am) {
* executed early, but that shouldn't be a problem since everything will be * executed early, but that shouldn't be a problem since everything will be
* fine after the first AOFRW. */ * fine after the first AOFRW. */
server.aof_rewrite_base_size = base_size; server.aof_rewrite_base_size = base_size;
server.aof_fsync_offset = server.aof_current_size;
cleanup: cleanup:
stopLoading(ret == AOF_OK || ret == AOF_TRUNCATED); stopLoading(ret == AOF_OK || ret == AOF_TRUNCATED);
...@@ -2659,13 +2669,10 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { ...@@ -2659,13 +2669,10 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) {
/* We can safely let `server.aof_manifest` point to 'temp_am' and free the previous one. */ /* We can safely let `server.aof_manifest` point to 'temp_am' and free the previous one. */
aofManifestFreeAndUpdate(temp_am); aofManifestFreeAndUpdate(temp_am);
if (server.aof_fd != -1) { if (server.aof_state != AOF_OFF) {
/* AOF enabled. */ /* AOF enabled. */
server.aof_selected_db = -1; /* Make sure SELECT is re-issued */
server.aof_current_size = getAppendOnlyFileSize(new_base_filename, NULL) + server.aof_last_incr_size; server.aof_current_size = getAppendOnlyFileSize(new_base_filename, NULL) + server.aof_last_incr_size;
server.aof_rewrite_base_size = server.aof_current_size; server.aof_rewrite_base_size = server.aof_current_size;
server.aof_fsync_offset = server.aof_current_size;
server.aof_last_fsync = server.unixtime;
} }
/* We don't care about the return value of `aofDelHistoryFiles`, because the history /* We don't care about the return value of `aofDelHistoryFiles`, because the history
......
...@@ -114,6 +114,7 @@ void updateStatsOnUnblock(client *c, long blocked_us, long reply_us, int had_err ...@@ -114,6 +114,7 @@ void updateStatsOnUnblock(client *c, long blocked_us, long reply_us, int had_err
updateCommandLatencyHistogram(&(c->lastcmd->latency_histogram), total_cmd_duration*1000); updateCommandLatencyHistogram(&(c->lastcmd->latency_histogram), total_cmd_duration*1000);
/* Log the command into the Slow log if needed. */ /* Log the command into the Slow log if needed. */
slowlogPushCurrentCommand(c, c->lastcmd, total_cmd_duration); slowlogPushCurrentCommand(c, c->lastcmd, total_cmd_duration);
c->duration = 0;
/* Log the reply duration event. */ /* Log the reply duration event. */
latencyAddSampleIfNeeded("command-unblocking",reply_us/1000); latencyAddSampleIfNeeded("command-unblocking",reply_us/1000);
} }
......
#include <stddef.h>
#include "cli_commands.h"
/* Definitions to configure commands.c to generate the above structs. */
#define MAKE_CMD(name,summary,complexity,since,doc_flags,replaced,deprecated,group,group_enum,history,num_history,tips,num_tips,function,arity,flags,acl,key_specs,key_specs_num,get_keys,numargs) name,summary,group,since,numargs
#define MAKE_ARG(name,type,key_spec_index,token,summary,since,flags,numsubargs,deprecated_since) name,type,token,since,flags,numsubargs
#define COMMAND_ARG cliCommandArg
#define COMMAND_STRUCT commandDocs
#define SKIP_CMD_HISTORY_TABLE
#define SKIP_CMD_TIPS_TABLE
#define SKIP_CMD_KEY_SPECS_TABLE
#include "commands.def"
/* This file is used by redis-cli in place of server.h when including commands.c
* It contains alternative structs which omit the parts of the commands table
* that are not suitable for redis-cli, e.g. the command proc. */
#ifndef __REDIS_CLI_COMMANDS_H
#define __REDIS_CLI_COMMANDS_H
#include <stddef.h>
#include "commands.h"
/* Syntax specifications for a command argument. */
typedef struct cliCommandArg {
char *name;
redisCommandArgType type;
char *token;
char *since;
int flags;
int numsubargs;
struct cliCommandArg *subargs;
const char *display_text;
/*
* For use at runtime.
* Fields used to keep track of input word matches for command-line hinting.
*/
int matched; /* How many input words have been matched by this argument? */
int matched_token; /* Has the token been matched? */
int matched_name; /* Has the name been matched? */
int matched_all; /* Has the whole argument been consumed (no hint needed)? */
} cliCommandArg;
/* Command documentation info used for help output */
struct commandDocs {
char *name;
char *summary;
char *group;
char *since;
int numargs;
cliCommandArg *args; /* An array of the command arguments. */
struct commandDocs *subcommands;
char *params; /* A string describing the syntax of the command arguments. */
};
extern struct commandDocs redisCommandTable[];
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef __REDIS_COMMANDS_H
#define __REDIS_COMMANDS_H
/* Must be synced with ARG_TYPE_STR and generate-command-code.py */
typedef enum {
ARG_TYPE_STRING,
ARG_TYPE_INTEGER,
ARG_TYPE_DOUBLE,
ARG_TYPE_KEY, /* A string, but represents a keyname */
ARG_TYPE_PATTERN,
ARG_TYPE_UNIX_TIME,
ARG_TYPE_PURE_TOKEN,
ARG_TYPE_ONEOF, /* Has subargs */
ARG_TYPE_BLOCK /* Has subargs */
} redisCommandArgType;
#define CMD_ARG_NONE (0)
#define CMD_ARG_OPTIONAL (1<<0)
#define CMD_ARG_MULTIPLE (1<<1)
#define CMD_ARG_MULTIPLE_TOKEN (1<<2)
/* WARNING! This struct must match RedisModuleCommandArg */
typedef struct redisCommandArg {
const char *name;
redisCommandArgType type;
int key_spec_index;
const char *token;
const char *summary;
const char *since;
int flags;
const char *deprecated_since;
int num_args;
struct redisCommandArg *subargs;
const char *display_text;
} redisCommandArg;
/* Returns the command group name by group number. */
const char *commandGroupStr(int index);
#endif
{ {
"CAT": { "CAT": {
"summary": "List the ACL categories or the commands inside a category", "summary": "Lists the ACL categories, or the commands inside a category.",
"complexity": "O(1) since the categories and commands are a fixed set.", "complexity": "O(1) since the categories and commands are a fixed set.",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
...@@ -17,14 +17,14 @@ ...@@ -17,14 +17,14 @@
"anyOf": [ "anyOf": [
{ {
"type": "array", "type": "array",
"description": "In case `categoryname` was not given, a list of existing ACL categories", "description": "In case `category` was not given, a list of existing ACL categories",
"items": { "items": {
"type": "string" "type": "string"
} }
}, },
{ {
"type": "array", "type": "array",
"description": "In case `categoryname` was given, list of commands that fall under the provided ACL category", "description": "In case `category` was given, list of commands that fall under the provided ACL category",
"items": { "items": {
"type": "string" "type": "string"
} }
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
}, },
"arguments": [ "arguments": [
{ {
"name": "categoryname", "name": "category",
"type": "string", "type": "string",
"optional": true "optional": true
} }
......
{ {
"DELUSER": { "DELUSER": {
"summary": "Remove the specified ACL users and the associated rules", "summary": "Deletes ACL users, and terminates their connections.",
"complexity": "O(1) amortized time considering the typical user.", "complexity": "O(1) amortized time considering the typical user.",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
{ {
"DRYRUN": { "DRYRUN": {
"summary": "Returns whether the user can execute the given command without executing the command.", "summary": "Simulates the execution of a command by a user, without executing the command.",
"complexity": "O(1).", "complexity": "O(1).",
"group": "server", "group": "server",
"since": "7.0.0", "since": "7.0.0",
......
{ {
"GENPASS": { "GENPASS": {
"summary": "Generate a pseudorandom secure password to use for ACL users", "summary": "Generates a pseudorandom, secure password that can be used to identify ACL users.",
"complexity": "O(1)", "complexity": "O(1)",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
{ {
"GETUSER": { "GETUSER": {
"summary": "Get the rules for a specific ACL user", "summary": "Lists the ACL rules of a user.",
"complexity": "O(N). Where N is the number of password, command and pattern rules that the user has.", "complexity": "O(N). Where N is the number of password, command and pattern rules that the user has.",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
{ {
"HELP": { "HELP": {
"summary": "Show helpful text about the different subcommands", "summary": "Returns helpful text about the different subcommands.",
"complexity": "O(1)", "complexity": "O(1)",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
{ {
"LIST": { "LIST": {
"summary": "List the current ACL rules in ACL config file format", "summary": "Dumps the effective rules in ACL file format.",
"complexity": "O(N). Where N is the number of configured users.", "complexity": "O(N). Where N is the number of configured users.",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
{ {
"LOAD": { "LOAD": {
"summary": "Reload the ACLs from the configured ACL file", "summary": "Reloads the rules from the configured ACL file.",
"complexity": "O(N). Where N is the number of configured users.", "complexity": "O(N). Where N is the number of configured users.",
"group": "server", "group": "server",
"since": "6.0.0", "since": "6.0.0",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment