From 0c211a1953afeda3d0d45126653e2d4c38bd88cb Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 5 Dec 2014 10:51:09 +0100 Subject: [PATCH 01/25] Simplify lua_cmsgpack macro and fix build on old Linux distros. Thanks to @badboy for the help in checking the build after the fix. --- deps/lua/src/lua_cmsgpack.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/deps/lua/src/lua_cmsgpack.c b/deps/lua/src/lua_cmsgpack.c index 6aa04e2f110..4ccf07f6d47 100644 --- a/deps/lua/src/lua_cmsgpack.c +++ b/deps/lua/src/lua_cmsgpack.c @@ -18,14 +18,8 @@ #define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */ #endif -#if (_XOPEN_SOURCE >= 600 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L) - #define IS_FINITE(x) isfinite(x) -#else - #define IS_FINITE(x) ((x) == (x) && (x) + 1 > (x)) -#endif - /* Check if float or double can be an integer without loss of precision */ -#define IS_INT_TYPE_EQUIVALENT(x, T) (IS_FINITE(x) && (T)(x) == (x)) +#define IS_INT_TYPE_EQUIVALENT(x, T) (!isinf(x) && (T)(x) == (x)) #define IS_INT64_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int64_t) #define IS_INT_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int) From 2f3c8609793d9999ecadd089bc4e319e729ce76b Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 9 Dec 2014 00:57:46 +0100 Subject: [PATCH 02/25] Only ignore sigpipe in interactive mode This allows shell pipes to correctly end redis-cli. Ref #2066 --- src/redis-cli.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/redis-cli.c b/src/redis-cli.c index a3caf6b5a4a..fc1265c3f88 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -1915,8 +1915,6 @@ int main(int argc, char **argv) { argc -= firstarg; argv += firstarg; - signal(SIGPIPE, SIG_IGN); - /* Latency mode */ if (config.latency_mode) { if (cliConnect(0) == REDIS_ERR) exit(1); @@ -1965,6 +1963,9 @@ int main(int argc, char **argv) { /* Start interactive mode when no command is provided */ if (argc == 0 && !config.eval) { + /* Ignore SIGPIPE in interactive mode to force a reconnect */ + signal(SIGPIPE, SIG_IGN); + /* Note that in repl mode we don't abort on connection error. * A new attempt will be performed for every command send. */ cliConnect(0); From 7d480abab498fd48b645291184d421060fc85ef7 Mon Sep 17 00:00:00 2001 From: Sun He Date: Mon, 8 Dec 2014 11:15:06 +0800 Subject: [PATCH 03/25] sparkline.c: mov label-ini into the AddSample Function --- src/latency.c | 4 +--- src/sparkline.c | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/latency.c b/src/latency.c index 9875aa16496..cb116fb9033 100644 --- a/src/latency.c +++ b/src/latency.c @@ -512,7 +512,6 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { for (j = 0; j < LATENCY_TS_LEN; j++) { int i = (ts->idx + j) % LATENCY_TS_LEN; int elapsed; - char *label; char buf[64]; if (ts->samples[i].time == 0) continue; @@ -534,8 +533,7 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { snprintf(buf,sizeof(buf),"%dh",elapsed/3600); else snprintf(buf,sizeof(buf),"%dd",elapsed/(3600*24)); - label = zstrdup(buf); - sparklineSequenceAddSample(seq,ts->samples[i].latency,label); + sparklineSequenceAddSample(seq,ts->samples[i].latency,buf); } graph = sdscatprintf(graph, diff --git a/src/sparkline.c b/src/sparkline.c index 900f26ab727..3355a598cda 100644 --- a/src/sparkline.c +++ b/src/sparkline.c @@ -49,7 +49,7 @@ static int label_margin_top = 1; * sparklineSequenceAddSample(seq, 10, NULL); * sparklineSequenceAddSample(seq, 20, NULL); * sparklineSequenceAddSample(seq, 30, "last sample label"); - * sds output = sparklineRender(seq, 80, 4); + * sds output = sparklineRender(sdsempty(), seq, 80, 4, SPARKLINE_FILL); * freeSparklineSequence(seq); * ------------------------------------------------------------------------- */ @@ -63,6 +63,7 @@ struct sequence *createSparklineSequence(void) { /* Add a new sample into a sequence. */ void sparklineSequenceAddSample(struct sequence *seq, double value, char *label) { + label = label == NULL ? label : zstrdup(label); if (seq->length == 0) { seq->min = seq->max = value; } else { From a598e0894b518643db39acf11b98adcf3e584009 Mon Sep 17 00:00:00 2001 From: Sun He Date: Mon, 8 Dec 2014 11:43:32 +0800 Subject: [PATCH 04/25] sparkline.c: AddSample skip Empty label --- src/sparkline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sparkline.c b/src/sparkline.c index 3355a598cda..8e2764aeec4 100644 --- a/src/sparkline.c +++ b/src/sparkline.c @@ -63,7 +63,7 @@ struct sequence *createSparklineSequence(void) { /* Add a new sample into a sequence. */ void sparklineSequenceAddSample(struct sequence *seq, double value, char *label) { - label = label == NULL ? label : zstrdup(label); + label = (label == NULL || label[0] == '\0') ? NULL : zstrdup(label); if (seq->length == 0) { seq->min = seq->max = value; } else { From b5737d2d197199ad1648b642f02088b9d6e8b2a3 Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Fri, 5 Dec 2014 14:50:45 +0200 Subject: [PATCH 05/25] getting pid fixes ```sh $ ~ pidof redis-server # nothing $ ~ ps aux | grep [r]edis redis 593 0.0 0.0 36900 5564 ? Ssl Dec02 1:37 /usr/bin/redis-server 127.0.0.1:6379 klay 15927 0.0 0.0 16772 6068 pts/6 S+ 13:58 0:00 redis-cli $ ~ uname -a Linux edge 3.17.4-1-ARCH #1 SMP PREEMPT Fri Nov 21 21:14:42 CET 2014 x86_64 GNU/Linux ``` --- utils/whatisdoing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/whatisdoing.sh b/utils/whatisdoing.sh index 8f441cfc01a..1e51e390518 100755 --- a/utils/whatisdoing.sh +++ b/utils/whatisdoing.sh @@ -3,7 +3,7 @@ #!/bin/bash nsamples=1 sleeptime=0 -pid=$(pidof redis-server) +pid=$(ps auxww | grep 'redis-server' | grep -v grep | awk '{print $2}') for x in $(seq 1 $nsamples) do From a47a042ea69caaa4a30197dd559e9b13c5423347 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 9 Dec 2014 12:18:34 +0100 Subject: [PATCH 06/25] Mark whatisdoing.sh as deprecated in top-comment. --- utils/whatisdoing.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utils/whatisdoing.sh b/utils/whatisdoing.sh index 1e51e390518..23cacc2156b 100755 --- a/utils/whatisdoing.sh +++ b/utils/whatisdoing.sh @@ -1,4 +1,10 @@ # This script is from http://poormansprofiler.org/ +# +# NOTE: Instead of using this script, you should use the Redis +# Software Watchdog, which provides a similar functionality but in +# a more reliable / easy to use way. +# +# Check http://redis.io/topics/latency for more information. #!/bin/bash nsamples=1 From 23b96c02a511f1d7864338777793df54db510245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bergstr=C3=B6m?= Date: Fri, 5 Dec 2014 12:41:59 +1100 Subject: [PATCH 07/25] Silence _BSD_SOURCE warnings in glibc 2.20 and forward See https://sourceware.org/glibc/wiki/Release/2.20#Packaging_Changes --- src/fmacros.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fmacros.h b/src/fmacros.h index e49735ce523..6e56c759dd5 100644 --- a/src/fmacros.h +++ b/src/fmacros.h @@ -34,6 +34,7 @@ #if defined(__linux__) #define _GNU_SOURCE +#define _DEFAULT_SOURCE #endif #if defined(_AIX) From d409371193179a104a12d977dbe18132d24013cc Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 1 Dec 2014 23:22:03 +0100 Subject: [PATCH 08/25] Fix implicit declaration of ioctl on Solaris --- src/memtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/memtest.c b/src/memtest.c index 18d821b10f7..e424e528b84 100644 --- a/src/memtest.c +++ b/src/memtest.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "config.h" #if (ULONG_MAX == 4294967295UL) From 77b997d42922c95f0964bd47db428f85aa6e1d58 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 9 Dec 2014 12:59:36 +0100 Subject: [PATCH 09/25] Include stropts only if __sun is defined. --- src/memtest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/memtest.c b/src/memtest.c index e424e528b84..39fc4fcaad4 100644 --- a/src/memtest.c +++ b/src/memtest.c @@ -35,7 +35,9 @@ #include #include #include +#if defined(__sun) #include +#endif #include "config.h" #if (ULONG_MAX == 4294967295UL) From 2ed3f09cc39f54fceb42dae2a9b4dd86a72983ea Mon Sep 17 00:00:00 2001 From: Serghei Iakovlev Date: Fri, 5 Dec 2014 18:48:20 +0200 Subject: [PATCH 10/25] Update whatisdoing.sh Improved getting pid --- utils/whatisdoing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/whatisdoing.sh b/utils/whatisdoing.sh index 23cacc2156b..e4059caeddc 100755 --- a/utils/whatisdoing.sh +++ b/utils/whatisdoing.sh @@ -9,7 +9,7 @@ #!/bin/bash nsamples=1 sleeptime=0 -pid=$(ps auxww | grep 'redis-server' | grep -v grep | awk '{print $2}') +pid=$(ps auxww | grep '[r]edis-server' | awk '{print $2}') for x in $(seq 1 $nsamples) do From d2f584fa53ee30f876bdd17f17b3d76d673d6419 Mon Sep 17 00:00:00 2001 From: Sun He Date: Sun, 2 Nov 2014 10:40:28 +0800 Subject: [PATCH 11/25] sds.c: Correct some comments --- src/sds.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sds.c b/src/sds.c index 0ad925b4ab3..36ae56c99f1 100644 --- a/src/sds.c +++ b/src/sds.c @@ -295,7 +295,7 @@ sds sdscpy(sds s, const char *t) { * conversion. 's' must point to a string with room for at least * SDS_LLSTR_SIZE bytes. * - * The function returns the lenght of the null-terminated string + * The function returns the lengh of the null-terminated string * representation stored at 's'. */ #define SDS_LLSTR_SIZE 21 int sdsll2str(char *s, long long value) { @@ -415,7 +415,7 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) { * * Example: * - * s = sdsempty("Sum is: "); + * s = sdsnew("Sum is: "); * s = sdscatprintf(s,"%d+%d = %d",a,b,a+b). * * Often you need to create a string from scratch with the printf-alike @@ -643,8 +643,8 @@ void sdstoupper(sds s) { * * Return value: * - * 1 if s1 > s2. - * -1 if s1 < s2. + * positive if s1 > s2. + * negative if s1 < s2. * 0 if s1 and s2 are exactly the same binary string. * * If two strings share exactly the same prefix, but one of the two has From 4848cf93357771b37f55bf1187a3756bd8ce354d Mon Sep 17 00:00:00 2001 From: Sun He Date: Sun, 2 Nov 2014 10:42:26 +0800 Subject: [PATCH 12/25] sds.c/sdscatvprintf: set va_end to finish va_list cpy --- src/sds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sds.c b/src/sds.c index 36ae56c99f1..6370a25e5cf 100644 --- a/src/sds.c +++ b/src/sds.c @@ -390,7 +390,7 @@ sds sdscatvprintf(sds s, const char *fmt, va_list ap) { buf[buflen-2] = '\0'; va_copy(cpy,ap); vsnprintf(buf, buflen, fmt, cpy); - va_end(ap); + va_end(cpy); if (buf[buflen-2] != '\0') { if (buf != staticbuf) zfree(buf); buflen *= 2; From 76d53a677082d571354452b43b2a32c39575dcb3 Mon Sep 17 00:00:00 2001 From: Sun He Date: Mon, 3 Nov 2014 17:21:54 +0800 Subject: [PATCH 13/25] sds.c: Correct two spelling mistakes in comments --- src/sds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sds.c b/src/sds.c index 6370a25e5cf..5a3bc82b11c 100644 --- a/src/sds.c +++ b/src/sds.c @@ -295,7 +295,7 @@ sds sdscpy(sds s, const char *t) { * conversion. 's' must point to a string with room for at least * SDS_LLSTR_SIZE bytes. * - * The function returns the lengh of the null-terminated string + * The function returns the length of the null-terminated string * representation stored at 's'. */ #define SDS_LLSTR_SIZE 21 int sdsll2str(char *s, long long value) { @@ -369,7 +369,7 @@ sds sdsfromlonglong(long long value) { return sdsnewlen(buf,len); } -/* Like sdscatpritf() but gets va_list instead of being variadic. */ +/* Like sdscatprintf() but gets va_list instead of being variadic. */ sds sdscatvprintf(sds s, const char *fmt, va_list ap) { va_list cpy; char staticbuf[1024], *buf = staticbuf, *t; From 3d73f088e1589b2eac900b20f18da75d57569e09 Mon Sep 17 00:00:00 2001 From: azure provisioned user Date: Mon, 1 Dec 2014 21:42:40 +0000 Subject: [PATCH 14/25] redis-benchmark AUTH command to be discarded after the first send #2150 --- src/redis-benchmark.c | 58 ++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index 76c755dd2e1..ef8d8ff8304 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -90,9 +90,10 @@ typedef struct _client { long long start; /* Start time of a request */ long long latency; /* Request latency */ int pending; /* Number of pending requests (replies to consume) */ - int selectlen; /* If non-zero, a SELECT of 'selectlen' bytes is currently - used as a prefix of the pipline of commands. This gets - discarded the first time it's sent. */ + int prefix_pending; /* If non-zero, number of pending prefix commands. Commands + such as auth and select are prefixed to the pipeline of + benchmark commands and discarded after the first send. */ + int prefixlen; /* Size in bytes of the pending prefix commands */ } *client; /* Prototypes */ @@ -212,20 +213,21 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { } freeReplyObject(reply); - - if (c->selectlen) { - size_t j; - - /* This is the OK from SELECT. Just discard the SELECT - * from the buffer. */ + // This is an OK for prefix commands such as auth and select. + if (c->prefix_pending > 0) { + c->prefix_pending--; c->pending--; - sdsrange(c->obuf,c->selectlen,-1); - /* We also need to fix the pointers to the strings - * we need to randomize. */ - for (j = 0; j < c->randlen; j++) - c->randptr[j] -= c->selectlen; - c->selectlen = 0; - continue; + // Discard prefix commands on first response. + if (c->prefixlen > 0) { + size_t j; + sdsrange(c->obuf, c->prefixlen, -1); + /* We also need to fix the pointers to the strings + * we need to randomize. */ + for (j = 0; j < c->randlen; j++) + c->randptr[j] -= c->prefixlen; + c->prefixlen = 0; + } + continue; } if (config.requests_finished < config.requests) @@ -299,8 +301,7 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) { * 2) The offsets of the __rand_int__ elements inside the command line, used * for arguments randomization. * - * Even when cloning another client, the SELECT command is automatically prefixed - * if needed. */ + * Even when cloning another client, prefix commands are applied if needed.*/ static client createClient(char *cmd, size_t len, client from) { int j; client c = zmalloc(sizeof(struct _client)); @@ -325,12 +326,16 @@ static client createClient(char *cmd, size_t len, client from) { * Queue N requests accordingly to the pipeline size, or simply clone * the example client buffer. */ c->obuf = sdsempty(); - + /* Prefix the request buffer with AUTH and/or SELECT commands, if applicable. + * These commands are discarded after the first response, so if the client is + * reused the commands will not be used again. */ + c->prefix_pending = 0; if (config.auth) { char *buf = NULL; int len = redisFormatCommand(&buf, "AUTH %s", config.auth); c->obuf = sdscatlen(c->obuf, buf, len); free(buf); + c->prefix_pending++; } /* If a DB number different than zero is selected, prefix our request @@ -340,26 +345,23 @@ static client createClient(char *cmd, size_t len, client from) { if (config.dbnum != 0) { c->obuf = sdscatprintf(c->obuf,"*2\r\n$6\r\nSELECT\r\n$%d\r\n%s\r\n", (int)sdslen(config.dbnumstr),config.dbnumstr); - c->selectlen = sdslen(c->obuf); - } else { - c->selectlen = 0; + c->prefix_pending++; } - + c->prefixlen = sdslen(c->obuf); /* Append the request itself. */ if (from) { c->obuf = sdscatlen(c->obuf, - from->obuf+from->selectlen, - sdslen(from->obuf)-from->selectlen); + from->obuf+from->prefixlen, + sdslen(from->obuf)-from->prefixlen); } else { for (j = 0; j < config.pipeline; j++) c->obuf = sdscatlen(c->obuf,cmd,len); } c->written = 0; - c->pending = config.pipeline; + c->pending = config.pipeline+c->prefix_pending; c->randptr = NULL; c->randlen = 0; - if (c->selectlen) c->pending++; /* Find substrings in the output buffer that need to be randomized. */ if (config.randomkeys) { @@ -371,7 +373,7 @@ static client createClient(char *cmd, size_t len, client from) { for (j = 0; j < (int)c->randlen; j++) { c->randptr[j] = c->obuf + (from->randptr[j]-from->obuf); /* Adjust for the different select prefix length. */ - c->randptr[j] += c->selectlen - from->selectlen; + c->randptr[j] += c->prefixlen - from->prefixlen; } } else { char *p = c->obuf; From 86ebc139c28bc960a4e25e87a90130f150d6e394 Mon Sep 17 00:00:00 2001 From: Deepak Verma Date: Mon, 1 Dec 2014 22:54:49 +0000 Subject: [PATCH 15/25] replaced // comments #2150 --- src/redis-benchmark.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index ef8d8ff8304..ddf891e2d83 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -213,11 +213,11 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { } freeReplyObject(reply); - // This is an OK for prefix commands such as auth and select. + /* This is an OK for prefix commands such as auth and select.*/ if (c->prefix_pending > 0) { c->prefix_pending--; c->pending--; - // Discard prefix commands on first response. + /* Discard prefix commands on first response.*/ if (c->prefixlen > 0) { size_t j; sdsrange(c->obuf, c->prefixlen, -1); From 888ea175486a9e297cb219ad953c49f2790dc516 Mon Sep 17 00:00:00 2001 From: Sun He Date: Tue, 25 Nov 2014 21:58:05 +0800 Subject: [PATCH 16/25] zipmap.c: update comments above --- src/zipmap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/zipmap.c b/src/zipmap.c index 803fedeec12..384b76bbae5 100644 --- a/src/zipmap.c +++ b/src/zipmap.c @@ -51,10 +51,9 @@ * is the length of the following string (key or value). * lengths are encoded in a single value or in a 5 bytes value. * If the first byte value (as an unsigned 8 bit value) is between 0 and - * 252, it's a single-byte length. If it is 253 then a four bytes unsigned + * 253, it's a single-byte length. If it is 254 then a four bytes unsigned * integer follows (in the host byte ordering). A value of 255 is used to - * signal the end of the hash. The special value 254 is used to mark - * empty space that can be used to add new key/value pairs. + * signal the end of the hash. * * is the number of free unused bytes after the string, resulting * from modification of values associated to a key. For instance if "foo" From dba57ea910599eb475a8c25bce6dac64590de3ea Mon Sep 17 00:00:00 2001 From: zhanghailei Date: Mon, 27 Oct 2014 14:02:52 +0800 Subject: [PATCH 17/25] FIXED redis-benchmark's idle mode.With idle mode shouldn't create write event --- src/redis-benchmark.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index ddf891e2d83..8c9304dec3b 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -392,7 +392,8 @@ static client createClient(char *cmd, size_t len, client from) { } } } - aeCreateFileEvent(config.el,c->context->fd,AE_WRITABLE,writeHandler,c); + if (config.idlemode == 0) + aeCreateFileEvent(config.el,c->context->fd,AE_WRITABLE,writeHandler,c); listAddNodeTail(config.clients,c); config.liveclients++; return c; @@ -601,9 +602,13 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData if (config.liveclients == 0) { fprintf(stderr,"All clients disconnected... aborting.\n"); exit(1); - } - + } if (config.csv) return 250; + if (config.idlemode == 1) { + printf("clients: %d\r", config.liveclients); + fflush(stdout); + return 250; + } float dt = (float)(mstime()-config.start)/1000.0; float rps = (float)config.requests_finished/dt; printf("%s: %.2f\r", config.title, rps); From d81c38316bdd1a501a6d225d7c97e1421538e645 Mon Sep 17 00:00:00 2001 From: Ben Dowling Date: Sun, 26 Oct 2014 11:09:45 -0700 Subject: [PATCH 18/25] Update redis_init_script.tpl status command currently reports success when redis has crashed and the pid file still exists. Changing to check the actual process is running. --- utils/redis_init_script.tpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/redis_init_script.tpl b/utils/redis_init_script.tpl index d650863126a..2e5b61301d5 100755 --- a/utils/redis_init_script.tpl +++ b/utils/redis_init_script.tpl @@ -26,11 +26,12 @@ case "$1" in fi ;; status) - if [ ! -f $PIDFILE ] + PID=$(cat $PIDFILE) + if [ ! -x /proc/${PID} ] then echo 'Redis is not running' else - echo "Redis is running ($(<$PIDFILE))" + echo "Redis is running ($PID)" fi ;; restart) From e945a546afd3f97b4f8b5231d44d2c46597469ea Mon Sep 17 00:00:00 2001 From: Matt Stancliff Date: Thu, 23 Oct 2014 11:52:35 -0400 Subject: [PATCH 19/25] Fix zero-ordering SORT when called against lists People mostly use SORT against lists, but our prior behavior was pretending lists were an unordered bag requiring a forced-sort when no sort was requested. We can just use the native list ordering to ensure consistency across replicaion and scripting calls. Closes #2079 Closes #545 (again) --- src/sort.c | 15 ++++++--------- tests/unit/sort.tcl | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/sort.c b/src/sort.c index 474a3cf6434..f813ff26b16 100644 --- a/src/sort.c +++ b/src/sort.c @@ -264,16 +264,13 @@ void sortCommand(redisClient *c) { j++; } - /* For the STORE option, or when SORT is called from a Lua script, - * we want to force a specific ordering even when no explicit ordering - * was asked (SORT BY nosort). This guarantees that replication / AOF - * is deterministic. + /* When sorting a set with no sort specified, we must sort the output + * so the result is consistent across scripting and replication. * - * However in the case 'dontsort' is true, but the type to sort is a - * sorted set, we don't need to do anything as ordering is guaranteed - * in this special case. */ - if ((storekey || c->flags & REDIS_LUA_CLIENT) && - (dontsort && sortval->type != REDIS_ZSET)) + * The other types (list, sorted set) will retain their native order + * even if no sort order is requested, so they remain stable across + * scripting and replication. */ + if ((dontsort && sortval->type == REDIS_SET)) { /* Force ALPHA sorting */ dontsort = 0; diff --git a/tests/unit/sort.tcl b/tests/unit/sort.tcl index 9903a183fbe..a25ffeb5ce7 100644 --- a/tests/unit/sort.tcl +++ b/tests/unit/sort.tcl @@ -238,6 +238,24 @@ start_server { r sort mylist by num get x:*-> } {100} + test "SORT by nosort retains native order for lists" { + r del testa + r lpush testa 2 1 4 3 5 + r sort testa by nosort + } {5 3 4 1 2} + + test "SORT by nosort plus store retains native order for lists" { + r del testa + r lpush testa 2 1 4 3 5 + r sort testa by nosort store testb + r lrange testb 0 -1 + } {5 3 4 1 2} + + test "SORT by nosort with limit returns based on original list order" { + r sort testa by nosort limit 0 3 store testb + r lrange testb 0 -1 + } {5 3 4} + tags {"slow"} { set num 100 set res [create_random_dataset $num lpush] From 7de1ef773ed9359db3b1bf8041e67c050ec8c564 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 11 Dec 2014 15:57:11 +0100 Subject: [PATCH 20/25] SORT: Don't sort Set elements if not needed. Related to #2094. --- src/sort.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sort.c b/src/sort.c index f813ff26b16..3724819693a 100644 --- a/src/sort.c +++ b/src/sort.c @@ -270,7 +270,9 @@ void sortCommand(redisClient *c) { * The other types (list, sorted set) will retain their native order * even if no sort order is requested, so they remain stable across * scripting and replication. */ - if ((dontsort && sortval->type == REDIS_SET)) + if (dontsort && + sortval->type == REDIS_SET && + (storekey || c->flags & REDIS_LUA_CLIENT)) { /* Force ALPHA sorting */ dontsort = 0; From 5509c141f8636153128031f4d3bddfe46691f243 Mon Sep 17 00:00:00 2001 From: Rhommel Lamas Date: Thu, 23 Oct 2014 10:52:35 +0200 Subject: [PATCH 21/25] Add symlink to redis-sentinel during make install --- src/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile b/src/Makefile index 8b3e959890b..bb2c044868d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -251,3 +251,4 @@ install: all $(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_CHECK_DUMP_NAME) $(INSTALL_BIN) $(REDIS_INSTALL) $(REDIS_CHECK_AOF_NAME) $(INSTALL_BIN) + @ln -sf $(INSTALL_BIN)/$(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME) From e47e460f1f762ceb4a8d1c5367406b29dcdcefac Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 12 Dec 2014 22:56:33 +0100 Subject: [PATCH 22/25] Lua cmsgpack lib updated to latest version. It fixes a bad bug that crashes the server in certain conditions as shown in issue #2210. --- deps/lua/src/lua_cmsgpack.c | 53 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/deps/lua/src/lua_cmsgpack.c b/deps/lua/src/lua_cmsgpack.c index 4ccf07f6d47..e13f053d265 100644 --- a/deps/lua/src/lua_cmsgpack.c +++ b/deps/lua/src/lua_cmsgpack.c @@ -31,12 +31,10 @@ #define BITS_32 0 #endif -#if LUA_VERSION_NUM < 503 - #if BITS_32 - #define lua_pushunsigned(L, n) lua_pushnumber(L, n) - #else - #define lua_pushunsigned(L, n) lua_pushinteger(L, n) - #endif +#if BITS_32 + #define lua_pushunsigned(L, n) lua_pushnumber(L, n) +#else + #define lua_pushunsigned(L, n) lua_pushinteger(L, n) #endif /* ============================================================================= @@ -256,7 +254,7 @@ static void mp_encode_int(mp_buf *buf, int64_t n) { } } else { if (n >= -32) { - b[0] = ((char)n); /* negative fixnum */ + b[0] = ((signed char)n); /* negative fixnum */ enclen = 1; } else if (n >= -128) { b[0] = 0xd0; /* int 8 */ @@ -544,6 +542,7 @@ static int mp_pack(lua_State *L) { void mp_decode_to_lua_type(lua_State *L, mp_cur *c); void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) { + assert(len <= UINT_MAX); int index = 1; lua_newtable(L); @@ -556,6 +555,7 @@ void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) { } void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) { + assert(len <= UINT_MAX); lua_newtable(L); while(len--) { mp_decode_to_lua_type(L,c); /* key */ @@ -588,7 +588,7 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { break; case 0xd0: /* int 8 */ mp_cur_need(c,2); - lua_pushinteger(L,(char)c->p[1]); + lua_pushinteger(L,(signed char)c->p[1]); mp_cur_consume(c,2); break; case 0xcd: /* uint 16 */ @@ -699,13 +699,14 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { case 0xdb: /* raw 32 */ mp_cur_need(c,5); { - size_t l = (c->p[1] << 24) | - (c->p[2] << 16) | - (c->p[3] << 8) | - c->p[4]; - mp_cur_need(c,5+l); - lua_pushlstring(L,(char*)c->p+5,l); - mp_cur_consume(c,5+l); + size_t l = ((size_t)c->p[1] << 24) | + ((size_t)c->p[2] << 16) | + ((size_t)c->p[3] << 8) | + (size_t)c->p[4]; + mp_cur_consume(c,5); + mp_cur_need(c,l); + lua_pushlstring(L,(char*)c->p,l); + mp_cur_consume(c,l); } break; case 0xdc: /* array 16 */ @@ -719,10 +720,10 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { case 0xdd: /* array 32 */ mp_cur_need(c,5); { - size_t l = (c->p[1] << 24) | - (c->p[2] << 16) | - (c->p[3] << 8) | - c->p[4]; + size_t l = ((size_t)c->p[1] << 24) | + ((size_t)c->p[2] << 16) | + ((size_t)c->p[3] << 8) | + (size_t)c->p[4]; mp_cur_consume(c,5); mp_decode_to_lua_array(L,c,l); } @@ -738,10 +739,10 @@ void mp_decode_to_lua_type(lua_State *L, mp_cur *c) { case 0xdf: /* map 32 */ mp_cur_need(c,5); { - size_t l = (c->p[1] << 24) | - (c->p[2] << 16) | - (c->p[3] << 8) | - c->p[4]; + size_t l = ((size_t)c->p[1] << 24) | + ((size_t)c->p[2] << 16) | + ((size_t)c->p[3] << 8) | + (size_t)c->p[4]; mp_cur_consume(c,5); mp_decode_to_lua_hash(L,c,l); } @@ -830,15 +831,15 @@ static int mp_unpack(lua_State *L) { } static int mp_unpack_one(lua_State *L) { - int offset = luaL_optint(L, 2, 0); + int offset = luaL_optinteger(L, 2, 0); /* Variable pop because offset may not exist */ lua_pop(L, lua_gettop(L)-1); return mp_unpack_full(L, 1, offset); } static int mp_unpack_limit(lua_State *L) { - int limit = luaL_checkint(L, 2); - int offset = luaL_optint(L, 3, 0); + int limit = luaL_checkinteger(L, 2); + int offset = luaL_optinteger(L, 3, 0); /* Variable pop because offset may not exist */ lua_pop(L, lua_gettop(L)-1); From 4d8f4262a46db9785edf22f84d1f090fe10e6bb4 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 13 Dec 2014 08:54:33 +0100 Subject: [PATCH 23/25] List of commands flagged as admin commands modified. The old list did not made much sense... and the flag is currently not used at all, so no side effects. --- src/redis.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/redis.c b/src/redis.c index 289e3779147..c35b3fa1345 100644 --- a/src/redis.c +++ b/src/redis.c @@ -244,7 +244,7 @@ struct redisCommand redisCommandTable[] = { {"pttl",pttlCommand,2,"rF",0,NULL,1,1,1,0,0}, {"persist",persistCommand,2,"wF",0,NULL,1,1,1,0,0}, {"slaveof",slaveofCommand,3,"ast",0,NULL,0,0,0,0,0}, - {"role",roleCommand,1,"last",0,NULL,0,0,0,0,0}, + {"role",roleCommand,1,"lst",0,NULL,0,0,0,0,0}, {"debug",debugCommand,-2,"as",0,NULL,0,0,0,0,0}, {"config",configCommand,-2,"art",0,NULL,0,0,0,0,0}, {"subscribe",subscribeCommand,-2,"rpslt",0,NULL,0,0,0,0,0}, @@ -255,15 +255,15 @@ struct redisCommand redisCommandTable[] = { {"pubsub",pubsubCommand,-2,"pltrR",0,NULL,0,0,0,0,0}, {"watch",watchCommand,-2,"rsF",0,NULL,1,-1,1,0,0}, {"unwatch",unwatchCommand,1,"rsF",0,NULL,0,0,0,0,0}, - {"restore",restoreCommand,4,"awm",0,NULL,1,1,1,0,0}, - {"migrate",migrateCommand,6,"aw",0,NULL,0,0,0,0,0}, - {"dump",dumpCommand,2,"ar",0,NULL,1,1,1,0,0}, + {"restore",restoreCommand,4,"wm",0,NULL,1,1,1,0,0}, + {"migrate",migrateCommand,6,"w",0,NULL,0,0,0,0,0}, + {"dump",dumpCommand,2,"r",0,NULL,1,1,1,0,0}, {"object",objectCommand,3,"r",0,NULL,2,2,2,0,0}, - {"client",clientCommand,-2,"ars",0,NULL,0,0,0,0,0}, + {"client",clientCommand,-2,"rs",0,NULL,0,0,0,0,0}, {"eval",evalCommand,-3,"s",0,zunionInterGetKeys,0,0,0,0,0}, {"evalsha",evalShaCommand,-3,"s",0,zunionInterGetKeys,0,0,0,0,0}, {"slowlog",slowlogCommand,-2,"r",0,NULL,0,0,0,0,0}, - {"script",scriptCommand,-2,"ras",0,NULL,0,0,0,0,0}, + {"script",scriptCommand,-2,"rs",0,NULL,0,0,0,0,0}, {"time",timeCommand,1,"rRF",0,NULL,0,0,0,0,0}, {"bitop",bitopCommand,-4,"wm",0,NULL,2,-1,1,0,0}, {"bitcount",bitcountCommand,-2,"r",0,NULL,1,1,1,0,0}, From 02d465c8fed757053d135d4fb3f412fd7a5d9821 Mon Sep 17 00:00:00 2001 From: antirez Date: Sat, 13 Dec 2014 08:57:06 +0100 Subject: [PATCH 24/25] Don't log admin commands in MONITOR. Otherwise there are security risks, especially when providing Redis as a service, the user may "sniff" for admin commands renamed to an unguessable string via rename-command in redis.conf. --- src/redis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redis.c b/src/redis.c index c35b3fa1345..85fcc8e42b1 100644 --- a/src/redis.c +++ b/src/redis.c @@ -1938,7 +1938,7 @@ void call(redisClient *c, int flags) { * not generated from reading an AOF. */ if (listLength(server.monitors) && !server.loading && - !(c->cmd->flags & REDIS_CMD_SKIP_MONITOR)) + !(c->cmd->flags & (REDIS_CMD_SKIP_MONITOR|REDIS_CMD_ADMIN))) { replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc); } From 902b877dc020df3f43b2f8179a85dc48144d0b20 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 16 Dec 2014 09:18:20 +0100 Subject: [PATCH 25/25] Redis 2.8.19. --- 00-RELEASENOTES | 30 ++++++++++++++++++++++++++++++ src/version.h | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/00-RELEASENOTES b/00-RELEASENOTES index 6108816df46..e06319cd514 100644 --- a/00-RELEASENOTES +++ b/00-RELEASENOTES @@ -14,6 +14,36 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade! CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. -------------------------------------------------------------------------------- +--[ Redis 2.8.19 ] Release date: 16 Dec 2014 + +# UPGRADE URGENCY: LOW for both Redis and Sentinel. This release mostly + fixes small issues. + +02d465c Don't log admin commands in MONITOR. (antirez) +4d8f426 List of commands flagged as admin commands modified. (antirez) +e47e460 Lua cmsgpack lib updated to latest version. (antirez) +5509c14 Add symlink to redis-sentinel during make install (Rhommel Lamas) +7de1ef7 SORT: Don't sort Set elements if not needed. (antirez) +e945a54 Fix zero-ordering SORT when called against lists (Matt Stancliff) +d81c383 Update redis_init_script.tpl (Ben Dowling) +dba57ea FIXED redis-benchmark's idle mode.With idle mode shouldn't create write event (zhanghailei) +888ea17 zipmap.c: update comments above (Sun He) +86ebc13 replaced // comments #2150 (Deepak Verma) +3d73f08 redis-benchmark AUTH command to be discarded after the first send #2150 (azure provisioned user) +76d53a6 sds.c: Correct two spelling mistakes in comments (Sun He) +4848cf9 sds.c/sdscatvprintf: set va_end to finish va_list cpy (Sun He) +d2f584f sds.c: Correct some comments (Sun He) +2ed3f09 Update whatisdoing.sh (Serghei Iakovlev) +77b997d Include stropts only if __sun is defined. (antirez) +d409371 Fix implicit declaration of ioctl on Solaris (Jan-Erik Rediger) +23b96c0 Silence _BSD_SOURCE warnings in glibc 2.20 and forward (Johan Bergström) +a47a042 Mark whatisdoing.sh as deprecated in top-comment. (antirez) +b5737d2 getting pid fixes (Serghei Iakovlev) +a598e08 sparkline.c: AddSample skip Empty label (Sun He) +7d480ab sparkline.c: mov label-ini into the AddSample Function (Sun He) +2f3c860 Only ignore sigpipe in interactive mode (Jan-Erik Rediger) +0c211a1 Simplify lua_cmsgpack macro and fix build on old Linux distros. (antirez) + --[ Redis 2.8.18 ] Release date: 4 Dec 2014 # UPGRADE URGENCY: LOW for both Redis and Sentinel. This release mostly diff --git a/src/version.h b/src/version.h index 9a736509eac..c4bd3045a59 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define REDIS_VERSION "2.8.18" +#define REDIS_VERSION "2.8.19"