diff options
-rw-r--r-- | 00-RELEASENOTES | 21 | ||||
-rwxr-xr-x | redis.conf | 67 | ||||
-rwxr-xr-x | runtest | 15 | ||||
-rwxr-xr-x | src/Makefile | 5 | ||||
-rw-r--r-- | src/anet.c | 63 | ||||
-rw-r--r-- | src/anet.h | 4 | ||||
-rwxr-xr-x | src/config.c | 21 | ||||
-rw-r--r-- | src/networking.c | 4 | ||||
-rwxr-xr-x | src/redis.c | 6 | ||||
-rwxr-xr-x | src/redis.h | 2 | ||||
-rwxr-xr-x | src/replication.c | 7 | ||||
-rw-r--r-- | src/sentinel.c | 10 | ||||
-rw-r--r-- | src/t_set.c | 4 | ||||
-rw-r--r-- | src/version.h | 2 | ||||
-rw-r--r-- | src/ziplist.c | 4 | ||||
-rw-r--r-- | tests/assets/default.conf | 2 | ||||
-rw-r--r-- | tests/integration/replication-4.tcl | 3 | ||||
-rw-r--r-- | tests/integration/replication.tcl | 3 | ||||
-rw-r--r-- | tests/test_helper.tcl | 5 |
19 files changed, 206 insertions, 42 deletions
diff --git a/00-RELEASENOTES b/00-RELEASENOTES index 2c5010660..3306784e5 100644 --- a/00-RELEASENOTES +++ b/00-RELEASENOTES @@ -14,6 +14,27 @@ 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.10 ] + +UPGRADE URGENCY: MODERATE, this release contains many non-critical fixes + and many small improvements. + +* [BUGFIX] redis-cli --rdb, fixed when the server sends newlines to ping. +* [BUGFIX] redis-cli, minor fixes on connection handling, prompt. +* [BUGFIX] Slow log: don't log EXEC, just executed commands. +* [BUGFIX] On failed shutdown don't try again and again compulsively. +* [BUGFIX] Fix build on sunos without backtrace(). +* [BUGFIX] UNSUBSCRIBE and PUNSUBSCRIBE: always provide a reply (see 742e580) +* [BUGFIX] Lua struct library was broken, upgraded. +* [BUGFIX] Fix a bug in srandmemberWithCountCommand() with count argument. +* [BUGFIX] Test: disable clients timeout to prevent issues on slow systems. +* [BUGFIX] Sentinel: don't advertise the promoted slave as master too early. +* [IMPROVED] Whitelist SIGUSR1, see http://redis.io/topics/signals. +* [IMPROVED] Simpler to understand redis-cli --bigkeys output. +* [IMPROVED] Test now works with tclsh > 8.5. +* [IMPROVED] Added option to turn of the Nagle algorithm in slave socket. +* [IMPROVED] Optionally use SO_KEEPALIVE to detect dead peers. + --[ Redis 2.6.9 ] UPGRADE URGENCY: MODERATE if you use replication. diff --git a/redis.conf b/redis.conf index 6da381361..24e0372f4 100755 --- a/redis.conf +++ b/redis.conf @@ -39,8 +39,24 @@ port 6379 # Close the connection after a client is idle for N seconds (0 to disable) timeout 0 -# Set server verbosity to 'debug' -# it can be one of: +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 60 seconds. +tcp-keepalive 0 + +# Specify the server verbosity level. +# This can be one of: # debug (a lot of information, useful for development/testing) # verbose (many rarely useful info, but not a mess like the debug level) # notice (moderately verbose, what you want in production probably) @@ -59,7 +75,7 @@ logfile stdout # Specify the syslog identity. # syslog-ident redis -# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # syslog-facility local0 # Set the number of databases. The default database is DB 0, you can select @@ -114,7 +130,7 @@ stop-writes-on-bgsave-error yes # the dataset will likely be bigger if you have compressible values or keys. rdbcompression yes -# Since verison 5 of RDB a CRC64 checksum is placed at the end of the file. +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. # This makes the format more resistant to corruption but there is a performance # hit to pay (around 10%) when saving and loading RDB files, so you can disable it # for maximum performances. @@ -138,7 +154,7 @@ load-on-startup yes # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # -# Also the Append Only File will be created inside this directory. +# The Append Only File will also be created inside this directory. # # Note that you must specify a directory here, not a file name. dir ./ @@ -159,7 +175,7 @@ dir ./ # # masterauth <master-password> -# When a slave lost the connection with the master, or when the replication +# When a slave loses its connection with the master, or when the replication # is still in progress, the slave can act in two different ways: # # 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will @@ -207,6 +223,21 @@ slave-read-only yes # to be maintained and has a slight affect on performance. conditional-sync yes +# Disable TCP_NODELAY on the slave socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to slaves. But this can add a delay for +# the data to appear on the slave side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the slave side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and slaves are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + # The slave priority is an integer number published by Redis in the INFO output. # It is used by Redis Sentinel in order to select a slave to promote into a # master if the master is no longer working correctly. @@ -241,14 +272,14 @@ slave-priority 100 # # It is possible to change the name of dangerous commands in a shared # environment. For instance the CONFIG command may be renamed into something -# of hard to guess so that it will be still available for internal-use -# tools but not available for general clients. +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. # # Example: # # rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 # -# It is also possible to completely kill a command renaming it into +# It is also possible to completely kill a command by renaming it into # an empty string: # # rename-command CONFIG "" @@ -292,7 +323,7 @@ slave-priority 100 # maxmemory <bytes> # MAXMEMORY POLICY: how Redis will select what to remove when maxmemory -# is reached? You can select among five behavior: +# is reached. You can select among five behaviors: # # volatile-lru -> remove the key with an expire set using an LRU algorithm # allkeys-lru -> remove any key accordingly to the LRU algorithm @@ -301,7 +332,7 @@ slave-priority 100 # volatile-ttl -> remove the key with the nearest expire time (minor TTL) # noeviction -> don't expire at all, just return an error on write operations # -# Note: with all the kind of policies, Redis will return an error on write +# Note: with any of the above policies, Redis will return an error on write # operations, when there are not suitable keys for eviction. # # At the date of writing this commands are: set setnx setex append @@ -363,7 +394,7 @@ appendonly no # always: fsync after every write to the append only log . Slow, Safest. # everysec: fsync only one time every second. Compromise. # -# The default is "everysec" that's usually the right compromise between +# The default is "everysec", as that's usually the right compromise between # speed and data safety. It's up to you to understand if you can relax this to # "no" that will let the operating system flush the output buffer when # it wants, for better performances (but if you can live with the idea of @@ -391,9 +422,9 @@ appendfsync everysec # that will prevent fsync() from being called in the main process while a # BGSAVE or BGREWRITEAOF is in progress. # -# This means that while another child is saving the durability of Redis is -# the same as "appendfsync none", that in practical terms means that it is -# possible to lost up to 30 seconds of log in the worst scenario (with the +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the # default Linux settings). # # If you have latency problems turn this to "yes". Otherwise leave it as @@ -402,10 +433,10 @@ no-appendfsync-on-rewrite no # Automatic rewrite of the append only file. # Redis is able to automatically rewrite the log file implicitly calling -# BGREWRITEAOF when the AOF log size will growth by the specified percentage. +# BGREWRITEAOF when the AOF log size grows by the specified percentage. # # This is how it works: Redis remembers the size of the AOF file after the -# latest rewrite (or if no rewrite happened since the restart, the size of +# latest rewrite (if no rewrite has happened since the restart, the size of # the AOF at startup is used). # # This base size is compared to the current size. If the current size is @@ -541,7 +572,7 @@ activerehashing yes # Instead there is a default limit for pubsub and slave clients, since # subscribers and slaves receive data in a push fashion. # -# Both the hard or the soft limit can be disabled just setting it to zero. +# Both the hard or the soft limit can be disabled by setting them to zero. client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 @@ -1,9 +1,14 @@ #!/bin/sh -TCL=tclsh8.5 -which $TCL -if [ "$?" != "0" ] +TCL_VERSIONS="8.5 8.6" +TCLSH="" + +for VERSION in $TCL_VERSIONS; do + TCL=`which tclsh$VERSION 2>/dev/null` && TCLSH=$TCL +done + +if [ -z $TCLSH ] then - echo "You need '$TCL' in order to run the Redis test" + echo "You need tcl 8.5 or newer in order to run the Redis test" exit 1 fi @@ -16,7 +21,7 @@ fi ln -sf obj.${BUILD_ARCH}/redis-server src/redis-server ln -sf obj.${BUILD_ARCH}/redis-check-aof src/redis-check-aof -$TCL tests/test_helper.tcl $* +$TCLSH tests/test_helper.tcl $* rm src/redis-server rm src/redis-check-aof diff --git a/src/Makefile b/src/Makefile index ebf5786e2..7a553d030 100755 --- a/src/Makefile +++ b/src/Makefile @@ -241,7 +241,10 @@ gcov: $(MAKE) REDIS_CFLAGS="-fprofile-arcs -ftest-coverage -DCOVERAGE_TEST" REDIS_LDFLAGS="-fprofile-arcs -ftest-coverage" noopt: - $(MAKE) OPT="-O0" + $(MAKE) OPTIMIZATION="-O0" + +valgrind: + $(MAKE) OPTIMIZATION="-O0" MALLOC="libc" src/help.h: @$(SRCDIR)/../utils/generate-command-help.rb > help.h diff --git a/src/anet.c b/src/anet.c index 4da3e28db..963b6688e 100644 --- a/src/anet.c +++ b/src/anet.c @@ -75,10 +75,56 @@ int anetNonBlock(char *err, int fd) return ANET_OK; } -int anetTcpNoDelay(char *err, int fd) +/* Set TCP keep alive option to detect dead peers. The interval option + * is only used for Linux as we are using Linux-specific APIs to set + * the probe send time, interval, and count. */ +int anetKeepAlive(char *err, int fd, int interval) { - int yes = 1; - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) + int val = 1; + + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1) + { + anetSetError(err, "setsockopt SO_KEEPALIVE: %s", strerror(errno)); + return ANET_ERR; + } + +#ifdef __linux__ + /* Default settings are more or less garbage, with the keepalive time + * set to 7200 by default on Linux. Modify settings to make the feature + * actually useful. */ + + /* Send first probe after interval. */ + val = interval; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPIDLE: %s\n", strerror(errno)); + return ANET_ERR; + } + + /* Send next probes after the specified interval. Note that we set the + * delay as interval / 3, as we send three probes before detecting + * an error (see the next setsockopt call). */ + val = interval/3; + if (val == 0) val = 1; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPINTVL: %s\n", strerror(errno)); + return ANET_ERR; + } + + /* Consider the socket in error state after three we send three ACK + * probes without getting a reply. */ + val = 3; + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) { + anetSetError(err, "setsockopt TCP_KEEPCNT: %s\n", strerror(errno)); + return ANET_ERR; + } +#endif + + return ANET_OK; +} + +static int anetSetTcpNoDelay(char *err, int fd, int val) +{ + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) == -1) { anetSetError(err, "setsockopt TCP_NODELAY: %s", strerror(errno)); return ANET_ERR; @@ -86,6 +132,17 @@ int anetTcpNoDelay(char *err, int fd) return ANET_OK; } +int anetEnableTcpNoDelay(char *err, int fd) +{ + return anetSetTcpNoDelay(err, fd, 1); +} + +int anetDisableTcpNoDelay(char *err, int fd) +{ + return anetSetTcpNoDelay(err, fd, 0); +} + + int anetSetSendBuffer(char *err, int fd, int buffsize) { if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffsize, sizeof(buffsize)) == -1) diff --git a/src/anet.h b/src/anet.h index 062b22c56..696c2c225 100644 --- a/src/anet.h +++ b/src/anet.h @@ -51,8 +51,10 @@ int anetTcpAccept(char *err, int serversock, char *ip, int *port); int anetUnixAccept(char *err, int serversock); int anetWrite(int fd, char *buf, int count); int anetNonBlock(char *err, int fd); -int anetTcpNoDelay(char *err, int fd); +int anetEnableTcpNoDelay(char *err, int fd); +int anetDisableTcpNoDelay(char *err, int fd); int anetTcpKeepAlive(char *err, int fd); int anetPeerToString(int fd, char *ip, int *port); +int anetKeepAlive(char *err, int fd, int interval); #endif diff --git a/src/config.c b/src/config.c index 71157313c..dbea5513d 100755 --- a/src/config.c +++ b/src/config.c @@ -81,6 +81,11 @@ void loadServerConfigFromString(char *config) { if (server.maxidletime < 0) { err = "Invalid timeout value"; goto loaderr; } + } else if (!strcasecmp(argv[0],"tcp-keepalive") && argc == 2) { + server.tcpkeepalive = atoi(argv[1]); + if (server.tcpkeepalive < 0) { + err = "Invalid tcp-keepalive value"; goto loaderr; + } } else if (!strcasecmp(argv[0],"port") && argc == 2) { server.port = atoi(argv[1]); if (server.port < 0 || server.port > 65535) { @@ -238,6 +243,10 @@ void loadServerConfigFromString(char *config) { err = "repl-timeout must be 1 or greater"; goto loaderr; } + } else if (!strcasecmp(argv[0],"repl-disable-tcp-nodelay") && argc==2) { + if ((server.repl_disable_tcp_nodelay = yesnotoi(argv[1])) == -1) { + err = "argument must be 'yes' or 'no'"; goto loaderr; + } } else if (!strcasecmp(argv[0],"masterauth") && argc == 2) { server.masterauth = zstrdup(argv[1]); } else if (!strcasecmp(argv[0],"slave-serve-stale-data") && argc == 2) { @@ -521,6 +530,10 @@ void configSetCommand(redisClient *c) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll < 0 || ll > LONG_MAX) goto badfmt; server.maxidletime = ll; + } else if (!strcasecmp(c->argv[2]->ptr,"tcp-keepalive")) { + if (getLongLongFromObject(o,&ll) == REDIS_ERR || + ll < 0 || ll > INT_MAX) goto badfmt; + server.tcpkeepalive = ll; } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) { if (!strcasecmp(o->ptr,"no")) { server.aof_fsync = AOF_FSYNC_NO; @@ -719,6 +732,11 @@ void configSetCommand(redisClient *c) { if (yn == -1) goto badfmt; server.rdb_checksum = yn; + } else if (!strcasecmp(c->argv[2]->ptr,"repl-disable-tcp-nodelay")) { + int yn = yesnotoi(o->ptr); + + if (yn == -1) goto badfmt; + server.repl_disable_tcp_nodelay = yn; } else if (!strcasecmp(c->argv[2]->ptr,"slave-priority")) { if (getLongLongFromObject(o,&ll) == REDIS_ERR || ll <= 0) goto badfmt; @@ -784,6 +802,7 @@ void configGetCommand(redisClient *c) { config_get_numerical_field("maxmemory",server.maxmemory); config_get_numerical_field("maxmemory-samples",server.maxmemory_samples); config_get_numerical_field("timeout",server.maxidletime); + config_get_numerical_field("tcp-keepalive",server.tcpkeepalive); config_get_numerical_field("auto-aof-rewrite-percentage", server.aof_rewrite_perc); config_get_numerical_field("auto-aof-rewrite-min-size", @@ -828,6 +847,8 @@ void configGetCommand(redisClient *c) { config_get_bool_field("rdbcompression", server.rdb_compression); config_get_bool_field("rdbchecksum", server.rdb_checksum); config_get_bool_field("activerehashing", server.activerehashing); + config_get_bool_field("repl-disable-tcp-nodelay", + server.repl_disable_tcp_nodelay); /* Everything we can't handle with macros follows. */ diff --git a/src/networking.c b/src/networking.c index 6e5d32489..3f14b17c8 100644 --- a/src/networking.c +++ b/src/networking.c @@ -58,7 +58,9 @@ redisClient *createClient(int fd) { * contexts (for instance a Lua script) we need a non connected client. */ if (fd != -1) { anetNonBlock(NULL,fd); - anetTcpNoDelay(NULL,fd); + anetEnableTcpNoDelay(NULL,fd); + if (server.tcpkeepalive) + anetKeepAlive(NULL,fd,server.tcpkeepalive); if (aeCreateFileEvent(server.el,fd,AE_READABLE, readQueryFromClient, c) == AE_ERR) { diff --git a/src/redis.c b/src/redis.c index 9b4e1ac28..e6faf8ada 100755 --- a/src/redis.c +++ b/src/redis.c @@ -215,7 +215,7 @@ struct redisCommand redisCommandTable[] = { {"bgsaveto",bgsavetoCommand,2,"ar",0,NULL,0,0,0,0,0}, {"bgrewriteaof",bgrewriteaofCommand,1,"ar",0,NULL,0,0,0,0,0}, {"shutdown",shutdownCommand,-1,"ar",0,NULL,0,0,0,0,0}, - {"lastsave",lastsaveCommand,1,"r",0,NULL,0,0,0,0,0}, + {"lastsave",lastsaveCommand,1,"rR",0,NULL,0,0,0,0,0}, {"type",typeCommand,2,"r",0,NULL,1,1,1,0,0}, {"multi",multiCommand,1,"rs",0,NULL,0,0,0,0,0}, {"exec",execCommand,1,"sM",0,NULL,0,0,0,0,0}, @@ -541,7 +541,7 @@ dictType commandTableDictType = { NULL /* val destructor */ }; -/* Hash type hash table (note that small hashes are represented with zipmaps) */ +/* Hash type hash table (note that small hashes are represented with ziplists) */ dictType hashDictType = { dictEncObjHash, /* hash function */ NULL, /* key dup */ @@ -1187,6 +1187,7 @@ void initServerConfig() { server.dbnum = REDIS_DEFAULT_DBNUM; server.verbosity = REDIS_NOTICE; server.maxidletime = REDIS_MAXIDLETIME; + server.tcpkeepalive = 0; server.client_max_querybuf_len = REDIS_MAX_QUERYBUF_LEN; server.saveparams = NULL; server.loading = 0; @@ -1256,6 +1257,7 @@ void initServerConfig() { server.repl_serve_stale_data = 1; server.repl_slave_ro = 1; server.repl_down_since = time(NULL); + server.repl_disable_tcp_nodelay = 0; server.slave_priority = REDIS_DEFAULT_SLAVE_PRIORITY; /* Client output buffer limits */ diff --git a/src/redis.h b/src/redis.h index 3319aa87b..b4d58db40 100755 --- a/src/redis.h +++ b/src/redis.h @@ -574,6 +574,7 @@ struct redisServer { /* Configuration */ int verbosity; /* Loglevel in redis.conf */ int maxidletime; /* Client timeout in seconds */ + int tcpkeepalive; /* Set SO_KEEPALIVE if non-zero. */ size_t client_max_querybuf_len; /* Limit for client query buffer length */ int dbnum; /* Total number of configured DBs */ int daemonize; /* True if running as a daemon */ @@ -647,6 +648,7 @@ struct redisServer { int repl_serve_stale_data; /* Serve stale data when link is down? */ int repl_slave_ro; /* Slave is read only? */ time_t repl_down_since; /* Unix time at which link with master went down */ + int repl_disable_tcp_nodelay; /* Disable TCP_NODELAY after SYNC? */ int slave_priority; /* Reported in INFO and used by Sentinel. */ /* Limits */ unsigned int maxclients; /* Max number of simultaneous clients */ diff --git a/src/replication.c b/src/replication.c index 9c6d4dff7..7fbc4591b 100755 --- a/src/replication.c +++ b/src/replication.c @@ -276,7 +276,11 @@ void syncCommand(redisClient *c) { } c->repldbfd = -1; } - + + if (server.repl_disable_tcp_nodelay) + anetDisableTcpNoDelay(NULL, c->fd); /* Non critical if it fails. */ + c->repldbfd = -1; + c->flags |= REDIS_SLAVE; c->slaveseldb = 0; listAddNodeTail(server.slaves,c); @@ -539,6 +543,7 @@ void readSyncBulkPayload(aeEventLoop *el, int fd, void *privdata, int mask) { return; } redisLog(REDIS_NOTICE, "MASTER <-> SLAVE sync: Loading DB in memory"); + signalFlushedDb(-1); emptyDb(); /* Before loading the DB into memory we need to delete the readable * handler, otherwise it will get called recursively since diff --git a/src/sentinel.c b/src/sentinel.c index 8009e5ed9..fc857344c 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -2035,8 +2035,16 @@ void sentinelCommand(redisClient *c) { } else { sentinelAddr *addr = ri->addr; - if ((ri->flags & SRI_FAILOVER_IN_PROGRESS) && ri->promoted_slave) + /* If we are in the middle of a failover, and the slave was + * already successfully switched to master role, we can advertise + * the new address as slave in order to allow clients to talk + * with the new master ASAP. */ + if ((ri->flags & SRI_FAILOVER_IN_PROGRESS) && + ri->promoted_slave && + ri->failover_state >= SENTINEL_FAILOVER_STATE_RECONF_SLAVES) + { addr = ri->promoted_slave->addr; + } addReplyMultiBulkLen(c,2); addReplyBulkCString(c,addr->ip); addReplyBulkLongLong(c,addr->port); diff --git a/src/t_set.c b/src/t_set.c index f384dc76c..2cdcf86c6 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -451,7 +451,7 @@ void srandmemberWithCountCommand(redisClient *c) { * The number of requested elements is greater than the number of * elements inside the set: simply return the whole set. */ if (count >= size) { - sunionDiffGenericCommand(c,c->argv,c->argc-1,NULL,REDIS_OP_UNION); + sunionDiffGenericCommand(c,c->argv+1,1,NULL,REDIS_OP_UNION); return; } @@ -473,7 +473,7 @@ void srandmemberWithCountCommand(redisClient *c) { /* Add all the elements into the temporary dictionary. */ si = setTypeInitIterator(set); while((encoding = setTypeNext(si,&ele,&llele)) != -1) { - int retval; + int retval = DICT_ERR; if (encoding == REDIS_ENCODING_INTSET) { retval = dictAdd(d,createStringObjectFromLongLong(llele),NULL); diff --git a/src/version.h b/src/version.h index 293bd1bfb..765dc9100 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define REDIS_VERSION "2.6.9" +#define REDIS_VERSION "2.6.10" diff --git a/src/ziplist.c b/src/ziplist.c index d4ac4f9b4..8a6b54a7c 100644 --- a/src/ziplist.c +++ b/src/ziplist.c @@ -739,10 +739,10 @@ unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) { } } -/* Get entry pointer to by 'p' and store in either 'e' or 'v' depending +/* Get entry pointed to by 'p' and store in either 'e' or 'v' depending * on the encoding of the entry. 'e' is always set to NULL to be able * to find out whether the string pointer or the integer value was set. - * Return 0 if 'p' points to the end of the zipmap, 1 otherwise. */ + * Return 0 if 'p' points to the end of the ziplist, 1 otherwise. */ unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *slen, long long *sval) { zlentry entry; if (p == NULL || p[0] == ZIP_END) return 0; diff --git a/tests/assets/default.conf b/tests/assets/default.conf index 976852e91..c76eca3eb 100644 --- a/tests/assets/default.conf +++ b/tests/assets/default.conf @@ -35,7 +35,7 @@ port 6379 # unixsocket /tmp/redis.sock # Close the connection after a client is idle for N seconds (0 to disable) -timeout 300 +timeout 0 # Set server verbosity to 'debug' # it can be one of: diff --git a/tests/integration/replication-4.tcl b/tests/integration/replication-4.tcl index 69fcab373..0a0dcdc2b 100644 --- a/tests/integration/replication-4.tcl +++ b/tests/integration/replication-4.tcl @@ -1,5 +1,6 @@ proc start_bg_complex_data {host port db ops} { - exec tclsh8.5 tests/helpers/bg_complex_data.tcl $host $port $db $ops & + set tclsh [info nameofexecutable] + exec $tclsh tests/helpers/bg_complex_data.tcl $host $port $db $ops & } proc stop_bg_complex_data {handle} { diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl index da94b0880..5ca6449f4 100644 --- a/tests/integration/replication.tcl +++ b/tests/integration/replication.tcl @@ -78,7 +78,8 @@ start_server {tags {"repl"}} { } proc start_write_load {host port seconds} { - exec tclsh8.5 tests/helpers/gen_write_load.tcl $host $port $seconds & + set tclsh [info nameofexecutable] + exec $tclsh tests/helpers/gen_write_load.tcl $host $port $seconds & } proc stop_write_load {handle} { diff --git a/tests/test_helper.tcl b/tests/test_helper.tcl index 38fb1f539..483774219 100644 --- a/tests/test_helper.tcl +++ b/tests/test_helper.tcl @@ -2,6 +2,8 @@ # This softare is released under the BSD License. See the COPYING file for # more information. +package require Tcl 8.5 + set tcl_precision 17 source tests/support/redis.tcl source tests/support/server.tcl @@ -176,6 +178,7 @@ proc find_available_port start { proc test_server_main {} { cleanup + set tclsh [info nameofexecutable] # Open a listening socket, trying different ports in order to find a # non busy one. set port [find_available_port 11111] @@ -189,7 +192,7 @@ proc test_server_main {} { set start_port [expr {$::port+100}] for {set j 0} {$j < $::numclients} {incr j} { set start_port [find_available_port $start_port] - set p [exec tclsh8.5 [info script] {*}$::argv \ + set p [exec $tclsh [info script] {*}$::argv \ --client $port --port $start_port &] lappend ::clients_pids $p incr start_port 10 |