From cd63359a1767b929ab542093e9bd0a67281308f1 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 29 May 2020 11:07:13 +0200 Subject: [PATCH 01/15] Fix handling of special chars in ACL LOAD. Now it is also possible for ACL SETUSER to accept empty strings as valid operations (doing nothing), so for instance ACL SETUSER myuser "" Will have just the effect of creating a user in the default state. This should fix #7329. --- src/acl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/acl.c b/src/acl.c index c3a724c33..6dd0f70ac 100644 --- a/src/acl.c +++ b/src/acl.c @@ -732,10 +732,11 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) { * EEXIST: You are adding a key pattern after "*" was already added. This is * almost surely an error on the user side. * ENODEV: The password you are trying to remove from the user does not exist. - * EBADMSG: The hash you are trying to add is not a valid hash. + * EBADMSG: The hash you are trying to add is not a valid hash. */ int ACLSetUser(user *u, const char *op, ssize_t oplen) { if (oplen == -1) oplen = strlen(op); + if (oplen == 0) return C_OK; /* Empty string is a no-operation. */ if (!strcasecmp(op,"on")) { u->flags |= USER_FLAG_ENABLED; u->flags &= ~USER_FLAG_DISABLED; @@ -1297,7 +1298,7 @@ sds ACLLoadFromFile(const char *filename) { if (lines[i][0] == '\0') continue; /* Split into arguments */ - argv = sdssplitargs(lines[i],&argc); + argv = sdssplitlen(lines[i],sdslen(lines[i])," ",1,&argc); if (argv == NULL) { errors = sdscatprintf(errors, "%s:%d: unbalanced quotes in acl line. ", @@ -1329,11 +1330,14 @@ sds ACLLoadFromFile(const char *filename) { continue; } - /* Try to process the line using the fake user to validate iif - * the rules are able to apply cleanly. */ + /* Try to process the line using the fake user to validate if + * the rules are able to apply cleanly. At this stage we also + * trim trailing spaces, so that we don't have to handle that + * in ACLSetUser(). */ ACLSetUser(fakeuser,"reset",-1); int j; for (j = 2; j < argc; j++) { + argv[j] = sdstrim(argv[j],"\t\r\n"); if (ACLSetUser(fakeuser,argv[j],sdslen(argv[j])) != C_OK) { char *errmsg = ACLSetUserStringError(); errors = sdscatprintf(errors, From 84a7a90586d9302ccd65fb61c47b9970c13cf363 Mon Sep 17 00:00:00 2001 From: Liu Zhen Date: Wed, 27 May 2020 11:55:23 +0800 Subject: [PATCH 02/15] fix clusters mixing accidentally by gossip `clusterStartHandshake` will start hand handshake and eventually send CLUSTER MEET message, which is strictly prohibited in the REDIS CLUSTER SPEC. Only system administrator can initiate CLUSTER MEET message. Futher, according to the SPEC, rather than IP/PORT pairs, only nodeid can be trusted. --- src/cluster.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index a2fab323a..24b14d1dc 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1463,7 +1463,10 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { } } else { /* If it's not in NOADDR state and we don't have it, we - * start a handshake process against this IP/PORT pairs. + * add it to our trusted dict with exact nodeid and flag. + * Note that we cannot simply start a handshake against + * this IP/PORT pairs, since IP/PORT can be reused already, + * otherwise we risk joining another cluster. * * Note that we require that the sender of this gossip message * is a well known node in our cluster, otherwise we risk @@ -1472,7 +1475,12 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) { !(flags & CLUSTER_NODE_NOADDR) && !clusterBlacklistExists(g->nodename)) { - clusterStartHandshake(g->ip,ntohs(g->port),ntohs(g->cport)); + clusterNode *node; + node = createClusterNode(g->nodename, flags); + memcpy(node->ip,g->ip,NET_IP_STR_LEN); + node->port = ntohs(g->port); + node->cport = ntohs(g->cport); + clusterAddNode(node); } } From 925a2cd5aacdb83f307e4418417feabb5024dae9 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 6 Jun 2020 11:42:41 +0200 Subject: [PATCH 03/15] Revert "avoid using sendfile if tls-replication is enabled" This reverts commit b9abecfc4c97db01fa6f09180c68a92ea5974ac1. --- src/replication.c | 65 +++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/src/replication.c b/src/replication.c index 063a8705e..7b15944a0 100644 --- a/src/replication.c +++ b/src/replication.c @@ -1067,46 +1067,39 @@ void sendBulkToSlave(connection *conn) { } } - /* If the preamble was already transferred, send the RDB bulk data. - * try to use sendfile system call if supported, unless tls is enabled. - * fallback to normal read+write otherwise. */ - nwritten = 0; + /* If the preamble was already transferred, send the RDB bulk data. */ #if HAVE_SENDFILE - if (!server.tls_replication) { - if ((nwritten = redis_sendfile(conn->fd,slave->repldbfd, - slave->repldboff,PROTO_IOBUF_LEN)) == -1) - { - if (errno != EAGAIN) { - serverLog(LL_WARNING,"Sendfile error sending DB to replica: %s", - strerror(errno)); - freeClient(slave); - } - return; + if ((nwritten = redis_sendfile(conn->fd,slave->repldbfd, + slave->repldboff,PROTO_IOBUF_LEN)) == -1) + { + if (errno != EAGAIN) { + serverLog(LL_WARNING,"Sendfile error sending DB to replica: %s", + strerror(errno)); + freeClient(slave); } + return; + } +#else + ssize_t buflen; + char buf[PROTO_IOBUF_LEN]; + + lseek(slave->repldbfd,slave->repldboff,SEEK_SET); + buflen = read(slave->repldbfd,buf,PROTO_IOBUF_LEN); + if (buflen <= 0) { + serverLog(LL_WARNING,"Read error sending DB to replica: %s", + (buflen == 0) ? "premature EOF" : strerror(errno)); + freeClient(slave); + return; + } + if ((nwritten = connWrite(conn,buf,buflen)) == -1) { + if (connGetState(conn) != CONN_STATE_CONNECTED) { + serverLog(LL_WARNING,"Write error sending DB to replica: %s", + connGetLastError(conn)); + freeClient(slave); + } + return; } #endif - if (!nwritten) { - ssize_t buflen; - char buf[PROTO_IOBUF_LEN]; - - lseek(slave->repldbfd,slave->repldboff,SEEK_SET); - buflen = read(slave->repldbfd,buf,PROTO_IOBUF_LEN); - if (buflen <= 0) { - serverLog(LL_WARNING,"Read error sending DB to replica: %s", - (buflen == 0) ? "premature EOF" : strerror(errno)); - freeClient(slave); - return; - } - if ((nwritten = connWrite(conn,buf,buflen)) == -1) { - if (connGetState(conn) != CONN_STATE_CONNECTED) { - serverLog(LL_WARNING,"Write error sending DB to replica: %s", - connGetLastError(conn)); - freeClient(slave); - } - return; - } - } - slave->repldboff += nwritten; server.stat_net_output_bytes += nwritten; if (slave->repldboff == slave->repldbsize) { From 329fddbda1baf6779f806840668320a4d25eceb7 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 6 Jun 2020 11:42:45 +0200 Subject: [PATCH 04/15] Revert "Implements sendfile for redis." This reverts commit 9cf500a3f67e4e2ce51414c354e3472faf095d5b. --- src/config.h | 6 ------ src/replication.c | 51 ++--------------------------------------------- 2 files changed, 2 insertions(+), 55 deletions(-) diff --git a/src/config.h b/src/config.h index 23de5d3ad..0fcc42972 100644 --- a/src/config.h +++ b/src/config.h @@ -133,12 +133,6 @@ void setproctitle(const char *fmt, ...); /* Byte ordering detection */ #include /* This will likely define BYTE_ORDER */ -/* Define redis_sendfile. */ -#if defined(__linux__) || (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_5)) -#define HAVE_SENDFILE 1 -ssize_t redis_sendfile(int out_fd, int in_fd, off_t offset, size_t count); -#endif - #ifndef BYTE_ORDER #if (BSD >= 199103) # include diff --git a/src/replication.c b/src/replication.c index 7b15944a0..d9bff79ad 100644 --- a/src/replication.c +++ b/src/replication.c @@ -1008,41 +1008,10 @@ void removeRDBUsedToSyncReplicas(void) { } } -#if HAVE_SENDFILE -/* Implements redis_sendfile to transfer data between file descriptors and - * avoid transferring data to and from user space. - * - * The function prototype is just like sendfile(2) on Linux. in_fd is a file - * descriptor opened for reading and out_fd is a descriptor opened for writing. - * offset specifies where to start reading data from in_fd. count is the number - * of bytes to copy between the file descriptors. - * - * The return value is the number of bytes written to out_fd, if the transfer - * was successful. On error, -1 is returned, and errno is set appropriately. */ -ssize_t redis_sendfile(int out_fd, int in_fd, off_t offset, size_t count) { -#if defined(__linux__) - #include - return sendfile(out_fd, in_fd, &offset, count); - -#elif defined(__APPLE__) - off_t len = count; - /* Notice that it may return -1 and errno is set to EAGAIN even if some - * bytes have been sent successfully and the len argument is set correctly - * when using a socket marked for non-blocking I/O. */ - if (sendfile(in_fd, out_fd, offset, &len, NULL, 0) == -1 && - errno != EAGAIN) return -1; - else - return (ssize_t)len; - -#endif - errno = ENOSYS; - return -1; -} -#endif - void sendBulkToSlave(connection *conn) { client *slave = connGetPrivateData(conn); - ssize_t nwritten; + char buf[PROTO_IOBUF_LEN]; + ssize_t nwritten, buflen; /* Before sending the RDB file, we send the preamble as configured by the * replication process. Currently the preamble is just the bulk count of @@ -1068,21 +1037,6 @@ void sendBulkToSlave(connection *conn) { } /* If the preamble was already transferred, send the RDB bulk data. */ -#if HAVE_SENDFILE - if ((nwritten = redis_sendfile(conn->fd,slave->repldbfd, - slave->repldboff,PROTO_IOBUF_LEN)) == -1) - { - if (errno != EAGAIN) { - serverLog(LL_WARNING,"Sendfile error sending DB to replica: %s", - strerror(errno)); - freeClient(slave); - } - return; - } -#else - ssize_t buflen; - char buf[PROTO_IOBUF_LEN]; - lseek(slave->repldbfd,slave->repldboff,SEEK_SET); buflen = read(slave->repldbfd,buf,PROTO_IOBUF_LEN); if (buflen <= 0) { @@ -1099,7 +1053,6 @@ void sendBulkToSlave(connection *conn) { } return; } -#endif slave->repldboff += nwritten; server.stat_net_output_bytes += nwritten; if (slave->repldboff == slave->repldbsize) { From 49af4d07e43c63f44bb3cd92b498f43422919fc9 Mon Sep 17 00:00:00 2001 From: Kevin Fwu Date: Wed, 27 May 2020 08:53:29 -0400 Subject: [PATCH 05/15] Fix TLS certificate loading for chained certificates. This impacts client verification for chained certificates (such as Lets Encrypt certificates). Client Verify requires the full chain in order to properly verify the certificate. --- src/tls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tls.c b/src/tls.c index 28a74df9a..a62f2284e 100644 --- a/src/tls.c +++ b/src/tls.c @@ -217,7 +217,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) { SSL_CTX_set_ecdh_auto(ctx, 1); #endif - if (SSL_CTX_use_certificate_file(ctx, ctx_config->cert_file, SSL_FILETYPE_PEM) <= 0) { + if (SSL_CTX_use_certificate_chain_file(ctx, ctx_config->cert_file) <= 0) { ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf)); serverLog(LL_WARNING, "Failed to load certificate: %s: %s", ctx_config->cert_file, errbuf); goto error; From f33de403edd1ab9bd1edee97708fadb8bdd0adf9 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Sun, 31 May 2020 15:51:52 +0300 Subject: [PATCH 06/15] fix pingoff test race --- tests/integration/psync2-pingoff.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integration/psync2-pingoff.tcl b/tests/integration/psync2-pingoff.tcl index 5a9a46d16..cdecfc5c6 100644 --- a/tests/integration/psync2-pingoff.tcl +++ b/tests/integration/psync2-pingoff.tcl @@ -64,6 +64,7 @@ start_server {} { # make sure replication is still alive and kicking $R(1) incr x wait_for_condition 50 1000 { + [status $R(0) loading] == 0 && [$R(0) get x] == 1 } else { fail "replica didn't get incr" From 4846c0c8af3226c7a2d575ff93391b9cf0590655 Mon Sep 17 00:00:00 2001 From: "zhaozhao.zz" Date: Tue, 2 Jun 2020 11:34:28 +0800 Subject: [PATCH 07/15] donot free protected client in freeClientsInAsyncFreeQueue related #7234 --- src/networking.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/networking.c b/src/networking.c index 8d3e057b7..cc28732d1 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1239,14 +1239,20 @@ void freeClientAsync(client *c) { /* Free the clietns marked as CLOSE_ASAP, return the number of clients * freed. */ int freeClientsInAsyncFreeQueue(void) { - int freed = listLength(server.clients_to_close); - while (listLength(server.clients_to_close)) { - listNode *ln = listFirst(server.clients_to_close); + int freed = 0; + listIter li; + listNode *ln; + + listRewind(server.clients_to_close,&li); + while ((ln = listNext(&li)) != NULL) { client *c = listNodeValue(ln); + if (c->flags & CLIENT_PROTECTED) continue; + c->flags &= ~CLIENT_CLOSE_ASAP; freeClient(c); listDelNode(server.clients_to_close,ln); + freed++; } return freed; } From 676445ad953724221d11d4de1d1ea1ed955cd474 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Mon, 8 Jun 2020 09:50:06 +0300 Subject: [PATCH 08/15] fix disconnectSlaves, to try to free each slave. the recent change in that loop (iteration rather than waiting for it to be empty) was intended to avoid an endless loop in case some slave would refuse to be freed. but the lookup of the first client remained, which would have caused it to try the first one again and again instead of moving on. --- src/networking.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/networking.c b/src/networking.c index cc28732d1..80973109c 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1019,7 +1019,6 @@ void disconnectSlaves(void) { listNode *ln; listRewind(server.slaves,&li); while((ln = listNext(&li))) { - listNode *ln = listFirst(server.slaves); freeClient((client*)ln->value); } } From 1d7bf208ce1697d7e2000c44407c5146f0232122 Mon Sep 17 00:00:00 2001 From: "zhaozhao.zz" Date: Wed, 3 Jun 2020 17:55:18 +0800 Subject: [PATCH 09/15] AOF: append origin SET if no expire option --- src/aof.c | 21 +++++++++++++-------- tests/unit/expire.tcl | 10 ++++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/aof.c b/src/aof.c index 02409abe6..6f8e53712 100644 --- a/src/aof.c +++ b/src/aof.c @@ -611,19 +611,24 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a } else if (cmd->proc == setCommand && argc > 3) { int i; robj *exarg = NULL, *pxarg = NULL; - /* Translate SET [EX seconds][PX milliseconds] to SET and PEXPIREAT */ - buf = catAppendOnlyGenericCommand(buf,3,argv); for (i = 3; i < argc; i ++) { if (!strcasecmp(argv[i]->ptr, "ex")) exarg = argv[i+1]; if (!strcasecmp(argv[i]->ptr, "px")) pxarg = argv[i+1]; } serverAssert(!(exarg && pxarg)); - if (exarg) - buf = catAppendOnlyExpireAtCommand(buf,server.expireCommand,argv[1], - exarg); - if (pxarg) - buf = catAppendOnlyExpireAtCommand(buf,server.pexpireCommand,argv[1], - pxarg); + + if (exarg || pxarg) { + /* Translate SET [EX seconds][PX milliseconds] to SET and PEXPIREAT */ + buf = catAppendOnlyGenericCommand(buf,3,argv); + if (exarg) + buf = catAppendOnlyExpireAtCommand(buf,server.expireCommand,argv[1], + exarg); + if (pxarg) + buf = catAppendOnlyExpireAtCommand(buf,server.pexpireCommand,argv[1], + pxarg); + } else { + buf = catAppendOnlyGenericCommand(buf,argc,argv); + } } else { /* All the other commands don't need translation or need the * same translation already operated in the command vector diff --git a/tests/unit/expire.tcl b/tests/unit/expire.tcl index 11fb82ef0..52d174d75 100644 --- a/tests/unit/expire.tcl +++ b/tests/unit/expire.tcl @@ -232,4 +232,14 @@ start_server {tags {"expire"}} { set ttl [r ttl foo] assert {$ttl <= 100 && $ttl > 90} } + + test {SET - use KEEPTTL option, TTL should not be removed after loadaof} { + r config set appendonly yes + r set foo bar EX 100 + r set foo bar2 KEEPTTL + after 2000 + r debug loadaof + set ttl [r ttl foo] + assert {$ttl <= 98 && $ttl > 90} + } } From b35fdf1de1aa91bd0f625f6f3a9fd9930c1b3d55 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Mon, 8 Jun 2020 09:16:32 +0300 Subject: [PATCH 10/15] Avoid rejecting WATCH / UNWATCH, like MULTI/EXEC/DISCARD Much like MULTI/EXEC/DISCARD, the WATCH and UNWATCH are not actually operating on the database or server state, but instead operate on the client state. the client may send them all in one long pipeline and check all the responses only at the end, so failing them may lead to a mismatch between the client state on the server and the one on the client end, and execute the wrong commands (ones that were meant to be discarded) the watched keys are not actually stored in the client struct, but they are in fact part of the client state. for instance, they're not cleared or moved in SWAPDB or FLUSHDB. --- src/server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server.c b/src/server.c index b7a6a928f..e8e711240 100644 --- a/src/server.c +++ b/src/server.c @@ -776,11 +776,11 @@ struct redisCommand redisCommandTable[] = { 0,NULL,0,0,0,0,0,0}, {"watch",watchCommand,-2, - "no-script fast @transaction", + "no-script fast ok-loading ok-stale @transaction", 0,NULL,1,-1,1,0,0,0}, {"unwatch",unwatchCommand,1, - "no-script fast @transaction", + "no-script fast ok-loading ok-stale @transaction", 0,NULL,0,0,0,0,0,0}, {"cluster",clusterCommand,-2, @@ -3627,6 +3627,8 @@ int processCommand(client *c) { c->cmd->proc != multiCommand && c->cmd->proc != execCommand && c->cmd->proc != discardCommand && + c->cmd->proc != watchCommand && + c->cmd->proc != unwatchCommand && !(c->cmd->proc == shutdownCommand && c->argc == 2 && tolower(((char*)c->argv[1]->ptr)[0]) == 'n') && From e2046b300373093e0e4640e97d6dbdb8bb7cd221 Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Mon, 8 Jun 2020 09:43:10 +0300 Subject: [PATCH 11/15] Don't queue commands in an already aborted MULTI state --- src/multi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/multi.c b/src/multi.c index a331a6240..3e606fcec 100644 --- a/src/multi.c +++ b/src/multi.c @@ -58,6 +58,13 @@ void queueMultiCommand(client *c) { multiCmd *mc; int j; + /* No sense to waste memory if the transaction is already aborted. + * this is useful in case client sends these in a pipeline, or doesn't + * bother to read previous responses and didn't notice the multi was already + * aborted. */ + if (c->flags & CLIENT_DIRTY_EXEC) + return; + c->mstate.commands = zrealloc(c->mstate.commands, sizeof(multiCmd)*(c->mstate.count+1)); mc = c->mstate.commands+c->mstate.count; From a4a856d5326dbce60b907a4ef5a1b5379ba52c85 Mon Sep 17 00:00:00 2001 From: xhe Date: Sun, 7 Jun 2020 13:34:55 +0800 Subject: [PATCH 12/15] return the correct proto version HELLO should return the current proto version, while the code hardcoded 3 --- src/networking.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/networking.c b/src/networking.c index 80973109c..77b9a6fcf 100644 --- a/src/networking.c +++ b/src/networking.c @@ -2527,7 +2527,7 @@ void helloCommand(client *c) { addReplyBulkCString(c,REDIS_VERSION); addReplyBulkCString(c,"proto"); - addReplyLongLong(c,3); + addReplyLongLong(c,ver); addReplyBulkCString(c,"id"); addReplyLongLong(c,c->id); From ee8dd01bbcaab39c643b005c4acb93c132b07aa3 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 9 Jun 2020 11:52:33 +0200 Subject: [PATCH 13/15] Temporary fix for #7353 issue about EVAL during -BUSY. --- src/multi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/multi.c b/src/multi.c index 3e606fcec..60a07dfc7 100644 --- a/src/multi.c +++ b/src/multi.c @@ -135,6 +135,15 @@ void execCommand(client *c) { return; } + /* If we are in -BUSY state, flag the transaction and return the + * -BUSY error, like Redis <= 5. This is a temporary fix, may be changed + * ASAP, see issue #7353 on Github. */ + if (server.lua_timedout) { + flagTransaction(c); + addReply(c, shared.slowscripterr); + return; + } + /* Check if we need to abort the EXEC because: * 1) Some WATCHed key was touched. * 2) There was a previous error while queueing commands. From a7d3670da5dfb7afe35e46130f516bbddd3918dc Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 9 Jun 2020 12:19:14 +0200 Subject: [PATCH 14/15] Adapt EVAL+busy script test to new behavior. --- tests/unit/multi.tcl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unit/multi.tcl b/tests/unit/multi.tcl index 55f18bec8..0c70fbde7 100644 --- a/tests/unit/multi.tcl +++ b/tests/unit/multi.tcl @@ -363,6 +363,9 @@ start_server {tags {"multi"}} { set xx [r get xx] # make sure that either the whole transcation passed or none of it (we actually expect none) assert { $xx == 1 || $xx == 3} + # Discard the transaction since EXEC likely got -BUSY error + # so the client is still in MULTI state. + catch { $rd2 discard ;$rd2 read } e # check that the connection is no longer in multi state $rd2 ping asdf set pong [$rd2 read] From 51efb7fe25753867d39aa88a521f7c275fd8cddb Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 9 Jun 2020 12:00:15 +0200 Subject: [PATCH 15/15] Redis 6.0.5. --- 00-RELEASENOTES | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ src/version.h | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/00-RELEASENOTES b/00-RELEASENOTES index 7ce88c556..c6ee44246 100644 --- a/00-RELEASENOTES +++ b/00-RELEASENOTES @@ -11,6 +11,76 @@ CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. SECURITY: There are security fixes in the release. -------------------------------------------------------------------------------- +================================================================================ +Redis 6.0.5 Released Tue Jun 09 11:56:08 CEST 2020 +================================================================================ + +Upgrade urgency MODERATE: several bugs with moderate impact are fixed here. + +The most important issues are listed here: + +* Fix handling of speical chars in ACL LOAD. +* Make Redis Cluster more robust about operation errors that may lead + to two clusters to mix together. +* Revert the sendfile() implementation of RDB transfer. It causes some delay. +* Fix TLS certificate loading for chained certificates. +* Fix AOF rewirting of KEEPTTL SET option. +* Fix MULTI/EXEC behavior during -BUSY script errors. + +And this is the full list of commits: + +antirez in commit ee8dd01bb: + Temporary fix for #7353 issue about EVAL during -BUSY. + 1 file changed, 9 insertions(+) + +xhe in commit a4a856d53: + return the correct proto version HELLO should return the current proto version, while the code hardcoded 3 + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit e2046b300: + Don't queue commands in an already aborted MULTI state + 1 file changed, 7 insertions(+) + +Oran Agra in commit b35fdf1de: + Avoid rejecting WATCH / UNWATCH, like MULTI/EXEC/DISCARD + 1 file changed, 4 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit 1d7bf208c: + AOF: append origin SET if no expire option + 2 files changed, 23 insertions(+), 8 deletions(-) + +Oran Agra in commit 676445ad9: + fix disconnectSlaves, to try to free each slave. + 1 file changed, 1 deletion(-) + +zhaozhao.zz in commit 4846c0c8a: + donot free protected client in freeClientsInAsyncFreeQueue + 1 file changed, 9 insertions(+), 3 deletions(-) + +Oran Agra in commit f33de403e: + fix pingoff test race + 1 file changed, 1 insertion(+) + +Kevin Fwu in commit 49af4d07e: + Fix TLS certificate loading for chained certificates. + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 329fddbda: + Revert "Implements sendfile for redis." + 2 files changed, 2 insertions(+), 55 deletions(-) + +antirez in commit 925a2cd5a: + Revert "avoid using sendfile if tls-replication is enabled" + 1 file changed, 27 insertions(+), 34 deletions(-) + +Liu Zhen in commit 84a7a9058: + fix clusters mixing accidentally by gossip + 1 file changed, 10 insertions(+), 2 deletions(-) + +antirez in commit cd63359a1: + Fix handling of special chars in ACL LOAD. + 1 file changed, 8 insertions(+), 4 deletions(-) + ================================================================================ Redis 6.0.4 Released Thu May 28 11:36:45 CEST 2020 ================================================================================ diff --git a/src/version.h b/src/version.h index 8efc3c5aa..e1eb096f3 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define REDIS_VERSION "6.0.4" +#define REDIS_VERSION "6.0.5"