Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d424259a12 | ||
|
|
7f6de086fe | ||
|
|
8c6ebf84ae | ||
|
|
ba113c8337 | ||
|
|
348eda81e0 | ||
|
|
3f6bd4fc25 | ||
|
|
d6601de73f | ||
|
|
00023873a8 | ||
|
|
413c8be5ad | ||
|
|
1119ecae6f | ||
|
|
cc244370a2 | ||
|
|
3e7523aceb | ||
|
|
459acdeeb1 | ||
|
|
0b2cbf138e | ||
|
|
9e505e6cd8 | ||
|
|
68305c5b99 |
+70
-1
@@ -11,8 +11,77 @@ CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
|
||||
SECURITY: There are security fixes in the release.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
================================================================================
|
||||
Redis 7.2.0 GA Released Mon Aug 15 12:00:00 IDT 2023
|
||||
Redis 7.2.2 Released Wed 18 Oct 2023 10:33:40 IDT
|
||||
================================================================================
|
||||
|
||||
Upgrade urgency SECURITY: See security fixes below.
|
||||
|
||||
Security fixes
|
||||
==============
|
||||
|
||||
* (CVE-2023-45145) The wrong order of listen(2) and chmod(2) calls creates a
|
||||
race condition that can be used by another process to bypass desired Unix
|
||||
socket permissions on startup.
|
||||
|
||||
|
||||
Platform / toolchain support related changes
|
||||
=================================================
|
||||
|
||||
* Fix compilation error on MacOS 13 (#12611)
|
||||
|
||||
Bug fixes
|
||||
=========
|
||||
|
||||
* WAITAOF could timeout in the absence of write traffic in case a new AOF is
|
||||
created and an AOF rewrite can't immediately start (#12620)
|
||||
|
||||
Redis cluster
|
||||
=============
|
||||
|
||||
* Fix crash when running rebalance command in a mixed cluster of 7.0 and 7.2
|
||||
nodes (#12604)
|
||||
* Fix the return type of the slot number in cluster shards to integer, which
|
||||
makes it consistent with past behavior (#12561)
|
||||
* Fix CLUSTER commands are called from modules or scripts to return TLS info
|
||||
appropriately (#12569)
|
||||
|
||||
Changes in CLI tools
|
||||
====================
|
||||
|
||||
* redis-cli, fix crash on reconnect when in SUBSCRIBE mode (#12571)
|
||||
|
||||
Module API changes
|
||||
==================
|
||||
|
||||
* Fix overflow calculation for next timer event (#12474)
|
||||
|
||||
|
||||
================================================================================
|
||||
Redis 7.2.1 Released Wed 06 Sep 2023 15:00:00 IDT
|
||||
================================================================================
|
||||
|
||||
Upgrade urgency SECURITY: See security fixes below.
|
||||
|
||||
Security Fixes
|
||||
==============
|
||||
|
||||
* (CVE-2023-41053) Redis does not correctly identify keys accessed by SORT_RO and,
|
||||
as a result, may grant users executing this command access to keys that are not
|
||||
explicitly authorized by the ACL configuration.
|
||||
|
||||
|
||||
Bug Fixes
|
||||
=========
|
||||
|
||||
* Fix crashes when joining a node to an existing 7.0 Redis Cluster (#12538)
|
||||
* Correct request_policy and response_policy command tips on for some admin /
|
||||
configuration commands (#12545, #12530)
|
||||
|
||||
|
||||
================================================================================
|
||||
Redis 7.2.0 GA Released Tue Aug 15 12:00:00 IDT 2023
|
||||
================================================================================
|
||||
|
||||
Upgrade urgency LOW: This is the first stable Release for Redis 7.2.
|
||||
|
||||
@@ -333,7 +333,7 @@ static int processTimeEvents(aeEventLoop *eventLoop) {
|
||||
processed++;
|
||||
now = getMonotonicUs();
|
||||
if (retval != AE_NOMORE) {
|
||||
te->when = now + retval * 1000;
|
||||
te->when = now + (monotime)retval * 1000;
|
||||
} else {
|
||||
te->id = AE_DELETED_EVENT_ID;
|
||||
}
|
||||
|
||||
+6
-5
@@ -417,13 +417,16 @@ int anetUnixGenericConnect(char *err, const char *path, int flags)
|
||||
return s;
|
||||
}
|
||||
|
||||
static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog) {
|
||||
static int anetListen(char *err, int s, struct sockaddr *sa, socklen_t len, int backlog, mode_t perm) {
|
||||
if (bind(s,sa,len) == -1) {
|
||||
anetSetError(err, "bind: %s", strerror(errno));
|
||||
close(s);
|
||||
return ANET_ERR;
|
||||
}
|
||||
|
||||
if (sa->sa_family == AF_LOCAL && perm)
|
||||
chmod(((struct sockaddr_un *) sa)->sun_path, perm);
|
||||
|
||||
if (listen(s, backlog) == -1) {
|
||||
anetSetError(err, "listen: %s", strerror(errno));
|
||||
close(s);
|
||||
@@ -467,7 +470,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
|
||||
|
||||
if (af == AF_INET6 && anetV6Only(err,s) == ANET_ERR) goto error;
|
||||
if (anetSetReuseAddr(err,s) == ANET_ERR) goto error;
|
||||
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog) == ANET_ERR) s = ANET_ERR;
|
||||
if (anetListen(err,s,p->ai_addr,p->ai_addrlen,backlog,0) == ANET_ERR) s = ANET_ERR;
|
||||
goto end;
|
||||
}
|
||||
if (p == NULL) {
|
||||
@@ -508,10 +511,8 @@ int anetUnixServer(char *err, char *path, mode_t perm, int backlog)
|
||||
memset(&sa,0,sizeof(sa));
|
||||
sa.sun_family = AF_LOCAL;
|
||||
redis_strlcpy(sa.sun_path,path,sizeof(sa.sun_path));
|
||||
if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog) == ANET_ERR)
|
||||
if (anetListen(err,s,(struct sockaddr*)&sa,sizeof(sa),backlog,perm) == ANET_ERR)
|
||||
return ANET_ERR;
|
||||
if (perm)
|
||||
chmod(sa.sun_path, perm);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -976,18 +976,6 @@ void stopAppendOnly(void) {
|
||||
int startAppendOnly(void) {
|
||||
serverAssert(server.aof_state == AOF_OFF);
|
||||
|
||||
/* Wait for all bio jobs related to AOF to drain. This prevents a race
|
||||
* between updates to `fsynced_reploff_pending` of the worker thread, belonging
|
||||
* to the previous AOF, and the new one. This concern is specific for a full
|
||||
* sync scenario where we don't wanna risk the ACKed replication offset
|
||||
* jumping backwards or forward when switching to a different master. */
|
||||
bioDrainWorker(BIO_AOF_FSYNC);
|
||||
|
||||
/* Set the initial repl_offset, which will be applied to fsynced_reploff
|
||||
* when AOFRW finishes (after possibly being updated by a bio thread) */
|
||||
atomicSet(server.fsynced_reploff_pending, server.master_repl_offset);
|
||||
server.fsynced_reploff = 0;
|
||||
|
||||
server.aof_state = AOF_WAIT_REWRITE;
|
||||
if (hasActiveChildProcess() && server.child_type != CHILD_TYPE_AOF) {
|
||||
server.aof_rewrite_scheduled = 1;
|
||||
@@ -2454,7 +2442,23 @@ int rewriteAppendOnlyFileBackground(void) {
|
||||
server.aof_lastbgrewrite_status = C_ERR;
|
||||
return C_ERR;
|
||||
}
|
||||
|
||||
if (server.aof_state == AOF_WAIT_REWRITE) {
|
||||
/* Wait for all bio jobs related to AOF to drain. This prevents a race
|
||||
* between updates to `fsynced_reploff_pending` of the worker thread, belonging
|
||||
* to the previous AOF, and the new one. This concern is specific for a full
|
||||
* sync scenario where we don't wanna risk the ACKed replication offset
|
||||
* jumping backwards or forward when switching to a different master. */
|
||||
bioDrainWorker(BIO_AOF_FSYNC);
|
||||
|
||||
/* Set the initial repl_offset, which will be applied to fsynced_reploff
|
||||
* when AOFRW finishes (after possibly being updated by a bio thread) */
|
||||
atomicSet(server.fsynced_reploff_pending, server.master_repl_offset);
|
||||
server.fsynced_reploff = 0;
|
||||
}
|
||||
|
||||
server.stat_aof_rewrites++;
|
||||
|
||||
if ((childpid = redisFork(CHILD_TYPE_AOF)) == 0) {
|
||||
char tmpfile[256];
|
||||
|
||||
|
||||
+23
-13
@@ -119,6 +119,20 @@ static inline int defaultClientPort(void) {
|
||||
return server.tls_cluster ? server.tls_port : server.port;
|
||||
}
|
||||
|
||||
/* When a cluster command is called, we need to decide whether to return TLS info or
|
||||
* non-TLS info by the client's connection type. However if the command is called by
|
||||
* a Lua script or RM_call, there is no connection in the fake client, so we use
|
||||
* server.current_client here to get the real client if available. And if it is not
|
||||
* available (modules may call commands without a real client), we return the default
|
||||
* info, which is determined by server.tls_cluster. */
|
||||
static int shouldReturnTlsInfo(void) {
|
||||
if (server.current_client && server.current_client->conn) {
|
||||
return connIsTLS(server.current_client->conn);
|
||||
} else {
|
||||
return server.tls_cluster;
|
||||
}
|
||||
}
|
||||
|
||||
/* Links to the next and previous entries for keys in the same slot are stored
|
||||
* in the dict entry metadata. See Slot to Key API below. */
|
||||
#define dictEntryNextInSlot(de) \
|
||||
@@ -938,13 +952,13 @@ static void updateAnnouncedHumanNodename(clusterNode *node, char *new) {
|
||||
|
||||
|
||||
static void updateShardId(clusterNode *node, const char *shard_id) {
|
||||
if (memcmp(node->shard_id, shard_id, CLUSTER_NAMELEN) != 0) {
|
||||
if (shard_id && memcmp(node->shard_id, shard_id, CLUSTER_NAMELEN) != 0) {
|
||||
clusterRemoveNodeFromShard(node);
|
||||
memcpy(node->shard_id, shard_id, CLUSTER_NAMELEN);
|
||||
clusterAddNodeToShard(shard_id, node);
|
||||
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG);
|
||||
}
|
||||
if (myself != node && myself->slaveof == node) {
|
||||
if (shard_id && myself != node && myself->slaveof == node) {
|
||||
if (memcmp(myself->shard_id, shard_id, CLUSTER_NAMELEN) != 0) {
|
||||
/* shard-id can diverge right after a rolling upgrade
|
||||
* from pre-7.2 releases */
|
||||
@@ -4922,12 +4936,8 @@ int clusterDelSlot(int slot) {
|
||||
if (!n) return C_ERR;
|
||||
|
||||
/* Cleanup the channels in master/replica as part of slot deletion. */
|
||||
list *nodes_for_slot = clusterGetNodesInMyShard(n);
|
||||
serverAssert(nodes_for_slot != NULL);
|
||||
listNode *ln = listSearchKey(nodes_for_slot, myself);
|
||||
if (ln != NULL) {
|
||||
removeChannelsInSlot(slot);
|
||||
}
|
||||
removeChannelsInSlot(slot);
|
||||
/* Clear the slot bit. */
|
||||
serverAssert(clusterNodeClearSlotBit(n,slot) == 1);
|
||||
server.cluster->slots[slot] = NULL;
|
||||
return C_OK;
|
||||
@@ -5570,7 +5580,7 @@ void addNodeToNodeReply(client *c, clusterNode *node) {
|
||||
}
|
||||
|
||||
/* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */
|
||||
addReplyLongLong(c, getNodeClientPort(node, connIsTLS(c->conn)));
|
||||
addReplyLongLong(c, getNodeClientPort(node, shouldReturnTlsInfo()));
|
||||
addReplyBulkCBuffer(c, node->name, CLUSTER_NAMELEN);
|
||||
|
||||
/* Add the additional endpoint information, this is all the known networking information
|
||||
@@ -5703,7 +5713,7 @@ void addShardReplyForClusterShards(client *c, list *nodes) {
|
||||
serverAssert((n->slot_info_pairs_count % 2) == 0);
|
||||
addReplyArrayLen(c, n->slot_info_pairs_count);
|
||||
for (int i = 0; i < n->slot_info_pairs_count; i++)
|
||||
addReplyBulkLongLong(c, (unsigned long)n->slot_info_pairs[i]);
|
||||
addReplyLongLong(c, (unsigned long)n->slot_info_pairs[i]);
|
||||
} else {
|
||||
/* If no slot info pair is provided, the node owns no slots */
|
||||
addReplyArrayLen(c, 0);
|
||||
@@ -5946,7 +5956,7 @@ NULL
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"nodes") && c->argc == 2) {
|
||||
/* CLUSTER NODES */
|
||||
/* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */
|
||||
sds nodes = clusterGenNodesDescription(c, 0, connIsTLS(c->conn));
|
||||
sds nodes = clusterGenNodesDescription(c, 0, shouldReturnTlsInfo());
|
||||
addReplyVerbatim(c,nodes,sdslen(nodes),"txt");
|
||||
sdsfree(nodes);
|
||||
} else if (!strcasecmp(c->argv[1]->ptr,"myid") && c->argc == 2) {
|
||||
@@ -6312,7 +6322,7 @@ NULL
|
||||
/* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */
|
||||
addReplyArrayLen(c,n->numslaves);
|
||||
for (j = 0; j < n->numslaves; j++) {
|
||||
sds ni = clusterGenNodeDescription(c, n->slaves[j], connIsTLS(c->conn));
|
||||
sds ni = clusterGenNodeDescription(c, n->slaves[j], shouldReturnTlsInfo());
|
||||
addReplyBulkCString(c,ni);
|
||||
sdsfree(ni);
|
||||
}
|
||||
@@ -7438,7 +7448,7 @@ void clusterRedirectClient(client *c, clusterNode *n, int hashslot, int error_co
|
||||
error_code == CLUSTER_REDIR_ASK)
|
||||
{
|
||||
/* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */
|
||||
int port = getNodeClientPort(n, connIsTLS(c->conn));
|
||||
int port = getNodeClientPort(n, shouldReturnTlsInfo());
|
||||
addReplyErrorSds(c,sdscatprintf(sdsempty(),
|
||||
"-%s %d %s:%d",
|
||||
(error_code == CLUSTER_REDIR_ASK) ? "ASK" : "MOVED",
|
||||
|
||||
+76
-21
@@ -1391,7 +1391,10 @@ struct COMMAND_ARG CLIENT_REPLY_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* CLIENT SETINFO tips */
|
||||
#define CLIENT_SETINFO_Tips NULL
|
||||
const char *CLIENT_SETINFO_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -1419,7 +1422,10 @@ struct COMMAND_ARG CLIENT_SETINFO_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* CLIENT SETNAME tips */
|
||||
#define CLIENT_SETNAME_Tips NULL
|
||||
const char *CLIENT_SETNAME_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -1543,8 +1549,8 @@ struct COMMAND_STRUCT CLIENT_Subcommands[] = {
|
||||
{MAKE_CMD("no-touch","Controls whether commands sent by the client affect the LRU/LFU of accessed keys.","O(1)","7.2.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_NO_TOUCH_History,0,CLIENT_NO_TOUCH_Tips,0,clientCommand,3,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,ACL_CATEGORY_CONNECTION,CLIENT_NO_TOUCH_Keyspecs,0,NULL,1),.args=CLIENT_NO_TOUCH_Args},
|
||||
{MAKE_CMD("pause","Suspends commands processing.","O(1)","3.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_PAUSE_History,1,CLIENT_PAUSE_Tips,0,clientCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_PAUSE_Keyspecs,0,NULL,2),.args=CLIENT_PAUSE_Args},
|
||||
{MAKE_CMD("reply","Instructs the server whether to reply to commands.","O(1)","3.2.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_REPLY_History,0,CLIENT_REPLY_Tips,0,clientCommand,3,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_REPLY_Keyspecs,0,NULL,1),.args=CLIENT_REPLY_Args},
|
||||
{MAKE_CMD("setinfo","Sets information specific to the client or connection.","O(1)","7.2.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_SETINFO_History,0,CLIENT_SETINFO_Tips,0,clientSetinfoCommand,4,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_SETINFO_Keyspecs,0,NULL,1),.args=CLIENT_SETINFO_Args},
|
||||
{MAKE_CMD("setname","Sets the connection name.","O(1)","2.6.9",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_SETNAME_History,0,CLIENT_SETNAME_Tips,0,clientCommand,3,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_SETNAME_Keyspecs,0,NULL,1),.args=CLIENT_SETNAME_Args},
|
||||
{MAKE_CMD("setinfo","Sets information specific to the client or connection.","O(1)","7.2.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_SETINFO_History,0,CLIENT_SETINFO_Tips,2,clientSetinfoCommand,4,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_SETINFO_Keyspecs,0,NULL,1),.args=CLIENT_SETINFO_Args},
|
||||
{MAKE_CMD("setname","Sets the connection name.","O(1)","2.6.9",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_SETNAME_History,0,CLIENT_SETNAME_Tips,2,clientCommand,3,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_SETNAME_Keyspecs,0,NULL,1),.args=CLIENT_SETNAME_Args},
|
||||
{MAKE_CMD("tracking","Controls server-assisted client-side caching for the connection.","O(1). Some options may introduce additional complexity.","6.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_TRACKING_History,0,CLIENT_TRACKING_Tips,0,clientCommand,-3,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_TRACKING_Keyspecs,0,NULL,7),.args=CLIENT_TRACKING_Args},
|
||||
{MAKE_CMD("trackinginfo","Returns information about server-assisted client-side caching for the connection.","O(1)","6.2.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_TRACKINGINFO_History,0,CLIENT_TRACKINGINFO_Tips,0,clientCommand,2,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_TRACKINGINFO_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("unblock","Unblocks a client blocked by a blocking command from a different connection.","O(log N) where N is the number of client connections","5.0.0",CMD_DOC_NONE,NULL,NULL,"connection",COMMAND_GROUP_CONNECTION,CLIENT_UNBLOCK_History,0,CLIENT_UNBLOCK_Tips,0,clientCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,ACL_CATEGORY_CONNECTION,CLIENT_UNBLOCK_Keyspecs,0,NULL,2),.args=CLIENT_UNBLOCK_Args},
|
||||
@@ -5886,7 +5892,10 @@ struct COMMAND_ARG ACL_CAT_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* ACL DELUSER tips */
|
||||
#define ACL_DELUSER_Tips NULL
|
||||
const char *ACL_DELUSER_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -6060,7 +6069,10 @@ struct COMMAND_ARG ACL_LOG_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* ACL SAVE tips */
|
||||
#define ACL_SAVE_Tips NULL
|
||||
const char *ACL_SAVE_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -6080,7 +6092,10 @@ commandHistory ACL_SETUSER_History[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* ACL SETUSER tips */
|
||||
#define ACL_SETUSER_Tips NULL
|
||||
const char *ACL_SETUSER_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -6131,7 +6146,7 @@ struct COMMAND_ARG ACL_SETUSER_Args[] = {
|
||||
/* ACL command table */
|
||||
struct COMMAND_STRUCT ACL_Subcommands[] = {
|
||||
{MAKE_CMD("cat","Lists the ACL categories, or the commands inside a category.","O(1) since the categories and commands are a fixed set.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_CAT_History,0,ACL_CAT_Tips,0,aclCommand,-2,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_CAT_Keyspecs,0,NULL,1),.args=ACL_CAT_Args},
|
||||
{MAKE_CMD("deluser","Deletes ACL users, and terminates their connections.","O(1) amortized time considering the typical user.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_DELUSER_History,0,ACL_DELUSER_Tips,0,aclCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_DELUSER_Keyspecs,0,NULL,1),.args=ACL_DELUSER_Args},
|
||||
{MAKE_CMD("deluser","Deletes ACL users, and terminates their connections.","O(1) amortized time considering the typical user.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_DELUSER_History,0,ACL_DELUSER_Tips,2,aclCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_DELUSER_Keyspecs,0,NULL,1),.args=ACL_DELUSER_Args},
|
||||
{MAKE_CMD("dryrun","Simulates the execution of a command by a user, without executing the command.","O(1).","7.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_DRYRUN_History,0,ACL_DRYRUN_Tips,0,aclCommand,-4,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_DRYRUN_Keyspecs,0,NULL,3),.args=ACL_DRYRUN_Args},
|
||||
{MAKE_CMD("genpass","Generates a pseudorandom, secure password that can be used to identify ACL users.","O(1)","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_GENPASS_History,0,ACL_GENPASS_Tips,0,aclCommand,-2,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_GENPASS_Keyspecs,0,NULL,1),.args=ACL_GENPASS_Args},
|
||||
{MAKE_CMD("getuser","Lists the ACL rules of a user.","O(N). Where N is the number of password, command and pattern rules that the user has.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_GETUSER_History,2,ACL_GETUSER_Tips,0,aclCommand,3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_GETUSER_Keyspecs,0,NULL,1),.args=ACL_GETUSER_Args},
|
||||
@@ -6139,8 +6154,8 @@ struct COMMAND_STRUCT ACL_Subcommands[] = {
|
||||
{MAKE_CMD("list","Dumps the effective rules in ACL file format.","O(N). Where N is the number of configured users.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_LIST_History,0,ACL_LIST_Tips,0,aclCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_LIST_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("load","Reloads the rules from the configured ACL file.","O(N). Where N is the number of configured users.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_LOAD_History,0,ACL_LOAD_Tips,0,aclCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_LOAD_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("log","Lists recent security events generated due to ACL rules.","O(N) with N being the number of entries shown.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_LOG_History,1,ACL_LOG_Tips,0,aclCommand,-2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_LOG_Keyspecs,0,NULL,1),.args=ACL_LOG_Args},
|
||||
{MAKE_CMD("save","Saves the effective ACL rules in the configured ACL file.","O(N). Where N is the number of configured users.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_SAVE_History,0,ACL_SAVE_Tips,0,aclCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_SAVE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("setuser","Creates and modifies an ACL user and its rules.","O(N). Where N is the number of rules provided.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_SETUSER_History,2,ACL_SETUSER_Tips,0,aclCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_SETUSER_Keyspecs,0,NULL,2),.args=ACL_SETUSER_Args},
|
||||
{MAKE_CMD("save","Saves the effective ACL rules in the configured ACL file.","O(N). Where N is the number of configured users.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_SAVE_History,0,ACL_SAVE_Tips,2,aclCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_SAVE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("setuser","Creates and modifies an ACL user and its rules.","O(N). Where N is the number of rules provided.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_SETUSER_History,2,ACL_SETUSER_Tips,2,aclCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_SETUSER_Keyspecs,0,NULL,2),.args=ACL_SETUSER_Args},
|
||||
{MAKE_CMD("users","Lists all ACL users.","O(N). Where N is the number of configured users.","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_USERS_History,0,ACL_USERS_Tips,0,aclCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_USERS_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("whoami","Returns the authenticated username of the current connection.","O(1)","6.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ACL_WHOAMI_History,0,ACL_WHOAMI_Tips,0,aclCommand,2,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_SENTINEL,0,ACL_WHOAMI_Keyspecs,0,NULL,0)},
|
||||
{0}
|
||||
@@ -6446,7 +6461,10 @@ struct COMMAND_ARG CONFIG_GET_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* CONFIG RESETSTAT tips */
|
||||
#define CONFIG_RESETSTAT_Tips NULL
|
||||
const char *CONFIG_RESETSTAT_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -6463,7 +6481,10 @@ struct COMMAND_ARG CONFIG_GET_Args[] = {
|
||||
|
||||
#ifndef SKIP_CMD_TIPS_TABLE
|
||||
/* CONFIG REWRITE tips */
|
||||
#define CONFIG_REWRITE_Tips NULL
|
||||
const char *CONFIG_REWRITE_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef SKIP_CMD_KEY_SPECS_TABLE
|
||||
@@ -6508,8 +6529,8 @@ struct COMMAND_ARG CONFIG_SET_Args[] = {
|
||||
struct COMMAND_STRUCT CONFIG_Subcommands[] = {
|
||||
{MAKE_CMD("get","Returns the effective values of configuration parameters.","O(N) when N is the number of configuration parameters provided","2.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_GET_History,1,CONFIG_GET_Tips,0,configGetCommand,-3,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_GET_Keyspecs,0,NULL,1),.args=CONFIG_GET_Args},
|
||||
{MAKE_CMD("help","Returns helpful text about the different subcommands.","O(1)","5.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_HELP_History,0,CONFIG_HELP_Tips,0,configHelpCommand,2,CMD_LOADING|CMD_STALE,0,CONFIG_HELP_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("resetstat","Resets the server's statistics.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_RESETSTAT_History,0,CONFIG_RESETSTAT_Tips,0,configResetStatCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_RESETSTAT_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("rewrite","Persists the effective configuration to file.","O(1)","2.8.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_REWRITE_History,0,CONFIG_REWRITE_Tips,0,configRewriteCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_REWRITE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("resetstat","Resets the server's statistics.","O(1)","2.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_RESETSTAT_History,0,CONFIG_RESETSTAT_Tips,2,configResetStatCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_RESETSTAT_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("rewrite","Persists the effective configuration to file.","O(1)","2.8.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_REWRITE_History,0,CONFIG_REWRITE_Tips,2,configRewriteCommand,2,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_REWRITE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("set","Sets configuration parameters in-flight.","O(N) when N is the number of configuration parameters provided","2.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,CONFIG_SET_History,1,CONFIG_SET_Tips,2,configSetCommand,-4,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,CONFIG_SET_Keyspecs,0,NULL,1),.args=CONFIG_SET_Args},
|
||||
{0}
|
||||
};
|
||||
@@ -6862,7 +6883,7 @@ const char *LATENCY_LATEST_Tips[] = {
|
||||
/* LATENCY RESET tips */
|
||||
const char *LATENCY_RESET_Tips[] = {
|
||||
"request_policy:all_nodes",
|
||||
"response_policy:all_succeeded",
|
||||
"response_policy:agg_sum",
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -7292,12 +7313,29 @@ struct COMMAND_ARG PSYNC_Args[] = {
|
||||
#define REPLICAOF_Keyspecs NULL
|
||||
#endif
|
||||
|
||||
/* REPLICAOF argument table */
|
||||
struct COMMAND_ARG REPLICAOF_Args[] = {
|
||||
/* REPLICAOF args host_port argument table */
|
||||
struct COMMAND_ARG REPLICAOF_args_host_port_Subargs[] = {
|
||||
{MAKE_ARG("host",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("port",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
};
|
||||
|
||||
/* REPLICAOF args no_one argument table */
|
||||
struct COMMAND_ARG REPLICAOF_args_no_one_Subargs[] = {
|
||||
{MAKE_ARG("no",ARG_TYPE_PURE_TOKEN,-1,"NO",NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("one",ARG_TYPE_PURE_TOKEN,-1,"ONE",NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
};
|
||||
|
||||
/* REPLICAOF args argument table */
|
||||
struct COMMAND_ARG REPLICAOF_args_Subargs[] = {
|
||||
{MAKE_ARG("host-port",ARG_TYPE_BLOCK,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=REPLICAOF_args_host_port_Subargs},
|
||||
{MAKE_ARG("no-one",ARG_TYPE_BLOCK,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=REPLICAOF_args_no_one_Subargs},
|
||||
};
|
||||
|
||||
/* REPLICAOF argument table */
|
||||
struct COMMAND_ARG REPLICAOF_Args[] = {
|
||||
{MAKE_ARG("args",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=REPLICAOF_args_Subargs},
|
||||
};
|
||||
|
||||
/********** RESTORE_ASKING ********************/
|
||||
|
||||
#ifndef SKIP_CMD_HISTORY_TABLE
|
||||
@@ -7416,12 +7454,29 @@ struct COMMAND_ARG SHUTDOWN_Args[] = {
|
||||
#define SLAVEOF_Keyspecs NULL
|
||||
#endif
|
||||
|
||||
/* SLAVEOF argument table */
|
||||
struct COMMAND_ARG SLAVEOF_Args[] = {
|
||||
/* SLAVEOF args host_port argument table */
|
||||
struct COMMAND_ARG SLAVEOF_args_host_port_Subargs[] = {
|
||||
{MAKE_ARG("host",ARG_TYPE_STRING,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("port",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
};
|
||||
|
||||
/* SLAVEOF args no_one argument table */
|
||||
struct COMMAND_ARG SLAVEOF_args_no_one_Subargs[] = {
|
||||
{MAKE_ARG("no",ARG_TYPE_PURE_TOKEN,-1,"NO",NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("one",ARG_TYPE_PURE_TOKEN,-1,"ONE",NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
};
|
||||
|
||||
/* SLAVEOF args argument table */
|
||||
struct COMMAND_ARG SLAVEOF_args_Subargs[] = {
|
||||
{MAKE_ARG("host-port",ARG_TYPE_BLOCK,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=SLAVEOF_args_host_port_Subargs},
|
||||
{MAKE_ARG("no-one",ARG_TYPE_BLOCK,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=SLAVEOF_args_no_one_Subargs},
|
||||
};
|
||||
|
||||
/* SLAVEOF argument table */
|
||||
struct COMMAND_ARG SLAVEOF_Args[] = {
|
||||
{MAKE_ARG("args",ARG_TYPE_ONEOF,-1,NULL,NULL,NULL,CMD_ARG_NONE,2,NULL),.subargs=SLAVEOF_args_Subargs},
|
||||
};
|
||||
|
||||
/********** SLOWLOG GET ********************/
|
||||
|
||||
#ifndef SKIP_CMD_HISTORY_TABLE
|
||||
@@ -10731,12 +10786,12 @@ struct COMMAND_STRUCT redisCommandTable[] = {
|
||||
{MAKE_CMD("monitor","Listens for all requests received by the server in real-time.",NULL,"1.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,MONITOR_History,0,MONITOR_Tips,0,monitorCommand,1,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE,0,MONITOR_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("psync","An internal command used in replication.",NULL,"2.8.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,PSYNC_History,0,PSYNC_Tips,0,syncCommand,-3,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NO_MULTI|CMD_NOSCRIPT,0,PSYNC_Keyspecs,0,NULL,2),.args=PSYNC_Args},
|
||||
{MAKE_CMD("replconf","An internal command for configuring the replication stream.","O(1)","3.0.0",CMD_DOC_SYSCMD,NULL,NULL,"server",COMMAND_GROUP_SERVER,REPLCONF_History,0,REPLCONF_Tips,0,replconfCommand,-1,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_ALLOW_BUSY,0,REPLCONF_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("replicaof","Configures a server as replica of another, or promotes it to a master.","O(1)","5.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,REPLICAOF_History,0,REPLICAOF_Tips,0,replicaofCommand,3,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NOSCRIPT|CMD_STALE,0,REPLICAOF_Keyspecs,0,NULL,2),.args=REPLICAOF_Args},
|
||||
{MAKE_CMD("replicaof","Configures a server as replica of another, or promotes it to a master.","O(1)","5.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,REPLICAOF_History,0,REPLICAOF_Tips,0,replicaofCommand,3,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NOSCRIPT|CMD_STALE,0,REPLICAOF_Keyspecs,0,NULL,1),.args=REPLICAOF_Args},
|
||||
{MAKE_CMD("restore-asking","An internal command for migrating keys in a cluster.","O(1) to create the new key and additional O(N*M) to reconstruct the serialized value, where N is the number of Redis objects composing the value and M their average size. For small string values the time complexity is thus O(1)+O(1*M) where M is small, so simply O(1). However for sorted set values the complexity is O(N*M*log(N)) because inserting values into sorted sets is O(log(N)).","3.0.0",CMD_DOC_SYSCMD,NULL,NULL,"server",COMMAND_GROUP_SERVER,RESTORE_ASKING_History,3,RESTORE_ASKING_Tips,0,restoreCommand,-4,CMD_WRITE|CMD_DENYOOM|CMD_ASKING,ACL_CATEGORY_KEYSPACE|ACL_CATEGORY_DANGEROUS,RESTORE_ASKING_Keyspecs,1,NULL,7),.args=RESTORE_ASKING_Args},
|
||||
{MAKE_CMD("role","Returns the replication role.","O(1)","2.8.12",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,ROLE_History,0,ROLE_Tips,0,roleCommand,1,CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_FAST|CMD_SENTINEL,ACL_CATEGORY_ADMIN|ACL_CATEGORY_DANGEROUS,ROLE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("save","Synchronously saves the database(s) to disk.","O(N) where N is the total number of keys in all databases","1.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,SAVE_History,0,SAVE_Tips,0,saveCommand,1,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NOSCRIPT|CMD_NO_MULTI,0,SAVE_Keyspecs,0,NULL,0)},
|
||||
{MAKE_CMD("shutdown","Synchronously saves the database(s) to disk and shuts down the Redis server.","O(N) when saving, where N is the total number of keys in all databases when saving data, otherwise O(1)","1.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,SHUTDOWN_History,1,SHUTDOWN_Tips,0,shutdownCommand,-1,CMD_ADMIN|CMD_NOSCRIPT|CMD_LOADING|CMD_STALE|CMD_NO_MULTI|CMD_SENTINEL|CMD_ALLOW_BUSY,0,SHUTDOWN_Keyspecs,0,NULL,4),.args=SHUTDOWN_Args},
|
||||
{MAKE_CMD("slaveof","Sets a Redis server as a replica of another, or promotes it to being a master.","O(1)","1.0.0",CMD_DOC_DEPRECATED,"`REPLICAOF`","5.0.0","server",COMMAND_GROUP_SERVER,SLAVEOF_History,0,SLAVEOF_Tips,0,replicaofCommand,3,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NOSCRIPT|CMD_STALE,0,SLAVEOF_Keyspecs,0,NULL,2),.args=SLAVEOF_Args},
|
||||
{MAKE_CMD("slaveof","Sets a Redis server as a replica of another, or promotes it to being a master.","O(1)","1.0.0",CMD_DOC_DEPRECATED,"`REPLICAOF`","5.0.0","server",COMMAND_GROUP_SERVER,SLAVEOF_History,0,SLAVEOF_Tips,0,replicaofCommand,3,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NOSCRIPT|CMD_STALE,0,SLAVEOF_Keyspecs,0,NULL,1),.args=SLAVEOF_Args},
|
||||
{MAKE_CMD("slowlog","A container for slow log commands.","Depends on subcommand.","2.2.12",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,SLOWLOG_History,0,SLOWLOG_Tips,0,NULL,-2,0,0,SLOWLOG_Keyspecs,0,NULL,0),.subcommands=SLOWLOG_Subcommands},
|
||||
{MAKE_CMD("swapdb","Swaps two Redis databases.","O(N) where N is the count of clients watching or blocking on keys from both databases.","4.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,SWAPDB_History,0,SWAPDB_Tips,0,swapdbCommand,3,CMD_WRITE|CMD_FAST,ACL_CATEGORY_KEYSPACE|ACL_CATEGORY_DANGEROUS,SWAPDB_Keyspecs,0,NULL,2),.args=SWAPDB_Args},
|
||||
{MAKE_CMD("sync","An internal command used in replication.",NULL,"1.0.0",CMD_DOC_NONE,NULL,NULL,"server",COMMAND_GROUP_SERVER,SYNC_History,0,SYNC_Tips,0,syncCommand,1,CMD_NO_ASYNC_LOADING|CMD_ADMIN|CMD_NO_MULTI|CMD_NOSCRIPT,0,SYNC_Keyspecs,0,NULL,0)},
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
"STALE",
|
||||
"SENTINEL"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"reply_schema": {
|
||||
"type": "integer",
|
||||
"description": "The number of users that were deleted"
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
"STALE",
|
||||
"SENTINEL"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"reply_schema": {
|
||||
"const": "OK"
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
"STALE",
|
||||
"SENTINEL"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"reply_schema": {
|
||||
"const": "OK"
|
||||
},
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
"STALE",
|
||||
"SENTINEL"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"acl_categories": [
|
||||
"CONNECTION"
|
||||
],
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
"STALE",
|
||||
"SENTINEL"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"acl_categories": [
|
||||
"CONNECTION"
|
||||
],
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"description": "an even number element array specifying the start and end slot numbers for slot ranges owned by this shard",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
"LOADING",
|
||||
"STALE"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"reply_schema": {
|
||||
"const": "OK"
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
"LOADING",
|
||||
"STALE"
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
],
|
||||
"reply_schema": {
|
||||
"const": "OK"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
],
|
||||
"command_tips": [
|
||||
"REQUEST_POLICY:ALL_NODES",
|
||||
"RESPONSE_POLICY:ALL_SUCCEEDED"
|
||||
"RESPONSE_POLICY:AGG_SUM"
|
||||
],
|
||||
"reply_schema": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -14,12 +14,40 @@
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"type": "integer"
|
||||
"name": "args",
|
||||
"type": "oneof",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host-port",
|
||||
"type": "block",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"type": "integer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "no-one",
|
||||
"type": "block",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "no",
|
||||
"type": "pure-token",
|
||||
"token": "NO"
|
||||
},
|
||||
{
|
||||
"name": "one",
|
||||
"type": "pure-token",
|
||||
"token": "ONE"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"reply_schema": {
|
||||
|
||||
@@ -19,12 +19,40 @@
|
||||
],
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"type": "integer"
|
||||
"name": "args",
|
||||
"type": "oneof",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host-port",
|
||||
"type": "block",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "host",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "port",
|
||||
"type": "integer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "no-one",
|
||||
"type": "block",
|
||||
"arguments": [
|
||||
{
|
||||
"name": "no",
|
||||
"type": "pure-token",
|
||||
"token": "NO"
|
||||
},
|
||||
{
|
||||
"name": "one",
|
||||
"type": "pure-token",
|
||||
"token": "ONE"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"reply_schema": {
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "GET option is specified, but no object was found ",
|
||||
"description": "GET option is specified, but no object was found",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -117,7 +117,15 @@
|
||||
"description": "a list of sorted elements",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "GET option is specified, but no object was found",
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -40,8 +40,12 @@
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
#define MAC_OS_10_6_DETECTED
|
||||
#endif
|
||||
|
||||
/* Define redis_fstat to fstat or fstat64() */
|
||||
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
|
||||
#if defined(__APPLE__) && !defined(MAC_OS_10_6_DETECTED)
|
||||
#define redis_fstat fstat64
|
||||
#define redis_stat stat64
|
||||
#else
|
||||
@@ -96,7 +100,7 @@
|
||||
#define HAVE_ACCEPT4 1
|
||||
#endif
|
||||
|
||||
#if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
|
||||
#if (defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
|
||||
#define HAVE_KQUEUE 1
|
||||
#endif
|
||||
|
||||
@@ -293,7 +297,7 @@ void setproctitle(const char *fmt, ...);
|
||||
#include <kernel/OS.h>
|
||||
#define redis_set_thread_title(name) rename_thread(find_thread(0), name)
|
||||
#else
|
||||
#if (defined __APPLE__ && defined(MAC_OS_X_VERSION_10_7))
|
||||
#if (defined __APPLE__ && defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070)
|
||||
int pthread_setname_np(const char *name);
|
||||
#include <pthread.h>
|
||||
#define redis_set_thread_title(name) pthread_setname_np(name)
|
||||
|
||||
@@ -2294,7 +2294,8 @@ int sortROGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult
|
||||
keys = getKeysPrepareResult(result, 1);
|
||||
keys[0].pos = 1; /* <sort-key> is always present. */
|
||||
keys[0].flags = CMD_KEY_RO | CMD_KEY_ACCESS;
|
||||
return 1;
|
||||
result->numkeys = 1;
|
||||
return result->numkeys;
|
||||
}
|
||||
|
||||
/* Helper function to extract keys from the SORT command.
|
||||
|
||||
+3
-3
@@ -1190,7 +1190,7 @@ static void* getAndSetMcontextEip(ucontext_t *uc, void *eip) {
|
||||
} \
|
||||
return old_val; \
|
||||
} while(0)
|
||||
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
|
||||
#if defined(__APPLE__) && !defined(MAC_OS_10_6_DETECTED)
|
||||
/* OSX < 10.6 */
|
||||
#if defined(__x86_64__)
|
||||
GET_SET_RETURN(uc->uc_mcontext->__ss.__rip, eip);
|
||||
@@ -1199,7 +1199,7 @@ static void* getAndSetMcontextEip(ucontext_t *uc, void *eip) {
|
||||
#else
|
||||
GET_SET_RETURN(uc->uc_mcontext->__ss.__srr0, eip);
|
||||
#endif
|
||||
#elif defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
|
||||
#elif defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)
|
||||
/* OSX >= 10.6 */
|
||||
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
|
||||
GET_SET_RETURN(uc->uc_mcontext->__ss.__rip, eip);
|
||||
@@ -1290,7 +1290,7 @@ void logRegisters(ucontext_t *uc) {
|
||||
} while(0)
|
||||
|
||||
/* OSX */
|
||||
#if defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
|
||||
#if defined(__APPLE__) && defined(MAC_OS_10_6_DETECTED)
|
||||
/* OSX AMD64 */
|
||||
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
|
||||
serverLog(LL_WARNING,
|
||||
|
||||
@@ -1657,6 +1657,7 @@ static int cliConnect(int flags) {
|
||||
redisFree(context);
|
||||
config.dbnum = 0;
|
||||
config.in_multi = 0;
|
||||
config.pubsub_mode = 0;
|
||||
cliRefreshPrompt();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
#define REDIS_VERSION "7.2.0"
|
||||
#define REDIS_VERSION_NUM 0x00070200
|
||||
#define REDIS_VERSION "7.2.2"
|
||||
#define REDIS_VERSION_NUM 0x00070202
|
||||
|
||||
+8
-2
@@ -75,12 +75,14 @@ start_server {
|
||||
assert_equal [lsort -integer $result] [r sort tosort GET #]
|
||||
} {} {cluster:skip}
|
||||
|
||||
test "SORT GET <const>" {
|
||||
foreach command {SORT SORT_RO} {
|
||||
test "$command GET <const>" {
|
||||
r del foo
|
||||
set res [r sort tosort GET foo]
|
||||
set res [r $command tosort GET foo]
|
||||
assert_equal 16 [llength $res]
|
||||
foreach item $res { assert_equal {} $item }
|
||||
} {} {cluster:skip}
|
||||
}
|
||||
|
||||
test "SORT GET (key and hash) with sanity check" {
|
||||
set l1 [r sort tosort GET # GET weight_*]
|
||||
@@ -109,6 +111,10 @@ start_server {
|
||||
test "SORT extracts STORE correctly" {
|
||||
r command getkeys sort abc store def
|
||||
} {abc def}
|
||||
|
||||
test "SORT_RO get keys" {
|
||||
r command getkeys sort_ro abc
|
||||
} {abc}
|
||||
|
||||
test "SORT extracts multiple STORE correctly" {
|
||||
r command getkeys sort abc store invalid store stillbad store def
|
||||
|
||||
@@ -140,6 +140,37 @@ tags {"wait aof network external:skip"} {
|
||||
assert_error {ERR WAITAOF cannot be used when numlocal is set but appendonly is disabled.} {$master waitaof 1 0 0}
|
||||
}
|
||||
|
||||
test {WAITAOF local if AOFRW was postponed} {
|
||||
r config set appendfsync everysec
|
||||
|
||||
# turn off AOF
|
||||
r config set appendonly no
|
||||
|
||||
# create an RDB child that takes a lot of time to run
|
||||
r set x y
|
||||
r config set rdb-key-save-delay 100000000 ;# 100 seconds
|
||||
r bgsave
|
||||
assert_equal [s rdb_bgsave_in_progress] 1
|
||||
|
||||
# turn on AOF
|
||||
r config set appendonly yes
|
||||
assert_equal [s aof_rewrite_scheduled] 1
|
||||
|
||||
# create a write command (to increment master_repl_offset)
|
||||
r set x y
|
||||
|
||||
# reset save_delay and kill RDB child
|
||||
r config set rdb-key-save-delay 0
|
||||
catch {exec kill -9 [get_child_pid 0]}
|
||||
|
||||
# wait for AOF (will unblock after AOFRW finishes)
|
||||
assert_equal [r waitaof 1 0 10000] {1 0}
|
||||
|
||||
# make sure AOFRW finished
|
||||
assert_equal [s aof_rewrite_in_progress] 0
|
||||
assert_equal [s aof_rewrite_scheduled] 0
|
||||
}
|
||||
|
||||
$master config set appendonly yes
|
||||
waitForBgrewriteaof $master
|
||||
|
||||
|
||||
Reference in New Issue
Block a user