Permalink
Browse files

Merge upstream 2.6.10.

  • Loading branch information...
yossigo committed Feb 25, 2013
2 parents acb73e8 + 948fdb5 commit 1a6f05c5a00a4eef852c09256e2f664bce297e93
View
@@ -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.
View
@@ -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
View
15 runtest
@@ -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
View
@@ -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
View
@@ -75,17 +75,74 @@ 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;
}
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)
View
@@ -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
View
@@ -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. */
View
@@ -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)
{
Oops, something went wrong.

0 comments on commit 1a6f05c

Please sign in to comment.