From: Jay Freeman (saurik) Date: Sun, 23 Dec 2012 08:00:44 +0000 (+0000) Subject: Further integrate MDB key archival into config. X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/b0aa9bc8cdd36925b2d8e5d3a9c1e1476eaa6fc1 Further integrate MDB key archival into config. Like other parts of the server, key archival is something you should be able to activate and deactivate at runtime. --- diff --git a/src/config.c b/src/config.c index c4e45c8b..4974d5ee 100644 --- a/src/config.c +++ b/src/config.c @@ -511,6 +511,19 @@ 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,"keyarchive")) { + int enable = yesnotoi(o->ptr); + + if (enable == -1) goto badfmt; + if (enable == 0 && server.mdb_state != REDIS_MDB_OFF) { + stopKeyArchive(); + } else if (enable && server.mdb_state == REDIS_MDB_OFF) { + if (startKeyArchive() != 0) { + addReplyError(c, + "Unable to turn on MDB. Check server logs."); + return; + } + } } else if (!strcasecmp(c->argv[2]->ptr,"appendfsync")) { if (!strcasecmp(o->ptr,"no")) { server.aof_fsync = AOF_FSYNC_NO; diff --git a/src/migrate.c b/src/migrate.c index a00f0e63..3886f62c 100644 --- a/src/migrate.c +++ b/src/migrate.c @@ -252,41 +252,54 @@ socket_rd_err: return; } -void mdb(void) { - int ret; +void stopKeyArchive(void) { + redisAssert(server.mdb_state == REDIS_MDB_ON); + redisAssert(env != NULL); - if (env != NULL) - return; + mdb_dbi_close(env, dbi); + mdb_env_close(env); + env = NULL; + + server.mdb_state = REDIS_MDB_OFF; +} + +int startKeyArchive(void) { + redisAssert(server.mdb_state == REDIS_MDB_OFF); + redisAssert(env == NULL); + + int ret; ret = mdb_env_create(&env); - redisAssert(ret == 0); + if (ret != 0) return ret; ret = mdb_env_set_mapsize(env, server.mdb_mapsize); - redisAssert(ret == 0); + if (ret != 0) return ret; ret = mdb_env_set_maxdbs(env, 1); - redisAssert(ret == 0); + if (ret != 0) return ret; mkdir(server.mdb_environment, 0644); ret = mdb_env_open(env, server.mdb_environment, MDB_FIXEDMAP | MDB_NOSYNC, 0664); - redisAssert(ret == 0); + if (ret != 0) return ret; MDB_txn *txn; ret = mdb_txn_begin(env, NULL, 0, &txn); - redisAssert(ret == 0); + if (ret != 0) return ret; ret = mdb_open(txn, NULL, 0, &dbi); - redisAssert(ret == 0); + if (ret != 0) return ret; mdb_txn_commit(txn); + + server.mdb_state = REDIS_MDB_ON; + return 0; } int archive(redisDb *db, robj *key) { if (server.mdb_state == REDIS_MDB_OFF) return 1; - - mdb(); + redisAssert(env != NULL); MDB_val kval; kval.mv_data = key->ptr; @@ -336,8 +349,6 @@ robj *recover(redisDb *db, robj *key) { int ret; - mdb(); - MDB_val kval; kval.mv_data = key->ptr; kval.mv_size = sdslen((sds)key->ptr); diff --git a/src/redis.c b/src/redis.c index b1c34ebb..eed21263 100644 --- a/src/redis.c +++ b/src/redis.c @@ -49,6 +49,7 @@ #include #include #include +#include /* Our shared "common" objects */ @@ -1347,6 +1348,15 @@ void initServer() { } } + if (server.aof_state == REDIS_MDB_ON) { + int retval = startKeyArchive(); + if (retval != 0) { + redisLog(REDIS_WARNING, "Can't open the key-archive environment: %s", + mdb_strerror(retval)); + exit(1); + } + } + /* 32 bit instances are limited to 4GB of address space, so if there is * no explicit limit in the user provided configuration we set a limit * at 3 GB using maxmemory with 'noeviction' policy'. This avoids diff --git a/src/redis.h b/src/redis.h index 6fe6cfc6..dc4e325a 100644 --- a/src/redis.h +++ b/src/redis.h @@ -1034,6 +1034,8 @@ void signalFlushedDb(int dbid); unsigned int GetKeysInSlot(unsigned int hashslot, robj **keys, unsigned int count); /* external database archival */ +void stopKeyArchive(void); +int startKeyArchive(void); robj *recover(redisDb *db, robj *key); int archive(redisDb *db, robj *key);