Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
214cf63730 | ||
|
|
4a4f4cb5ff | ||
|
|
a57bd791e9 | ||
|
|
ed9f997ce5 | ||
|
|
55eea93cae | ||
|
|
753e91b6c1 | ||
|
|
a830d941a7 | ||
|
|
9c3a89853c | ||
|
|
7ca6672338 | ||
|
|
6c68df4f32 | ||
|
|
8b58723eb2 | ||
|
|
abd4cd7827 |
@@ -7,7 +7,8 @@ Redis 2.2 is mostly a strict subset of 2.4.
|
||||
The only thing you should be aware is that you can't use .rdb and AOF files
|
||||
generated with 2.4 into a 2.2 instance.
|
||||
|
||||
2.4 slaves can be attached to 2.2 masters, but not the contrary.
|
||||
2.4 slaves can be attached to 2.2 masters, but not the contrary, and only for
|
||||
the time needed to perform the version upgrade.
|
||||
|
||||
From the point of view of the API Redis 2.4 only adds new commands
|
||||
(other commands now accepts a variable number of arguments) so you don't need
|
||||
@@ -17,13 +18,20 @@ to modify your program in order to use Redis 2.4.
|
||||
CHANGELOG
|
||||
---------
|
||||
|
||||
What's new in Redis 2.3.5 (2.4 Release Candidate 1)
|
||||
What's new in Redis 2.3.9 (2.4 Release Candidate 6)
|
||||
===================================================
|
||||
|
||||
This is the first Release Candidate of Redis 2.4, in our experience the
|
||||
server is very stable, however it is always better to closely monitor your
|
||||
server if you switch to 2.4 RC1. Also make sure to perform a backup of your
|
||||
old data set before switching from 2.2 to 2.4.
|
||||
* [BUGFIX] Fixed a bug with the automatic AOF rewrite causing continuous
|
||||
rewrites for AOF files bigger than 4 GB.
|
||||
* New maxmemory tests.
|
||||
|
||||
What's new in Redis 2.3.8 (2.4 Release Candidate 5)
|
||||
===================================================
|
||||
|
||||
Compared to Redis 2.3.7 (RC4) there are the following changes:
|
||||
|
||||
* [BUGFIX] HDEL: Abort deleting fields when hash is removed.
|
||||
* [BUGFIX] Fix adding bulk reply when getcwd fails.
|
||||
|
||||
WHAT'S NEW IN REDIS 2.4 compared to the 2.2 version?
|
||||
====================================================
|
||||
|
||||
9
runtest
Executable file
9
runtest
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
TCL=tclsh8.5
|
||||
which $TCL
|
||||
if [ "$?" != "0" ]
|
||||
then
|
||||
echo "You need '$TCL' in order to run the Redis test"
|
||||
exit 1
|
||||
fi
|
||||
$TCL tests/test_helper.tcl $*
|
||||
@@ -195,8 +195,8 @@ clean:
|
||||
dep:
|
||||
$(CC) -MM *.c -I ../deps/hiredis -I ../deps/linenoise
|
||||
|
||||
test: redis-server
|
||||
(cd ..; tclsh8.5 tests/test_helper.tcl --tags "${TAGS}")
|
||||
test: redis-server redis-check-aof
|
||||
@(cd ..; ./runtest)
|
||||
|
||||
bench:
|
||||
./redis-benchmark
|
||||
|
||||
@@ -526,12 +526,11 @@ void configGetCommand(redisClient *c) {
|
||||
if (stringmatch(pattern,"dir",0)) {
|
||||
char buf[1024];
|
||||
|
||||
addReplyBulkCString(c,"dir");
|
||||
if (getcwd(buf,sizeof(buf)) == NULL) {
|
||||
if (getcwd(buf,sizeof(buf)) == NULL)
|
||||
buf[0] = '\0';
|
||||
} else {
|
||||
addReplyBulkCString(c,buf);
|
||||
}
|
||||
|
||||
addReplyBulkCString(c,"dir");
|
||||
addReplyBulkCString(c,buf);
|
||||
matches++;
|
||||
}
|
||||
if (stringmatch(pattern,"dbfilename",0)) {
|
||||
|
||||
38
src/redis.c
38
src/redis.c
@@ -635,7 +635,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
|
||||
server.auto_aofrewrite_perc &&
|
||||
server.appendonly_current_size > server.auto_aofrewrite_min_size)
|
||||
{
|
||||
int base = server.auto_aofrewrite_base_size ?
|
||||
long long base = server.auto_aofrewrite_base_size ?
|
||||
server.auto_aofrewrite_base_size : 1;
|
||||
long long growth = (server.appendonly_current_size*100/base) - 100;
|
||||
if (growth >= server.auto_aofrewrite_perc) {
|
||||
@@ -1115,20 +1115,29 @@ int processCommand(redisClient *c) {
|
||||
/*================================== Shutdown =============================== */
|
||||
|
||||
int prepareForShutdown() {
|
||||
redisLog(REDIS_WARNING,"User requested shutdown, saving DB...");
|
||||
redisLog(REDIS_WARNING,"User requested shutdown...");
|
||||
/* Kill the saving child if there is a background saving in progress.
|
||||
We want to avoid race conditions, for instance our saving child may
|
||||
overwrite the synchronous saving did by SHUTDOWN. */
|
||||
if (server.bgsavechildpid != -1) {
|
||||
redisLog(REDIS_WARNING,"There is a live saving child. Killing it!");
|
||||
redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!");
|
||||
kill(server.bgsavechildpid,SIGKILL);
|
||||
rdbRemoveTempFile(server.bgsavechildpid);
|
||||
}
|
||||
if (server.appendonly) {
|
||||
/* Kill the AOF saving child as the AOF we already have may be longer
|
||||
* but contains the full dataset anyway. */
|
||||
if (server.bgrewritechildpid != -1) {
|
||||
redisLog(REDIS_WARNING,
|
||||
"There is a child rewriting the AOF. Killing it!");
|
||||
kill(server.bgrewritechildpid,SIGKILL);
|
||||
}
|
||||
/* Append only file: fsync() the AOF and exit */
|
||||
redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file.");
|
||||
aof_fsync(server.appendfd);
|
||||
if (server.vm_enabled) unlink(server.vm_swap_file);
|
||||
} else if (server.saveparamslen > 0) {
|
||||
}
|
||||
if (server.saveparamslen > 0) {
|
||||
redisLog(REDIS_NOTICE,"Saving the final RDB snapshot before exiting.");
|
||||
/* Snapshotting. Perform a SYNC SAVE and exit */
|
||||
if (rdbSave(server.dbfilename) != REDIS_OK) {
|
||||
/* Ooops.. error saving! The best we can do is to continue
|
||||
@@ -1136,14 +1145,23 @@ int prepareForShutdown() {
|
||||
* in the next cron() Redis will be notified that the background
|
||||
* saving aborted, handling special stuff like slaves pending for
|
||||
* synchronization... */
|
||||
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit");
|
||||
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit.");
|
||||
return REDIS_ERR;
|
||||
}
|
||||
} else {
|
||||
redisLog(REDIS_WARNING,"Not saving DB.");
|
||||
}
|
||||
if (server.daemonize) unlink(server.pidfile);
|
||||
redisLog(REDIS_WARNING,"Server exit now, bye bye...");
|
||||
if (server.vm_enabled) {
|
||||
redisLog(REDIS_NOTICE,"Removing the swap file.");
|
||||
unlink(server.vm_swap_file);
|
||||
}
|
||||
if (server.daemonize) {
|
||||
redisLog(REDIS_NOTICE,"Removing the pid file.");
|
||||
unlink(server.pidfile);
|
||||
}
|
||||
/* Close the listening sockets. Apparently this allows faster restarts. */
|
||||
if (server.ipfd != -1) close(server.ipfd);
|
||||
if (server.sofd != -1) close(server.sofd);
|
||||
|
||||
redisLog(REDIS_WARNING,"Redis is now ready to exit, bye bye...");
|
||||
return REDIS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -403,8 +403,11 @@ void hdelCommand(redisClient *c) {
|
||||
|
||||
for (j = 2; j < c->argc; j++) {
|
||||
if (hashTypeDelete(o,c->argv[j])) {
|
||||
if (hashTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
||||
deleted++;
|
||||
if (hashTypeLength(o) == 0) {
|
||||
dbDelete(c->db,c->argv[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (deleted) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define REDIS_VERSION "2.3.6"
|
||||
#define REDIS_VERSION "2.3.9"
|
||||
|
||||
@@ -5,7 +5,7 @@ set ::tests_failed {}
|
||||
|
||||
proc assert {condition} {
|
||||
if {![uplevel 1 expr $condition]} {
|
||||
error "assertion:Expected '$value' to be true"
|
||||
error "assertion:Expected condition '$condition' to be true"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ set ::all_tests {
|
||||
integration/aof
|
||||
unit/pubsub
|
||||
unit/slowlog
|
||||
unit/maxmemory
|
||||
}
|
||||
# Index to the next test to run in the ::all_tests list.
|
||||
set ::next_test 0
|
||||
|
||||
120
tests/unit/maxmemory.tcl
Normal file
120
tests/unit/maxmemory.tcl
Normal file
@@ -0,0 +1,120 @@
|
||||
start_server {tags {"maxmemory"}} {
|
||||
foreach policy {
|
||||
allkeys-random allkeys-lru volatile-lru volatile-random volatile-ttl
|
||||
} {
|
||||
test "maxmemory - is the memory limit honoured? (policy $policy)" {
|
||||
# make sure to start with a blank instance
|
||||
r flushall
|
||||
# Get the current memory limit and calculate a new limit.
|
||||
# We just add 100k to the current memory size so that it is
|
||||
# fast for us to reach that limit.
|
||||
set used [s used_memory]
|
||||
set limit [expr {$used+100*1024}]
|
||||
r config set maxmemory $limit
|
||||
r config set maxmemory-policy $policy
|
||||
# Now add keys until the limit is almost reached.
|
||||
set numkeys 0
|
||||
while 1 {
|
||||
r setex [randomKey] 10000 x
|
||||
incr numkeys
|
||||
if {[s used_memory]+4096 > $limit} {
|
||||
assert {$numkeys > 10}
|
||||
break
|
||||
}
|
||||
}
|
||||
# If we add the same number of keys already added again, we
|
||||
# should still be under the limit.
|
||||
for {set j 0} {$j < $numkeys} {incr j} {
|
||||
r setex [randomKey] 10000 x
|
||||
}
|
||||
assert {[s used_memory] < ($limit+4096)}
|
||||
}
|
||||
}
|
||||
|
||||
foreach policy {
|
||||
allkeys-random allkeys-lru volatile-lru volatile-random volatile-ttl
|
||||
} {
|
||||
test "maxmemory - only allkeys-* should remove non-volatile keys ($policy)" {
|
||||
# make sure to start with a blank instance
|
||||
r flushall
|
||||
# Get the current memory limit and calculate a new limit.
|
||||
# We just add 100k to the current memory size so that it is
|
||||
# fast for us to reach that limit.
|
||||
set used [s used_memory]
|
||||
set limit [expr {$used+100*1024}]
|
||||
r config set maxmemory $limit
|
||||
r config set maxmemory-policy $policy
|
||||
# Now add keys until the limit is almost reached.
|
||||
set numkeys 0
|
||||
while 1 {
|
||||
r set [randomKey] x
|
||||
incr numkeys
|
||||
if {[s used_memory]+4096 > $limit} {
|
||||
assert {$numkeys > 10}
|
||||
break
|
||||
}
|
||||
}
|
||||
# If we add the same number of keys already added again and
|
||||
# the policy is allkeys-* we should still be under the limit.
|
||||
# Otherwise we should see an error reported by Redis.
|
||||
set err 0
|
||||
for {set j 0} {$j < $numkeys} {incr j} {
|
||||
if {[catch {r set [randomKey] x} e]} {
|
||||
if {[string match {*used memory*} $e]} {
|
||||
set err 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if {[string match allkeys-* $policy]} {
|
||||
assert {[s used_memory] < ($limit+4096)}
|
||||
} else {
|
||||
assert {$err == 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach policy {
|
||||
volatile-lru volatile-random volatile-ttl
|
||||
} {
|
||||
test "maxmemory - policy $policy should only remove volatile keys." {
|
||||
# make sure to start with a blank instance
|
||||
r flushall
|
||||
# Get the current memory limit and calculate a new limit.
|
||||
# We just add 100k to the current memory size so that it is
|
||||
# fast for us to reach that limit.
|
||||
set used [s used_memory]
|
||||
set limit [expr {$used+100*1024}]
|
||||
r config set maxmemory $limit
|
||||
r config set maxmemory-policy $policy
|
||||
# Now add keys until the limit is almost reached.
|
||||
set numkeys 0
|
||||
while 1 {
|
||||
# Odd keys are volatile
|
||||
# Even keys are non volatile
|
||||
if {$numkeys % 2} {
|
||||
r setex "key:$numkeys" 10000 x
|
||||
} else {
|
||||
r set "key:$numkeys" x
|
||||
}
|
||||
if {[s used_memory]+4096 > $limit} {
|
||||
assert {$numkeys > 10}
|
||||
break
|
||||
}
|
||||
incr numkeys
|
||||
}
|
||||
# Now we add the same number of volatile keys already added.
|
||||
# We expect Redis to evict only volatile keys in order to make
|
||||
# space.
|
||||
set err 0
|
||||
for {set j 0} {$j < $numkeys} {incr j} {
|
||||
catch {r setex "foo:$j" 10000 x}
|
||||
}
|
||||
# We should still be under the limit.
|
||||
assert {[s used_memory] < ($limit+4096)}
|
||||
# However all our non volatile keys should be here.
|
||||
for {set j 0} {$j < $numkeys} {incr j 2} {
|
||||
assert {[r exists "key:$j"]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,6 +235,13 @@ start_server {tags {"hash"}} {
|
||||
r hgetall myhash
|
||||
} {b 2}
|
||||
|
||||
test {HDEL - hash becomes empty before deleting all specified fields} {
|
||||
r del myhash
|
||||
r hmset myhash a 1 b 2 c 3
|
||||
assert_equal 3 [r hdel myhash a b c d e]
|
||||
assert_equal 0 [r exists myhash]
|
||||
}
|
||||
|
||||
test {HEXISTS} {
|
||||
set rv {}
|
||||
set k [lindex [array names smallhash *] 0]
|
||||
|
||||
Reference in New Issue
Block a user