Compare commits

...
16 Commits
Author SHA1 Message Date
antirez 1c14507366 version bumped to 2.0.4, release note for this version added 2010-11-06 09:58:21 +01:00
antirez 19c8d5bf22 commit d8a717fb backported from master to 2.2 (do not save DB if no save interval configured with RDB, by Robey Pointer). 2010-11-06 09:55:38 +01:00
antirez fac62d47e7 Merge remote branch 'pietern/2.0.0-hmget-fix' into 2.0.0 2010-10-27 16:37:34 +02:00
Pieter Noordhuis f5936fa1c2 Return error to client on wrong type for HMGET (backport of e584d82f) 2010-10-26 12:35:09 +02:00
antirez ff29ca1c46 todo for 2.04 updated 2010-10-24 12:09:18 +02:00
antirez b766149d5f new release notes for 2.0.3 2010-10-15 13:04:38 +02:00
antirez 4ac0c844ed version bumped to 2.0.3 2010-10-15 13:01:29 +02:00
antirez 87c96a6ed8 Merge remote branch 'pietern/2.0.0-bpopaof' into 2.0.0 2010-10-15 11:09:03 +02:00
antirez a58426fb15 maxmemory fixed, we now try to release memory just before we check for the memory limit. Before fixing there was code between the attempt to free memory and the check for memory limits, and this code could result into allocations going again after the memory limit. 2010-10-11 13:20:17 +02:00
Pieter Noordhuis 2385ef4dfe Never block for keys when the AOF is being replayed
Replaying an AOF with blocking pop commands would lead to a state where
the fake AOF client would register itself (multiple times) as blocking
for a series of keys. Subsequent pushes against these keys could result
in a crash. Reported by and traced with the help from Jamie Turner.
2010-10-08 00:39:02 +02:00
antirez d7554adade release notes modified for 2.0.2 again 2010-09-22 11:37:16 +02:00
antirez 70a08f00d7 release notes updated 2010-09-22 11:33:06 +02:00
antirez 6ebd11cfa8 Version is now 2.0.2 2010-09-22 11:20:21 +02:00
antirez 42daeb4b48 Merge branch '2.0.0' of github.com:antirez/redis into 2.0.0 2010-09-22 11:19:17 +02:00
antirez 3306aefc87 Changed the dict resize policy when BGSAVEs are in progress to a more
dynamic algorithm where an overbooking up to 5 times is tolerated, but
after this threshold is reached the resizing is performed even if there
are child processes running.
2010-09-22 11:17:06 +02:00
antirez c8baa20507 Use a pointer for dict resize policy instead of a global
This makes sure only the main hash table cannot be resized when a BGSAVE
is in progress. In particular, set commands that generate a set (S*STORE
commands), will fall back to O(N) access instead of O(1) access because
the resulting sets have a huge number of collisions without resizing.
2010-09-15 15:01:37 +02:00
4 changed files with 108 additions and 12 deletions
+55
View File
@@ -1,3 +1,58 @@
Welcome to Redis 2.0.4
This release fixes two non critical bugs:
- HMGET used to crash when called against a key that was not holding
an hash. Fixed by Pieter Noordhuis.
- Redis will now not try to save the DB if no save points for RDB are
configured, when used as a non persistent cache. Thanks to Robey
Pointer from Twitter for providing this patch.
Waiting 2.2 ...
Salvatore
--------------------------------------------------------------------------------
Welcome to Redis 2.0.3
This release fixes two important bugs:
- The maxmemory directive was broken in Redis <= 2.0.2, since from time to
time it replayed with an error about memory limit reached even when
it was possible to expire some volatile key to make room for new data.
The new behaviour is the correct one of always allowing write operations
to succeed as long as there are other volatile keys to remove.
- An AOF bug related to blocking POP could crash Redis on AOF reload.
This is now fixed thanks to Pieter Noordhuis and a kind user that
helped us on IRC.
Enjoy!
Salvatore
--------------------------------------------------------------------------------
Welcome to Redis 2.0.2
This is a bugfix release, with the followign changes:
- Fixed a bug that may slow down significantly (from a few milliseconds
to many seconds) server side intersections when a background write is
in progress. This was due to the hash table resize policy, prevented when
there was a saving child. Now it's prevented only up to 5 times
overbooking, so we try hard to prevent a lot of copy on write, but
avoiding to trigger pathological hash table performances of O(N) instead
of O(1).
- Fixed expired keys counter in INFO output. It was not counting keys
force-expired due to max-memory limit reached.
Ciao,
Salvatore
--------------------------------------------------------------------------------
Welcome to Redis 2.0.1
This is a bugfix release, with the following changes:
+20 -6
View File
@@ -49,8 +49,13 @@
/* Using dictEnableResize() / dictDisableResize() we make possible to
* enable/disable resizing of the hash table as needed. This is very important
* for Redis, as we use copy-on-write and don't want to move too much memory
* around when there is a child performing saving operations. */
* around when there is a child performing saving operations.
*
* Note that even when dict_can_resize is set to 0, not all resizes are
* prevented: an hash table is still allowed to grow if the ratio between
* the number of elements and the buckets > dict_force_resize_ratio. */
static int dict_can_resize = 1;
static unsigned int dict_force_resize_ratio = 5;
/* ---------------------------- Utility funcitons --------------------------- */
@@ -522,14 +527,23 @@ dictEntry *dictGetRandomKey(dict *d)
/* Expand the hash table if needed */
static int _dictExpandIfNeeded(dict *d)
{
/* If the hash table is empty expand it to the intial size,
* if the table is "full" dobule its size. */
/* Incremental rehashing already in progress. Return. */
if (dictIsRehashing(d)) return DICT_OK;
if (d->ht[0].size == 0)
return dictExpand(d, DICT_HT_INITIAL_SIZE);
if (d->ht[0].used >= d->ht[0].size && dict_can_resize)
/* If the hash table is empty expand it to the intial size. */
if (d->ht[0].size == 0) return dictExpand(d, DICT_HT_INITIAL_SIZE);
/* If we reached the 1:1 ratio, and we are allowed to resize the hash
* table (global setting) or we should avoid it but the ratio between
* elements/buckets is over the "safe" threshold, we resize doubling
* the number of buckets. */
if (d->ht[0].used >= d->ht[0].size &&
(dict_can_resize ||
d->ht[0].used/d->ht[0].size > dict_force_resize_ratio))
{
return dictExpand(d, ((d->ht[0].size > d->ht[0].used) ?
d->ht[0].size : d->ht[0].used)*2);
}
return DICT_OK;
}
+28 -6
View File
@@ -27,7 +27,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#define REDIS_VERSION "2.0.1"
#define REDIS_VERSION "2.0.4"
#include "fmacros.h"
#include "config.h"
@@ -2296,9 +2296,6 @@ static void call(redisClient *c, struct redisCommand *cmd) {
static int processCommand(redisClient *c) {
struct redisCommand *cmd;
/* Free some memory if needed (maxmemory setting) */
if (server.maxmemory) freeMemoryIfNeeded();
/* Handle the multi bulk command type. This is an alternative protocol
* supported by Redis in order to receive commands that are composed of
* multiple binary-safe "bulk" arguments. The latency of processing is
@@ -2430,7 +2427,12 @@ static int processCommand(redisClient *c) {
return 1;
}
/* Handle the maxmemory directive */
/* Handle the maxmemory directive.
*
* First we try to free some memory if possible (if there are volatile
* keys in the dataset). If there are not the only thing we can do
* is returning an error. */
if (server.maxmemory) freeMemoryIfNeeded();
if (server.maxmemory && (cmd->flags & REDIS_CMD_DENYOOM) &&
zmalloc_used_memory() > server.maxmemory)
{
@@ -4219,7 +4221,7 @@ static int prepareForShutdown() {
/* Append only file: fsync() the AOF and exit */
fsync(server.appendfd);
if (server.vm_enabled) unlink(server.vm_swap_file);
} else {
} else if (server.saveparamslen > 0) {
/* Snapshotting. Perform a SYNC SAVE and exit */
if (rdbSave(server.dbfilename) == REDIS_OK) {
if (server.daemonize)
@@ -4234,6 +4236,8 @@ static int prepareForShutdown() {
redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit");
return REDIS_ERR;
}
} else {
redisLog(REDIS_WARNING,"Not saving DB.");
}
redisLog(REDIS_WARNING,"Server exit now, bye bye...");
return REDIS_OK;
@@ -6705,6 +6709,7 @@ static void hmgetCommand(redisClient *c) {
o = lookupKeyRead(c->db,c->argv[1]);
if (o != NULL && o->type != REDIS_HASH) {
addReply(c,shared.wrongtypeerr);
return;
}
/* Note the check for o != NULL happens inside the loop. This is
@@ -7634,6 +7639,22 @@ static void blockForKeys(redisClient *c, robj **keys, int numkeys, time_t timeou
list *l;
int j;
/* Never block for keys when the AOF is being replayed.
*
* When a BPOP is issued against an expiring list, the list is expired
* by means of the delete-on-write semantic, which causes the BPOP
* command to be written to the AOF. Then, the BPOP ends up in a blocking
* state and waits for a PUSH on any given key from another client.
*
* On replay, the expiring list will also be expired (if it isn't already),
* and the fake AOF client will block for a push. When multiple BPOPs
* (issued by multiple clients) are written to the AOF, this can cause the
* same blocking code to be executed against the single fake AOF client,
* which in turn can place the client in the list(s) of blocking clients
* *multiple times*. This state should be prevented, so simply skip
* blocking for the fake AOF client. */
if (c->fd < 0) return;
c->blockingkeys = zmalloc(sizeof(robj*)*numkeys);
c->blockingkeysnum = numkeys;
c->blockingto = timeout;
@@ -8227,6 +8248,7 @@ static void freeMemoryIfNeeded(void) {
}
}
deleteKey(server.db+j,minkey);
server.stat_expiredkeys++;
}
}
if (!freed) return; /* nothing to free... */
+5
View File
@@ -140,6 +140,11 @@ start_server {tags {"hash"}} {
set _ $rv
} {{{} {}} {{} {}} {{} {}}}
test {HMGET against wrong type} {
r set wrongtype somevalue
assert_error "*wrong*" {r hmget wrongtype field1 field2}
}
test {HMGET - small hash} {
set keys {}
set vals {}