Compare commits

...

18 Commits

Author SHA1 Message Date
antirez
89514f80e9 Redis 2.6.3 2012-11-06 22:07:51 +01:00
Runzhen Wang
3f006679b1 fix a typo in redis.h line 595 comment 2012-11-02 12:12:01 +01:00
antirez
36f026a3a0 More robust handling of AOF rewrite child.
After the wait3() syscall we used to do something like that:

    if (pid == server.rdb_child_pid) {
        backgroundSaveDoneHandler(exitcode,bysignal);
    } else {
        ....
    }

So the AOF rewrite was handled in the else branch without actually
checking if the pid really matches. This commit makes the check explicit
and logs at WARNING level if the pid returned by wait3() does not match
neither the RDB or AOF rewrite child.
2012-11-01 22:41:57 +01:00
Salvatore Sanfilippo
cc017c5839 Merge pull request #743 from Cofyc/fixtypo
fix typo in comments (redis.c, networking.c)
2012-11-01 14:26:01 -07:00
antirez
b6ffa85f11 Unix socket clients properly displayed in MONITOR and CLIENT LIST.
This also fixes issue #745.
2012-11-01 22:12:45 +01:00
antirez
4917a6a8b3 32 bit build fixed on Linux.
It failed because of the way jemalloc was compiled (without passing the
right flags to make, but just to configure). Now the same set of flags
are also passed to the make command, fixing the issue.

This fixes issue #744
2012-11-01 15:37:38 +01:00
Yecheng Fu
ed44a74e72 fix typo in comments (redis.c, networking.c) 2012-11-01 18:14:55 +08:00
YAMAMOTO Takashi
47ff443b53 fix a typo in a comment 2012-10-31 09:29:56 +01:00
antirez
4d9bd53530 Invert two sides of if expression in SET to avoid a lookup.
Because of the short circuit behavior of && inverting the two sides of
the if expression avoids an hash table lookup if the non-EX variant of
SET is called.

Thanks to Weibin Yao (@yaoweibin on github) for spotting this.
2012-10-31 09:27:48 +01:00
antirez
5bf0997ff8 No longer used macro rdbIsOpcode() removed. 2012-10-30 19:10:56 +01:00
antirez
ec0f483de2 help.h update (adds bitop, bitcount, evalsha...) 2012-10-30 18:57:28 +01:00
antirez
0dd6241314 Redis 2.6.2 2012-10-26 16:20:24 +02:00
antirez
3b1a41b172 Ctrl+w support in linenoise. 2012-10-26 16:06:36 +02:00
antirez
9b3b110004 Marginally more robust glibc version test for sync_file_range detection. 2012-10-26 15:55:10 +02:00
charsyam
b25b0dc5f4 patch config.h for sync_file_range 2012-10-26 09:30:35 +02:00
antirez
2b5fc529a4 Redis 2.6.1 2012-10-25 22:07:27 +02:00
antirez
be407c015c Fix compilation on Linux kernels or glibc versions lacking sync_file_range().
This fixes issue #667.

Many thanks to Didier Spezia for the fix.
2012-10-25 22:01:07 +02:00
antirez
1eb9145089 Update memory peak stats while loading RDB / AOF. 2012-10-24 12:21:34 +02:00
14 changed files with 133 additions and 50 deletions

View File

@@ -14,6 +14,23 @@ 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.6.3 ]
* [BUGFIX] Fixed 32 bit build on Linux systems.
* [BUGFIX] MONITOR and CLIENT LIST: propertly display unix socket clients.
* [IMPROVED] redis-cli inline help updated.
* [IMPROVED] Marginally more robust AOF child handling.
* [IMPROVED] Fixed a few typos in comments.
$--[ Redis 2.6.2 ]
* [BUGFIX] The compilation fix for RHLE5 in 2.6.1 was broken. Fixed.
* [IMPROVED] Linenoise updated, now supports Ctrl+w.
---[ Redis 2.6.1 ]
* [BUGFIX] Compilation on Linux < 2.6.17 or glibc < 2.6 fixed (RHLE5 & co).
---[ Redis 2.6.0 ]
* [BUGFIX] Allow AUTH when server is in -BUSY state because of a slow script.

2
deps/Makefile vendored
View File

@@ -73,6 +73,6 @@ JEMALLOC_LDFLAGS= $(LDFLAGS)
jemalloc: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd jemalloc && ./configure --with-jemalloc-prefix=je_ --enable-cc-silence CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)"
cd jemalloc && $(MAKE) lib/libjemalloc.a
cd jemalloc && $(MAKE) CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" lib/libjemalloc.a
.PHONY: jemalloc

View File

@@ -8,34 +8,37 @@
* Does a number of crazy assumptions that happen to be true in 99.9999% of
* the 2010 UNIX computers around.
*
* ------------------------------------------------------------------------
*
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ------------------------------------------------------------------------
*
* References:
* - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
@@ -290,6 +293,8 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt)
size_t len = 0;
size_t cols = getColumns();
int history_index = 0;
size_t old_pos;
size_t diff;
buf[0] = '\0';
buflen--; /* Make sure there is always space for the nulterm */
@@ -465,6 +470,18 @@ up_down_arrow:
case 12: /* ctrl+l, clear screen */
linenoiseClearScreen();
refreshLine(fd,prompt,buf,len,pos,cols);
break;
case 23: /* ctrl+w, delete previous word */
old_pos = pos;
while (pos > 0 && buf[pos-1] == ' ')
pos--;
while (pos > 0 && buf[pos-1] != ' ')
pos--;
diff = old_pos - pos;
memmove(&buf[pos], &buf[old_pos], len-old_pos+1);
len -= diff;
refreshLine(fd,prompt,buf,len,pos,cols);
break;
}
}
return len;

View File

@@ -55,6 +55,20 @@
/* Define rdb_fsync_range to sync_file_range() on Linux, otherwise we use
* the plain fsync() call. */
#ifdef __linux__
#include <linux/version.h>
#include <features.h>
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
#if (LINUX_VERSION_CODE >= 0x020611 && __GLIBC_PREREQ(2, 6))
#define HAVE_SYNC_FILE_RANGE 1
#endif
#else
#if (LINUX_VERSION_CODE >= 0x020611)
#define HAVE_SYNC_FILE_RANGE 1
#endif
#endif
#endif
#ifdef HAVE_SYNC_FILE_RANGE
#define rdb_fsync_range(fd,off,size) sync_file_range(fd,off,size,SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE)
#else
#define rdb_fsync_range(fd,off,size) fsync(fd)

View File

@@ -44,6 +44,16 @@ struct commandHelp {
"Asynchronously save the dataset to disk",
9,
"1.0.0" },
{ "BITCOUNT",
"key [start] [end]",
"Count set bits in a string",
1,
"2.6.0" },
{ "BITOP",
"operation destkey key [key ...]",
"Perform bitwise operations between strings",
1,
"2.6.0" },
{ "BLPOP",
"key [key ...] timeout",
"Remove and get the first element in a list, or block until one is available",
@@ -59,6 +69,16 @@ struct commandHelp {
"Pop a value from a list, push it to another list and return it; or block until one is available",
2,
"2.2.0" },
{ "CLIENT KILL",
"ip:port",
"Kill the connection of a client",
9,
"2.4.0" },
{ "CLIENT LIST",
"-",
"Get the list of client connections",
9,
"2.4.0" },
{ "CONFIG GET",
"parameter",
"Get the value of a configuration parameter",
@@ -111,7 +131,7 @@ struct commandHelp {
"2.0.0" },
{ "DUMP",
"key",
"Return a serialized verison of the value stored at the specified key.",
"Return a serialized version of the value stored at the specified key.",
0,
"2.6.0" },
{ "ECHO",
@@ -124,6 +144,11 @@ struct commandHelp {
"Execute a Lua script server side",
10,
"2.6.0" },
{ "EVALSHA",
"sha1 numkeys key [key ...] arg [arg ...]",
"Execute a Lua script server side",
10,
"2.6.0" },
{ "EXEC",
"-",
"Execute all commands issued after MULTI",
@@ -575,8 +600,8 @@ struct commandHelp {
3,
"1.0.0" },
{ "SRANDMEMBER",
"key",
"Get a random member from a set",
"key [count]",
"Get one or multiple random members from a set",
3,
"1.0.0" },
{ "SREM",

View File

@@ -486,11 +486,11 @@ void copyClientOutputBuffer(redisClient *dst, redisClient *src) {
dst->reply_bytes = src->reply_bytes;
}
static void acceptCommonHandler(int fd) {
static void acceptCommonHandler(int fd, int flags) {
redisClient *c;
if ((c = createClient(fd)) == NULL) {
redisLog(REDIS_WARNING,"Error allocating resoures for the client");
close(fd); /* May be already closed, just ingore errors */
redisLog(REDIS_WARNING,"Error allocating resources for the client");
close(fd); /* May be already closed, just ignore errors */
return;
}
/* If maxclient directive is set and this is one client more... close the
@@ -509,6 +509,7 @@ static void acceptCommonHandler(int fd) {
return;
}
server.stat_numconnections++;
c->flags |= flags;
}
void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
@@ -524,7 +525,7 @@ void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
return;
}
redisLog(REDIS_VERBOSE,"Accepted %s:%d", cip, cport);
acceptCommonHandler(cfd);
acceptCommonHandler(cfd,0);
}
void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
@@ -539,7 +540,7 @@ void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
return;
}
redisLog(REDIS_VERBOSE,"Accepted connection to %s", server.unixsocket);
acceptCommonHandler(cfd);
acceptCommonHandler(cfd,REDIS_UNIX_SOCKET);
}
@@ -990,9 +991,9 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
server.current_client = c;
readlen = REDIS_IOBUF_LEN;
/* If this is a multi bulk request, and we are processing a bulk reply
* that is large enough, try to maximize the probabilty that the query
* buffer contains excatly the SDS string representing the object, even
* at the risk of requring more read(2) calls. This way the function
* that is large enough, try to maximize the probability that the query
* buffer contains exactly the SDS string representing the object, even
* at the risk of requiring more read(2) calls. This way the function
* processMultiBulkBuffer() can avoid copying buffers to create the
* Redis Object representing the argument. */
if (c->reqtype == REDIS_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1
@@ -1062,10 +1063,11 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
/* Turn a Redis client into an sds string representing its state. */
sds getClientInfoString(redisClient *client) {
char ip[32], flags[16], events[3], *p;
int port;
int port = 0; /* initialized to zero for the unix socket case. */
int emask;
anetPeerToString(client->fd,ip,&port);
if (!(client->flags & REDIS_UNIX_SOCKET))
anetPeerToString(client->fd,ip,&port);
p = flags;
if (client->flags & REDIS_SLAVE) {
if (client->flags & REDIS_MONITOR)
@@ -1080,6 +1082,7 @@ sds getClientInfoString(redisClient *client) {
if (client->flags & REDIS_CLOSE_AFTER_REPLY) *p++ = 'c';
if (client->flags & REDIS_UNBLOCKED) *p++ = 'u';
if (client->flags & REDIS_CLOSE_ASAP) *p++ = 'A';
if (client->flags & REDIS_UNIX_SOCKET) *p++ = 'U';
if (p == flags) *p++ = 'N';
*p++ = '\0';
@@ -1090,7 +1093,8 @@ sds getClientInfoString(redisClient *client) {
*p = '\0';
return sdscatprintf(sdsempty(),
"addr=%s:%d fd=%d age=%ld idle=%ld flags=%s db=%d sub=%d psub=%d multi=%d qbuf=%lu qbuf-free=%lu obl=%lu oll=%lu omem=%lu events=%s cmd=%s",
ip,port,client->fd,
(client->flags & REDIS_UNIX_SOCKET) ? server.unixsocket : ip,
port,client->fd,
(long)(server.unixtime - client->ctime),
(long)(server.unixtime - client->lastinteraction),
flags,
@@ -1227,7 +1231,7 @@ unsigned long getClientOutputBufferMemoryUsage(redisClient *c) {
return c->reply_bytes + (list_item_size*listLength(c->reply));
}
/* Get the class of a client, used in order to envorce limits to different
/* Get the class of a client, used in order to enforce limits to different
* classes of clients.
*
* The function will return one of the following:

View File

@@ -1010,6 +1010,8 @@ void startLoading(FILE *fp) {
/* Refresh the loading progress info */
void loadingProgress(off_t pos) {
server.loading_loaded_bytes = pos;
if (server.stat_peak_memory < zmalloc_used_memory())
server.stat_peak_memory = zmalloc_used_memory();
}
/* Loading finished */

View File

@@ -62,9 +62,6 @@
#define REDIS_RDB_OPCODE_SELECTDB 254
#define REDIS_RDB_OPCODE_EOF 255
/* Test if a type is an opcode. */
#define rdbIsOpcode(t) (t >= 253 && t <= 255)
int rdbSaveType(rio *rdb, unsigned char type);
int rdbLoadType(rio *rdb);
int rdbSaveTime(rio *rdb, time_t t);

View File

@@ -902,8 +902,12 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
if (pid == server.rdb_child_pid) {
backgroundSaveDoneHandler(exitcode,bysignal);
} else {
} else if (pid == server.aof_child_pid) {
backgroundRewriteDoneHandler(exitcode,bysignal);
} else {
redisLog(REDIS_WARNING,
"Warning, detected child with unmatched pid: %ld",
(long)pid);
}
updateDictResizePolicy();
}
@@ -1527,7 +1531,7 @@ void call(redisClient *c, int flags) {
}
/* If this function gets called we already read a whole
* command, argments are in the client argv/argc fields.
* command, arguments are in the client argv/argc fields.
* processCommand() execute the command or prepare the
* server for a bulk read from the client.
*
@@ -2175,7 +2179,7 @@ void infoCommand(redisClient *c) {
}
void monitorCommand(redisClient *c) {
/* ignore MONITOR if aleady slave or in monitor mode */
/* ignore MONITOR if already slave or in monitor mode */
if (c->flags & REDIS_SLAVE) return;
c->flags |= (REDIS_SLAVE|REDIS_MONITOR);
@@ -2274,7 +2278,7 @@ int freeMemoryIfNeeded(void) {
de = dictGetRandomKey(dict);
thiskey = dictGetKey(de);
/* When policy is volatile-lru we need an additonal lookup
/* When policy is volatile-lru we need an additional lookup
* to locate the real key, as dict is set to db->expires. */
if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
de = dictFind(db->dict, thiskey);
@@ -2576,7 +2580,7 @@ int main(int argc, char **argv) {
redisAsciiArt();
if (!server.sentinel_mode) {
/* Things only needed when not runnign in Sentinel mode. */
/* Things only needed when not running in Sentinel mode. */
redisLog(REDIS_WARNING,"Server started, Redis version " REDIS_VERSION);
#ifdef __linux__
linuxOvercommitMemoryWarning();

View File

@@ -152,6 +152,7 @@
#define REDIS_LUA_CLIENT 512 /* This is a non connected client used by Lua */
#define REDIS_ASKING 1024 /* Client issued the ASKING command */
#define REDIS_CLOSE_ASAP 2048 /* Close this client ASAP */
#define REDIS_UNIX_SOCKET 4096 /* Client connected via Unix domain socket */
/* Client request types */
#define REDIS_REQ_INLINE 1
@@ -464,7 +465,7 @@ typedef struct redisOpArray {
struct redisServer {
/* General */
redisDb *db;
dict *commands; /* Command table hahs table */
dict *commands; /* Command table hash table */
aeEventLoop *el;
unsigned lruclock:22; /* Clock incrementing every minute, for LRU */
unsigned lruclock_padding:10;

View File

@@ -54,10 +54,12 @@ void replicationFeedMonitors(redisClient *c, list *monitors, int dictid, robj **
gettimeofday(&tv,NULL);
cmdrepr = sdscatprintf(cmdrepr,"%ld.%06ld ",(long)tv.tv_sec,(long)tv.tv_usec);
if (c->flags & REDIS_LUA_CLIENT) {
cmdrepr = sdscatprintf(cmdrepr,"[%d lua] ", dictid);
cmdrepr = sdscatprintf(cmdrepr,"[%d lua] ",dictid);
} else if (c->flags & REDIS_UNIX_SOCKET) {
cmdrepr = sdscatprintf(cmdrepr,"[%d unix:%s] ",dictid,server.unixsocket);
} else {
anetPeerToString(c->fd,ip,&port);
cmdrepr = sdscatprintf(cmdrepr,"[%d %s:%d] ", dictid,ip,port);
cmdrepr = sdscatprintf(cmdrepr,"[%d %s:%d] ",dictid,ip,port);
}
for (j = 0; j < argc; j++) {

View File

@@ -26,7 +26,7 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
if (unit == UNIT_SECONDS) milliseconds *= 1000;
}
if (lookupKeyWrite(c->db,key) != NULL && nx) {
if (nx && lookupKeyWrite(c->db,key) != NULL) {
addReply(c,shared.czero);
return;
}

View File

@@ -1 +1 @@
#define REDIS_VERSION "2.6.0"
#define REDIS_VERSION "2.6.3"

View File

@@ -107,7 +107,7 @@ proc tags {tags code} {
}
proc start_server {options {code undefined}} {
# If we are runnign against an external server, we just push the
# If we are running against an external server, we just push the
# host/port pair in the stack the first time
if {$::external} {
if {[llength $::servers] == 0} {