Compare commits

...
40 Commits
Author SHA1 Message Date
antirez 1cb6effdc8 Redis 3.2.11. 2017-09-21 16:20:18 +02:00
Oran Agra 13e8e53806 Flush append only buffers before existing.
when SHUTDOWN command is recived it is possible that some of the recent
command were not yet flushed from the AOF buffer, and the server
experiences data loss at shutdown.
2017-09-18 12:04:33 +02:00
antirez c9ab43ef7c Redis 3.2.10. 2017-07-28 17:59:00 +02:00
Jan-Erik Rediger bf50875353 Check that the whole first argument is a number
Fixes #2258
2017-07-24 15:21:44 +02:00
WuYunlong 8774228cc5 fix rewrite config: auto-aof-rewrite-min-size 2017-07-24 15:21:14 +02:00
Byron Grobe ab900303b8 Fixed issue #1996 (Missing '-' in help message for redis-benchmark) 2017-07-24 15:21:14 +02:00
Jan-Erik Rediger 7fcca9baef Don't use extended Regexp Syntax
It's not POSIX (BSD systems have -E instead) and we don't actually need it.

Closes #1922
2017-07-24 15:21:14 +02:00
Leon Chen 41963fe676 fix return wrong value of clusterDelNodeSlots 2017-07-24 14:18:56 +02:00
Leon Chen 97d50344c4 fix mismatch argument 2017-07-24 14:18:56 +02:00
liangsijian e39849808c Fix lua ldb command log 2017-07-24 14:11:36 +02:00
antirez 84a4f20278 Make representClusterNodeFlags() more robust.
This function failed when an internal-only flag was set as an only flag
in a node: the string was trimmed expecting a final comma before
exiting the function, causing a crash. See issue #4142.
Moreover generation of flags representation only needed at DEBUG log
level was always performed: a waste of CPU time. This is fixed as well
by this commit.
2017-07-24 14:09:50 +02:00
antirez 5aa2525006 Fix isHLLObjectOrReply() to handle integer encoded strings.
Close #3766.
2017-07-11 12:46:30 +02:00
antirez 7018d27dfe Fix abort typo in Lua debugger help screen. 2017-06-30 12:12:17 +02:00
antirez d557144ebb Added GEORADIUS(BYMEMBER)_RO variants for read-only operations.
Issue #4084 shows how for a design error, GEORADIUS is a write command
because of the STORE option. Because of this it does not work
on readonly slaves, gets redirected to masters in Redis Cluster even
when the connection is in READONLY mode and so forth.

To break backward compatibility at this stage, with Redis 4.0 to be in
advanced RC state, is problematic for the user base. The API can be
fixed into the unstable branch soon if we'll decide to do so in order to
be more consistent, and reease Redis 5.0 with this incompatibility in
the future. This is still unclear.

However, the ability to scale GEO queries in slaves easily is too
important so this commit adds two read-only variants to the GEORADIUS
and GEORADIUSBYMEMBER command: GEORADIUS_RO and GEORADIUSBYMEMBER_RO.
The commands are exactly as the original commands, but they do not
accept the STORE and STOREDIST options.
2017-06-30 11:53:45 +02:00
Suraj Narkhede a309388dff Fix following issues in blocking commands:
1. brpop last key index, thus checking all keys for slots.
2. Memory leak in clusterRedirectBlockedClientIfNeeded.
3. Remove while loop in clusterRedirectBlockedClientIfNeeded.
2017-06-27 18:06:22 +02:00
Suraj Narkhede 55442262e1 Fix brpop command table entry and redirect blocked clients. 2017-06-27 18:06:02 +02:00
antirez e3641c8dee Fix PERSIST expired key resuscitation issue #4048. 2017-06-27 18:05:37 +02:00
Antonio Mallia 9ce105add5 Removed duplicate 'sys/socket.h' include 2017-06-27 18:03:22 +02:00
Zachary Marquez e084a394a6 Prevent expirations and evictions while paused
Proposed fix to https://github.com/antirez/redis/issues/4027
2017-06-27 18:03:00 +02:00
antirez 61c78a5215 Collect fork() timing info only if fork succeeded. 2017-06-27 17:56:07 +02:00
antirez d067e3342f Aesthetic changes to #4068 PR to conform to Redis coding standard.
1. Inline if ... statement if short.
2. No lines over 80 columns.
2017-06-22 11:01:51 +02:00
xuzhou 2b0f03e4f2 Optimize set command with ex/px when updating aof. 2017-06-22 11:01:51 +02:00
antirez ad949f2329 redis-benchmark: add -t hset target. 2017-06-22 11:01:47 +02:00
xuzhou 351663bd7b Fix set with ex/px option when propagated to aof 2017-06-22 11:01:39 +02:00
minghang.zmh d70ac1d105 fix server.stat_net_output_bytes calc bug 2017-06-20 17:03:35 +02:00
xuchengxuan 8da9a167e0 Fixed comments of slowlog duration 2017-06-20 16:56:49 +02:00
cbgbt 13546adcb9 cli: Only print elapsed time on OUTPUT_STANDARD 2017-06-20 16:54:47 +02:00
Aric Huang 373facf81c (fix) Update create-cluster README
Fix a few typos/adjust wording in `create-cluster` README
2017-06-20 16:54:47 +02:00
Salvatore Sanfilippo 29e3ff9bec Merge pull request #3926 from QuChen88/3.2
Implement getKeys procedure for georadius and georadiusbymember commands
2017-06-14 09:12:17 -07:00
antirez 5116130d42 Redis 3.2.9. 2017-05-17 17:39:00 +02:00
antirez 3b46cf97de redis-cli --bigkeys: show error when TYPE fails.
Close #3993.
2017-05-15 11:23:57 +02:00
antirez f59b4b93d9 Fix preprocessor if/else chain broken in order to fix #3927. 2017-04-21 11:28:02 +02:00
antirez dd80fedf6f Fix zmalloc_get_memory_size() ifdefs to actually use the else branch.
Close #3927.
2017-04-21 11:27:28 +02:00
antirez 697d3abeff Set lua-time-limit default value at safe place.
Otherwise, as it was, it will overwrite whatever the user set.

Close #3703.
2017-04-21 11:26:27 +02:00
antirez c9c04b11b9 Fix #3848 by closing the descriptor on error. 2017-04-21 11:25:08 +02:00
张文康 d3b4992450 update block->free after some diff data are written to the child process 2017-04-20 07:59:46 +02:00
antirez 6a33952b8a Test: fix, hopefully, false PSYNC failure like in issue #2715.
And many other related Github issues... all reporting the same problem.
There was probably just not enough backlog in certain unlucky runs.
I'll ask people that can reporduce if they see now this as fixed as
well.
2017-04-14 17:54:06 +02:00
Qu Chen bacb04f89f Implement getKeys procedure for georadius and georadiusbymember
commands.
2017-04-08 18:37:02 +00:00
John.Koepi b83f9fea81 fix #2883, #2857 pipe fds leak when fork() failed on bg aof rw 2017-02-20 10:28:53 +01:00
antirez 10dbb5cd33 Don't leak file descriptor on syncWithMaster().
Close #3804.
2017-02-20 10:28:52 +01:00
23 changed files with 398 additions and 73 deletions
+196
View File
@@ -10,6 +10,202 @@ 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 3.2.11 Released Thu Sep 21 15:47:53 CEST 2017
================================================================================
Upgrade urgency HIGH: Potentially critical bugs fixed.
AOF flush on SHUTDOWN did not cared to really write the AOF buffers
(not in the kernel but in the Redis process memory) to disk before exiting.
Calling SHUTDOWN during traffic resulted into not every operation to be
persisted on disk.
Oran Agra (and also Buğra Gedik) in commit 8651e5d5:
Flush append only buffers before existing.
1 file changed, 2 insertions(+), 1 deletion(-)
================================================================================
Redis 3.2.10 Released Fri Jul 28 17:49:07 CEST 2017
================================================================================
Upgrade urgency MODERATE: This release contains a number of fixes that are not
critical in the general case, but quite important
in certain use cases. Upgrading is suggested but not
mandatory.
Dear Redis users,
while 4.0.1 is already out, this is a maintenance release of Redis 3.2.
It fixes several bugs, the most interesting ones are the following:
1. INFO server.stat_net_output_bytes field was computed in a wrong way, now
the output is correct.
2. SET with EX/PX options are now propagated correctly in the AOF, using
the absolute times.
3. CLIENT PAUSE was fixed to prevent eviction of keys, so that master and
slave continue to be consistent for the time the pause is active.
4. GEORADIUS(BYMEMBER)_RO variants for read-only operations added.
5. HyperLogLog sanity detection fixed in an edge case.
6. Redis Cluster crash due to mis-handling of hidden node flags fixed.
If you think you may be affected by the above problems, upgrading is a
good idea.
Have a nice day,
Salvatore
Full history of commits in this release:
Jan-Erik Rediger in commit bf508753:
Check that the whole first argument is a number
1 file changed, 3 insertions(+), 2 deletions(-)
WuYunlong in commit 8774228c:
fix rewrite config: auto-aof-rewrite-min-size
1 file changed, 2 insertions(+), 2 deletions(-)
Byron Grobe in commit ab900303:
Fixed issue #1996 (Missing '-' in help message for redis-benchmark)
1 file changed, 1 insertion(+), 1 deletion(-)
Jan-Erik Rediger in commit 7fcca9ba:
Don't use extended Regexp Syntax
1 file changed, 6 insertions(+), 6 deletions(-)
Leon Chen in commit 41963fe6:
fix return wrong value of clusterDelNodeSlots
1 file changed, 4 insertions(+), 2 deletions(-)
Leon Chen in commit 97d50344:
fix mismatch argument
1 file changed, 1 insertion(+), 1 deletion(-)
liangsijian in commit e3984980:
Fix lua ldb command log
1 file changed, 1 insertion(+)
antirez in commit 84a4f202:
Make representClusterNodeFlags() more robust.
1 file changed, 17 insertions(+), 16 deletions(-)
antirez in commit 5aa25250:
Fix isHLLObjectOrReply() to handle integer encoded strings.
1 file changed, 1 insertion(+)
antirez in commit 7018d27d:
Fix abort typo in Lua debugger help screen.
1 file changed, 1 insertion(+), 1 deletion(-)
antirez in commit d557144e:
Added GEORADIUS(BYMEMBER)_RO variants for read-only operations.
3 files changed, 32 insertions(+), 11 deletions(-)
Suraj Narkhede in commit a309388d:
Fix following issues in blocking commands: 1. brpop last key index, thus checking all keys for slots. 2. Memory leak in clusterRedirectBlockedClientIfNeeded. 3. Remove while loop in clusterRedirectBlockedClientIfNeeded.
1 file changed, 1 insertion(+)
Suraj Narkhede in commit 55442262:
Fix brpop command table entry and redirect blocked clients.
2 files changed, 3 insertions(+), 2 deletions(-)
antirez in commit e3641c8d:
Fix PERSIST expired key resuscitation issue #4048.
1 file changed, 4 insertions(+), 7 deletions(-)
Antonio Mallia in commit 9ce105ad:
Removed duplicate 'sys/socket.h' include
1 file changed, 1 deletion(-)
Zachary Marquez in commit e084a394:
Prevent expirations and evictions while paused
1 file changed, 10 insertions(+)
antirez in commit 61c78a52:
Collect fork() timing info only if fork succeeded.
1 file changed, 4 insertions(+), 3 deletions(-)
antirez in commit d067e334:
Aesthetic changes to #4068 PR to conform to Redis coding standard.
1 file changed, 6 insertions(+), 7 deletions(-)
xuzhou in commit 2b0f03e4:
Optimize set command with ex/px when updating aof.
1 file changed, 3 insertions(+), 3 deletions(-)
antirez in commit ad949f23:
redis-benchmark: add -t hset target.
1 file changed, 7 insertions(+)
xuzhou in commit 351663bd:
Fix set with ex/px option when propagated to aof
4 files changed, 36 insertions(+), 1 deletion(-)
minghang.zmh in commit d70ac1d1:
fix server.stat_net_output_bytes calc bug
1 file changed, 1 insertion(+), 1 deletion(-)
xuchengxuan in commit 8da9a167:
Fixed comments of slowlog duration
1 file changed, 1 insertion(+), 1 deletion(-)
cbgbt in commit 13546adc:
cli: Only print elapsed time on OUTPUT_STANDARD
1 file changed, 3 insertions(+), 1 deletion(-)
Aric Huang in commit 373facf8:
(fix) Update create-cluster README
1 file changed, 4 insertions(+), 4 deletions(-)
Salvatore Sanfilippo in commit 29e3ff9b:
Merge pull request #3926 from QuChen88/3.2
================================================================================
Redis 3.2.9 Released Mon May 17 17:35:38 CEST 2017
================================================================================
Upgrade urgency LOW: A few rarely harmful bugs were fixed.
This release just fixes bugs that are unlikely to cause serious problems
so there is no need to update ASAP. Please, see the list of commits
for the details on the bugs fixed and credits:
antirez in commit 3b46cf97:
redis-cli --bigkeys: show error when TYPE fails.
1 file changed, 7 insertions(+), 2 deletions(-)
antirez in commit f59b4b93:
Fix preprocessor if/else chain broken in order to fix #3927.
1 file changed, 3 insertions(+)
antirez in commit dd80fedf:
Fix zmalloc_get_memory_size() ifdefs to actually use the else branch.
1 file changed, 2 deletions(-)
antirez in commit 697d3abe:
Set lua-time-limit default value at safe place.
2 files changed, 1 insertion(+), 1 deletion(-)
antirez in commit c9c04b11:
Fix #3848 by closing the descriptor on error.
1 file changed, 2 insertions(+), 1 deletion(-)
张文康 in commit d3b49924:
update block->free after some diff data are written to the child process
1 file changed, 1 insertion(+)
antirez in commit 6a33952b:
Test: fix, hopefully, false PSYNC failure like in issue #2715.
1 file changed, 1 insertion(+), 1 deletion(-)
John.Koepi in commit b83f9fea:
fix #2883, #2857 pipe fds leak when fork() failed on bg aof rw
1 file changed, 1 insertion(+)
antirez in commit 10dbb5cd:
Don't leak file descriptor on syncWithMaster().
1 file changed, 2 insertions(+), 1 deletion(-)
================================================================================
Redis 3.2.8 Released Sun Feb 12 16:11:18 CET 2017
================================================================================
+2 -1
View File
@@ -462,7 +462,7 @@ static int anetV6Only(char *err, int s) {
static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backlog)
{
int s, rv;
int s = -1, rv;
char _port[6]; /* strlen("65535") */
struct addrinfo hints, *servinfo, *p;
@@ -491,6 +491,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl
}
error:
if (s != -1) close(s);
s = ANET_ERR;
end:
freeaddrinfo(servinfo);
+18
View File
@@ -115,6 +115,7 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) {
if (nwritten <= 0) return;
memmove(block->buf,block->buf+nwritten,block->used-nwritten);
block->used -= nwritten;
block->free += nwritten;
}
if (block->used == 0) listDelNode(server.aof_rewrite_buf_blocks,ln);
}
@@ -535,6 +536,22 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a
buf = catAppendOnlyGenericCommand(buf,3,tmpargv);
decrRefCount(tmpargv[0]);
buf = catAppendOnlyExpireAtCommand(buf,cmd,argv[1],argv[2]);
} 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);
} else {
/* All the other commands don't need translation or need the
* same translation already operated in the command vector
@@ -1295,6 +1312,7 @@ int rewriteAppendOnlyFileBackground(void) {
serverLog(LL_WARNING,
"Can't rewrite append only file in background: fork: %s",
strerror(errno));
aofClosePipes();
return C_ERR;
}
serverLog(LL_NOTICE,
+24 -20
View File
@@ -37,7 +37,6 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <math.h>
@@ -1300,13 +1299,15 @@ void clusterProcessGossipSection(clusterMsg *hdr, clusterLink *link) {
clusterNode *node;
sds ci;
ci = representClusterNodeFlags(sdsempty(), flags);
serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d %s",
g->nodename,
g->ip,
ntohs(g->port),
ci);
sdsfree(ci);
if (server.verbosity == LL_DEBUG) {
ci = representClusterNodeFlags(sdsempty(), flags);
serverLog(LL_DEBUG,"GOSSIP %.40s %s:%d %s",
g->nodename,
g->ip,
ntohs(g->port),
ci);
sdsfree(ci);
}
/* Update our state accordingly to the gossip sections */
node = clusterLookupNode(g->nodename);
@@ -3440,8 +3441,10 @@ int clusterDelNodeSlots(clusterNode *node) {
int deleted = 0, j;
for (j = 0; j < CLUSTER_SLOTS; j++) {
if (clusterNodeGetSlotBit(node,j)) clusterDelSlot(j);
deleted++;
if (clusterNodeGetSlotBit(node,j)) {
clusterDelSlot(j);
deleted++;
}
}
return deleted;
}
@@ -3675,15 +3678,14 @@ static struct redisNodeFlags redisNodeFlagsTable[] = {
/* Concatenate the comma separated list of node flags to the given SDS
* string 'ci'. */
sds representClusterNodeFlags(sds ci, uint16_t flags) {
if (flags == 0) {
ci = sdscat(ci,"noflags,");
} else {
int i, size = sizeof(redisNodeFlagsTable)/sizeof(struct redisNodeFlags);
for (i = 0; i < size; i++) {
struct redisNodeFlags *nodeflag = redisNodeFlagsTable + i;
if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name);
}
size_t orig_len = sdslen(ci);
int i, size = sizeof(redisNodeFlagsTable)/sizeof(struct redisNodeFlags);
for (i = 0; i < size; i++) {
struct redisNodeFlags *nodeflag = redisNodeFlagsTable + i;
if (flags & nodeflag->flag) ci = sdscat(ci, nodeflag->name);
}
/* If no flag was added, add the "noflags" special flag. */
if (sdslen(ci) == orig_len) ci = sdscat(ci,"noflags,");
sdsIncrLen(ci,-1); /* Remove trailing comma. */
return ci;
}
@@ -4007,7 +4009,7 @@ void clusterCommand(client *c) {
}
if ((n = clusterLookupNode(c->argv[4]->ptr)) == NULL) {
addReplyErrorFormat(c,"I don't know about node %s",
(char*)c->argv[3]->ptr);
(char*)c->argv[4]->ptr);
return;
}
server.cluster->importing_slots_from[slot] = n;
@@ -5204,8 +5206,9 @@ int clusterRedirectBlockedClientIfNeeded(client *c) {
return 1;
}
/* All keys must belong to the same slot, so check first key only. */
di = dictGetIterator(c->bpop.keys);
while((de = dictNext(di)) != NULL) {
if ((de = dictNext(di)) != NULL) {
robj *key = dictGetKey(de);
int slot = keyHashSlot((char*)key->ptr, sdslen(key->ptr));
clusterNode *node = server.cluster->slots[slot];
@@ -5223,6 +5226,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) {
clusterRedirectClient(c,node,slot,
CLUSTER_REDIR_MOVED);
}
dictReleaseIterator(di);
return 1;
}
}
+2 -2
View File
@@ -910,8 +910,6 @@ void configSetCommand(client *c) {
"timeout",server.maxidletime,0,LONG_MAX) {
} config_set_numerical_field(
"auto-aof-rewrite-percentage",server.aof_rewrite_perc,0,LLONG_MAX){
} config_set_numerical_field(
"auto-aof-rewrite-min-size",server.aof_rewrite_min_size,0,LLONG_MAX) {
} config_set_numerical_field(
"hash-max-ziplist-entries",server.hash_max_ziplist_entries,0,LLONG_MAX) {
} config_set_numerical_field(
@@ -986,6 +984,8 @@ void configSetCommand(client *c) {
}
} config_set_memory_field("repl-backlog-size",ll) {
resizeReplicationBacklog(ll);
} config_set_memory_field("auto-aof-rewrite-min-size",ll) {
server.aof_rewrite_min_size = ll;
/* Enumeration fields.
* config_set_enum_field(name,var,enum_var) */
+42 -7
View File
@@ -90,7 +90,7 @@ robj *lookupKeyReadWithFlags(redisDb *db, robj *key, int flags) {
if (expireIfNeeded(db,key) == 1) {
/* Key expired. If we are in the context of a master, expireIfNeeded()
* returns 0 only when the key does not exist at all, so it's save
* returns 0 only when the key does not exist at all, so it's safe
* to return NULL ASAP. */
if (server.masterhost == NULL) return NULL;
@@ -1033,18 +1033,15 @@ void pttlCommand(client *c) {
}
void persistCommand(client *c) {
dictEntry *de;
de = dictFind(c->db->dict,c->argv[1]->ptr);
if (de == NULL) {
addReply(c,shared.czero);
} else {
if (lookupKeyWrite(c->db,c->argv[1])) {
if (removeExpire(c->db,c->argv[1])) {
addReply(c,shared.cone);
server.dirty++;
} else {
addReply(c,shared.czero);
}
} else {
addReply(c,shared.czero);
}
}
@@ -1234,6 +1231,44 @@ int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkey
return keys;
}
/* Helper function to extract keys from following commands:
* GEORADIUS key x y radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC]
* [COUNT count] [STORE key] [STOREDIST key]
* GEORADIUSBYMEMBER key member radius unit ... options ... */
int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) {
int i, num, *keys;
UNUSED(cmd);
/* Check for the presence of the stored key in the command */
int stored_key = -1;
for (i = 5; i < argc; i++) {
char *arg = argv[i]->ptr;
/* For the case when user specifies both "store" and "storedist" options, the
* second key specified would override the first key. This behavior is kept
* the same as in georadiusCommand method.
*/
if ((!strcasecmp(arg, "store") || !strcasecmp(arg, "storedist")) && ((i+1) < argc)) {
stored_key = i+1;
i++;
}
}
num = 1 + (stored_key == -1 ? 0 : 1);
/* Keys in the command come from two places:
* argv[1] = key,
* argv[5...n] = stored key if present
*/
keys = zmalloc(sizeof(int) * num);
/* Add all key positions to keys[] */
keys[0] = 1;
if(num > 1) {
keys[1] = stored_key;
}
*numkeys = num;
return keys;
}
/* Slot to Key API. This is used by Redis Cluster in order to obtain in
* a fast way a key that belongs to a specified hash slot. This is useful
* while rehashing the cluster. */
+26 -9
View File
@@ -454,13 +454,14 @@ void geoaddCommand(client *c) {
#define SORT_ASC 1
#define SORT_DESC 2
#define RADIUS_COORDS 1
#define RADIUS_MEMBER 2
#define RADIUS_COORDS (1<<0) /* Search around coordinates. */
#define RADIUS_MEMBER (1<<1) /* Search around member. */
#define RADIUS_NOSTORE (1<<2) /* Do not acceot STORE/STOREDIST option. */
/* GEORADIUS key x y radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC]
* [COUNT count] [STORE key] [STOREDIST key]
* GEORADIUSBYMEMBER key member radius unit ... options ... */
void georadiusGeneric(client *c, int type) {
void georadiusGeneric(client *c, int flags) {
robj *key = c->argv[1];
robj *storekey = NULL;
int storedist = 0; /* 0 for STORE, 1 for STOREDIST. */
@@ -475,11 +476,11 @@ void georadiusGeneric(client *c, int type) {
/* Find long/lat to use for radius search based on inquiry type */
int base_args;
double xy[2] = { 0 };
if (type == RADIUS_COORDS) {
if (flags & RADIUS_COORDS) {
base_args = 6;
if (extractLongLatOrReply(c, c->argv + 2, xy) == C_ERR)
return;
} else if (type == RADIUS_MEMBER) {
} else if (flags & RADIUS_MEMBER) {
base_args = 5;
robj *member = c->argv[2];
if (longLatFromMember(zobj, member, xy) == C_ERR) {
@@ -487,7 +488,7 @@ void georadiusGeneric(client *c, int type) {
return;
}
} else {
addReplyError(c, "unknown georadius search type");
addReplyError(c, "Unknown georadius search type");
return;
}
@@ -524,11 +525,17 @@ void georadiusGeneric(client *c, int type) {
return;
}
i++;
} else if (!strcasecmp(arg, "store") && (i+1) < remaining) {
} else if (!strcasecmp(arg, "store") &&
(i+1) < remaining &&
!(flags & RADIUS_NOSTORE))
{
storekey = c->argv[base_args+i+1];
storedist = 0;
i++;
} else if (!strcasecmp(arg, "storedist") && (i+1) < remaining) {
} else if (!strcasecmp(arg, "storedist") &&
(i+1) < remaining &&
!(flags & RADIUS_NOSTORE))
{
storekey = c->argv[base_args+i+1];
storedist = 1;
i++;
@@ -676,10 +683,20 @@ void georadiusCommand(client *c) {
}
/* GEORADIUSBYMEMBER wrapper function. */
void georadiusByMemberCommand(client *c) {
void georadiusbymemberCommand(client *c) {
georadiusGeneric(c, RADIUS_MEMBER);
}
/* GEORADIUS_RO wrapper function. */
void georadiusroCommand(client *c) {
georadiusGeneric(c, RADIUS_COORDS|RADIUS_NOSTORE);
}
/* GEORADIUSBYMEMBER_RO wrapper function. */
void georadiusbymemberroCommand(client *c) {
georadiusGeneric(c, RADIUS_MEMBER|RADIUS_NOSTORE);
}
/* GEOHASH key ele1 ele2 ... eleN
*
* Returns an array with an 11 characters geohash representation of the
+1
View File
@@ -1128,6 +1128,7 @@ int isHLLObjectOrReply(client *c, robj *o) {
if (checkType(c,o,OBJ_STRING))
return C_ERR; /* Error already sent. */
if (!sdsEncodedObject(o)) goto invalid;
if (stringObjectLen(o) < sizeof(*hdr)) goto invalid;
hdr = o->ptr;
+1 -1
View File
@@ -949,11 +949,11 @@ int writeToClient(int fd, client *c, int handler_installed) {
*
* However if we are over the maxmemory limit we ignore that and
* just deliver as much data as it is possible to deliver. */
server.stat_net_output_bytes += totwritten;
if (totwritten > NET_MAX_WRITES_PER_EVENT &&
(server.maxmemory == 0 ||
zmalloc_used_memory() < server.maxmemory)) break;
}
server.stat_net_output_bytes += totwritten;
if (nwritten == -1) {
if (errno == EAGAIN) {
nwritten = 0;
+4 -3
View File
@@ -1690,9 +1690,6 @@ int rdbSaveToSlavesSockets(void) {
exitFromChild((retval == C_OK) ? 0 : 1);
} else {
/* Parent */
server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
if (childpid == -1) {
serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno));
@@ -1715,6 +1712,10 @@ int rdbSaveToSlavesSockets(void) {
close(pipefds[0]);
close(pipefds[1]);
} else {
server.stat_fork_time = ustime()-start;
server.stat_fork_rate = (double) zmalloc_used_memory() * 1000000 / server.stat_fork_time / (1024*1024*1024); /* GB per second. */
latencyAddSampleIfNeeded("fork",server.stat_fork_time/1000);
serverLog(LL_NOTICE,"Background RDB transfer started by pid %d",
childpid);
server.rdb_save_time_start = time(NULL);
+8 -1
View File
@@ -573,7 +573,7 @@ usage:
" -c <clients> Number of parallel connections (default 50)\n"
" -n <requests> Total number of requests (default 100000)\n"
" -d <size> Data size of SET/GET value in bytes (default 2)\n"
" -dbnum <db> SELECT the specified db number (default 0)\n"
" --dbnum <db> SELECT the specified db number (default 0)\n"
" -k <boolean> 1=keep alive 0=reconnect (default 1)\n"
" -r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD\n"
" Using this option the benchmark will expand the string __rand_int__\n"
@@ -779,6 +779,13 @@ int main(int argc, const char **argv) {
free(cmd);
}
if (test_is_selected("hset")) {
len = redisFormatCommand(&cmd,
"HSET myset:__rand_int__ element:__rand_int__ %s",data);
benchmark("HSET",cmd,len);
free(cmd);
}
if (test_is_selected("spop")) {
len = redisFormatCommand(&cmd,"SPOP myset");
benchmark("SPOP",cmd,len);
+13 -5
View File
@@ -1330,9 +1330,10 @@ static void repl(void) {
} else {
long long start_time = mstime(), elapsed;
int repeat, skipargs = 0;
char *endptr;
repeat = atoi(argv[0]);
if (argc > 1 && repeat) {
repeat = strtol(argv[0], &endptr, 10);
if (argc > 1 && *endptr == '\0' && repeat) {
skipargs = 1;
} else {
repeat = 1;
@@ -1351,7 +1352,9 @@ static void repl(void) {
}
elapsed = mstime()-start_time;
if (elapsed >= 500) {
if (elapsed >= 500 &&
config.output == OUTPUT_STANDARD)
{
printf("(%.2fs)\n",(double)elapsed/1000);
}
}
@@ -2022,8 +2025,13 @@ static void getKeyTypes(redisReply *keys, int *types) {
keys->element[i]->str, context->err, context->errstr);
exit(1);
} else if(reply->type != REDIS_REPLY_STATUS) {
fprintf(stderr, "Invalid reply type (%d) for TYPE on key '%s'!\n",
reply->type, keys->element[i]->str);
if(reply->type == REDIS_REPLY_ERROR) {
fprintf(stderr, "TYPE returned an error: %s\n", reply->str);
} else {
fprintf(stderr,
"Invalid reply type (%d) for TYPE on key '%s'!\n",
reply->type, keys->element[i]->str);
}
exit(1);
}
+2 -1
View File
@@ -1385,7 +1385,7 @@ int slaveTryPartialResynchronization(int fd, int read_reply) {
void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
char tmpfile[256], *err = NULL;
int dfd, maxtries = 5;
int dfd = -1, maxtries = 5;
int sockerr = 0, psync_result;
socklen_t errlen = sizeof(sockerr);
UNUSED(el);
@@ -1640,6 +1640,7 @@ void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
error:
aeDeleteFileEvent(server.el,fd,AE_READABLE|AE_WRITABLE);
if (dfd != -1) close(dfd);
close(fd);
server.repl_transfer_s = -1;
server.repl_state = REPL_STATE_CONNECT;
+2 -2
View File
@@ -443,6 +443,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
if (j == 10) {
cmdlog = sdscatprintf(cmdlog," ... (%d more)",
c->argc-j-1);
break;
} else {
cmdlog = sdscatlen(cmdlog," ",1);
cmdlog = sdscatsds(cmdlog,c->argv[j]->ptr);
@@ -900,7 +901,6 @@ void scriptingInit(int setup) {
server.lua_caller = NULL;
server.lua_timedout = 0;
server.lua_always_replicate_commands = 0; /* Only DEBUG can change it.*/
server.lua_time_limit = LUA_SCRIPT_TIME_LIMIT;
ldbInit();
}
@@ -2272,7 +2272,7 @@ ldbLog(sdsnew("[e]eval <code> Execute some Lua code (in a different callfr
ldbLog(sdsnew("[r]edis <cmd> Execute a Redis command."));
ldbLog(sdsnew("[m]axlen [len] Trim logged Redis replies and Lua var dumps to len."));
ldbLog(sdsnew(" Specifying zero as <len> means unlimited."));
ldbLog(sdsnew("[a]abort Stop the execution of the script. In sync"));
ldbLog(sdsnew("[a]bort Stop the execution of the script. In sync"));
ldbLog(sdsnew(" mode dataset changes will be retained."));
ldbLog(sdsnew(""));
ldbLog(sdsnew("Debugger functions you can call from Lua scripts:"));
+20 -4
View File
@@ -148,7 +148,7 @@ struct redisCommand redisCommandTable[] = {
{"linsert",linsertCommand,5,"wm",0,NULL,1,1,1,0,0},
{"rpop",rpopCommand,2,"wF",0,NULL,1,1,1,0,0},
{"lpop",lpopCommand,2,"wF",0,NULL,1,1,1,0,0},
{"brpop",brpopCommand,-3,"ws",0,NULL,1,1,1,0,0},
{"brpop",brpopCommand,-3,"ws",0,NULL,1,-2,1,0,0},
{"brpoplpush",brpoplpushCommand,4,"wms",0,NULL,1,2,1,0,0},
{"blpop",blpopCommand,-3,"ws",0,NULL,1,-2,1,0,0},
{"llen",llenCommand,2,"rF",0,NULL,1,1,1,0,0},
@@ -284,8 +284,10 @@ struct redisCommand redisCommandTable[] = {
{"wait",waitCommand,3,"s",0,NULL,0,0,0,0,0},
{"command",commandCommand,0,"lt",0,NULL,0,0,0,0,0},
{"geoadd",geoaddCommand,-5,"wm",0,NULL,1,1,1,0,0},
{"georadius",georadiusCommand,-6,"w",0,NULL,1,1,1,0,0},
{"georadiusbymember",georadiusByMemberCommand,-5,"w",0,NULL,1,1,1,0,0},
{"georadius",georadiusCommand,-6,"w",0,georadiusGetKeys,1,1,1,0,0},
{"georadius_ro",georadiusroCommand,-6,"r",0,georadiusGetKeys,1,1,1,0,0},
{"georadiusbymember",georadiusbymemberCommand,-5,"w",0,georadiusGetKeys,1,1,1,0,0},
{"georadiusbymember_ro",georadiusbymemberroCommand,-5,"r",0,georadiusGetKeys,1,1,1,0,0},
{"geohash",geohashCommand,-2,"r",0,NULL,1,1,1,0,0},
{"geopos",geoposCommand,-2,"r",0,NULL,1,1,1,0,0},
{"geodist",geodistCommand,-4,"r",0,NULL,1,1,1,0,0},
@@ -777,6 +779,11 @@ void activeExpireCycle(int type) {
int dbs_per_call = CRON_DBS_PER_CALL;
long long start = ustime(), timelimit;
/* When clients are paused the dataset should be static not just from the
* POV of clients not being able to write, but also from the POV of
* expires and evictions of keys not being performed. */
if (clientsArePaused()) return;
if (type == ACTIVE_EXPIRE_CYCLE_FAST) {
/* Don't start a fast cycle if the previous cycle did not exited
* for time limt. Also don't repeat a fast cycle for the same period
@@ -1533,6 +1540,7 @@ void initServerConfig(void) {
server.migrate_cached_sockets = dictCreate(&migrateCacheDictType,NULL);
server.next_client_id = 1; /* Client IDs, start from 1 .*/
server.loading_process_events_interval_bytes = (1024*1024*2);
server.lua_time_limit = LUA_SCRIPT_TIME_LIMIT;
server.lruclock = getLRUClock();
resetServerSaveParams();
@@ -1592,6 +1600,8 @@ void initServerConfig(void) {
server.rpopCommand = lookupCommandByCString("rpop");
server.sremCommand = lookupCommandByCString("srem");
server.execCommand = lookupCommandByCString("exec");
server.expireCommand = lookupCommandByCString("expire");
server.pexpireCommand = lookupCommandByCString("pexpire");
/* Slow log */
server.slowlog_log_slower_than = CONFIG_DEFAULT_SLOWLOG_LOG_SLOWER_THAN;
@@ -2585,8 +2595,9 @@ int prepareForShutdown(int flags) {
"There is a child rewriting the AOF. Killing it!");
kill(server.aof_child_pid,SIGUSR1);
}
/* Append only file: fsync() the AOF and exit */
/* Append only file: flush buffers and fsync() the AOF at exit */
serverLog(LL_NOTICE,"Calling fsync() on the AOF file.");
flushAppendOnlyFile(1);
aof_fsync(server.aof_fd);
}
@@ -3461,6 +3472,11 @@ int freeMemoryIfNeeded(void) {
int slaves = listLength(server.slaves);
mstime_t latency, eviction_latency;
/* When clients are paused the dataset should be static not just from the
* POV of clients not being able to write, but also from the POV of
* expires and evictions of keys not being performed. */
if (clientsArePaused()) return C_OK;
/* Remove the size of slaves output buffers and AOF buffer from the
* count of used memory. */
mem_used = zmalloc_used_memory();
+6 -2
View File
@@ -752,7 +752,8 @@ struct redisServer {
off_t loading_process_events_interval_bytes;
/* Fast pointers to often looked up command */
struct redisCommand *delCommand, *multiCommand, *lpushCommand, *lpopCommand,
*rpopCommand, *sremCommand, *execCommand;
*rpopCommand, *sremCommand, *execCommand, *expireCommand,
*pexpireCommand;
/* Fields used only for stats */
time_t stat_starttime; /* Server start time */
long long stat_numcommands; /* Number of processed commands */
@@ -1435,6 +1436,7 @@ int *zunionInterGetKeys(struct redisCommand *cmd,robj **argv, int argc, int *num
int *evalGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);
int *sortGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);
int *migrateGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);
int *georadiusGetKeys(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);
/* Cluster */
void clusterInit(void);
@@ -1633,8 +1635,10 @@ void replconfCommand(client *c);
void waitCommand(client *c);
void geoencodeCommand(client *c);
void geodecodeCommand(client *c);
void georadiusByMemberCommand(client *c);
void georadiusbymemberCommand(client *c);
void georadiusbymemberroCommand(client *c);
void georadiusCommand(client *c);
void georadiusroCommand(client *c);
void geoaddCommand(client *c);
void geohashCommand(client *c);
void geoposCommand(client *c);
+1 -1
View File
@@ -35,7 +35,7 @@ typedef struct slowlogEntry {
robj **argv;
int argc;
long long id; /* Unique entry identifier. */
long long duration; /* Time spent by the query, in nanoseconds. */
long long duration; /* Time spent by the query, in microseconds. */
time_t time; /* Unix time at which the query was executed. */
} slowlogEntry;
+1 -1
View File
@@ -1 +1 @@
#define REDIS_VERSION "3.2.8"
#define REDIS_VERSION "3.2.11"
+3 -2
View File
@@ -413,8 +413,9 @@ size_t zmalloc_get_memory_size(void) {
if (sysctl(mib, 2, &size, &len, NULL, 0) == 0)
return (size_t)size;
return 0L; /* Failed? */
#endif /* sysctl and sysconf variants */
#else
return 0L; /* Unknown method to get the data. */
#endif
#else
return 0L; /* Unknown OS. */
#endif
+1 -1
View File
@@ -110,7 +110,7 @@ foreach diskless {no yes} {
test_psync {no reconnection, just sync} 6 1000000 3600 0 {
} $diskless 0
test_psync {ok psync} 6 1000000 3600 0 {
test_psync {ok psync} 6 100000000 3600 0 {
assert {[s -1 sync_partial_ok] > 0}
} $diskless 1
+15
View File
@@ -204,4 +204,19 @@ start_server {tags {"expire"}} {
catch {r expire foo ""} e
set e
} {*not an integer*}
test {SET - use EX/PX option, TTL should not be reseted after loadaof} {
r config set appendonly yes
r set foo bar EX 100
after 2000
r debug loadaof
set ttl [r ttl foo]
assert {$ttl <= 98 && $ttl > 90}
r set foo bar PX 100000
after 2000
r debug loadaof
set ttl [r ttl foo]
assert {$ttl <= 98 && $ttl > 90}
}
}
+4 -4
View File
@@ -2,7 +2,7 @@ Create-custer is a small script used to easily start a big number of Redis
instances configured to run in cluster mode. Its main goal is to allow manual
testing in a condition which is not easy to replicate with the Redis cluster
unit tests, for example when a lot of instances are needed in order to trigger
a give bug.
a given bug.
The tool can also be used just to easily create a number of instances in a
Redis Cluster in order to experiment a bit with the system.
@@ -10,7 +10,7 @@ Redis Cluster in order to experiment a bit with the system.
USAGE
---
To create a cluster, follow this steps:
To create a cluster, follow these steps:
1. Edit create-cluster and change the start / end port, depending on the
number of instances you want to create.
@@ -21,7 +21,7 @@ an actual Redis cluster will be created.
In order to stop a cluster:
1. Use "./craete-cluster stop" to stop all the instances. After you stopped the instances you can use "./create-cluster start" to restart them if you change ideas.
2. Use "./create-cluster clean" to remove all the AOF / log files to restat with a clean environment.
1. Use "./create-cluster stop" to stop all the instances. After you stopped the instances you can use "./create-cluster start" to restart them if you change your mind.
2. Use "./create-cluster clean" to remove all the AOF / log files to restart with a clean environment.
Use the command "./create-cluster help" to get the full list of features.
+6 -6
View File
@@ -135,13 +135,13 @@ fi
echo "## Generated by install_server.sh ##" > $TMP_FILE
read -r SED_EXPR <<-EOF
s#^port [0-9]{4}\$#port ${REDIS_PORT}#; \
s#^logfile .+\$#logfile ${REDIS_LOG_FILE}#; \
s#^dir .+\$#dir ${REDIS_DATA_DIR}#; \
s#^pidfile .+\$#pidfile ${PIDFILE}#; \
s#^daemonize no\$#daemonize yes#;
s#^port .\+#port ${REDIS_PORT}#; \
s#^logfile .\+#logfile ${REDIS_LOG_FILE}#; \
s#^dir .\+#dir ${REDIS_DATA_DIR}#; \
s#^pidfile .\+#pidfile ${PIDFILE}#; \
s#^daemonize no#daemonize yes#;
EOF
sed -r "$SED_EXPR" $DEFAULT_CONFIG >> $TMP_FILE
sed "$SED_EXPR" $DEFAULT_CONFIG >> $TMP_FILE
#cat $TPL_FILE | while read line; do eval "echo \"$line\"" >> $TMP_FILE; done
cp $TMP_FILE $REDIS_CONFIG_FILE || die "Could not write redis config file $REDIS_CONFIG_FILE"