Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

save operation based on db #2856

Closed
hiteric opened this issue Nov 6, 2015 · 3 comments
Closed

save operation based on db #2856

hiteric opened this issue Nov 6, 2015 · 3 comments

Comments

@hiteric
Copy link

hiteric commented Nov 6, 2015

Current implementation, each save command will save all of the data of all of dbs, but in many cases, we only want to save data in one db or some of dbs but not all. I wrote an implementation, specify each db and specify rdb file when save. This is not what the new features, but I think, this will be more flexible and convenient during save.

For example, several modules(each module is a process may or not be) shared the same redis, each module with only one db, but each module just want to save their own db, or only not all of the modules need save. If their are too many dbs, and we just hope save one of these dbs, according current implementation of the code, every time when save,we must all traverse through all dbs,the efficiency is not high. So in order to meet the various needs, we can add a command to implementate this.

@hiteric
Copy link
Author

hiteric commented Nov 6, 2015

The following code is part of rdb.c
void savedbCommand(redisClient *c) {
......
if (rdbSave2(id, c->argv[2]->ptr) == REDIS_OK) {
......
}

int rdbSave2(int id, char *filename) {
...
if (rdbSaveRio2(id, &rdb,&error) == REDIS_ERR) {
...
}

int rdbSaveRio2(int id, rio *rdb, int *error) {
dictIterator *di = NULL;
dictEntry *de;
char magic[10];
int j;
long long now = mstime();
uint64_t cksum;

if (server.rdb_checksum)
    rdb->update_cksum = rioGenericUpdateChecksum;
snprintf(magic,sizeof(magic),"REDIS%04d",REDIS_RDB_VERSION);
if (rdbWriteRaw(rdb,magic,9) == -1) goto werr;


    redisDb *db = &server.db[id];
    dict *d = db->dict;
    if(dictSize(d) == 0) {
        return REDIS_OK;
    }
    di = dictGetSafeIterator(d);
    if (!di) return REDIS_ERR;

    /* Write the SELECT DB opcode */
    if (rdbSaveType(rdb,REDIS_RDB_OPCODE_SELECTDB) == -1) goto werr;
    if (rdbSaveLen(rdb,j) == -1) goto werr;

    /* Iterate this DB writing every entry */
    while((de = dictNext(di)) != NULL) {
        sds keystr = dictGetKey(de);
        robj key, *o = dictGetVal(de);
        long long expire;

        initStaticStringObject(key,keystr);
        expire = getExpire(db,&key);
        if (rdbSaveKeyValuePair(rdb,&key,o,expire,now) == -1) goto werr;
    }
    dictReleaseIterator(di);

di = NULL; /* So that we don't release it again on error. */

/* EOF opcode */
if (rdbSaveType(rdb,REDIS_RDB_OPCODE_EOF) == -1) goto werr;

/* CRC64 checksum. It will be zero if checksum computation is disabled, the
 * loading code skips the check in this case. */
cksum = rdb->cksum;
memrev64ifbe(&cksum);
if (rioWrite(rdb,&cksum,8) == 0) goto werr;
return REDIS_OK;

werr:
if (error) *error = errno;
if (di) dictReleaseIterator(di);
return REDIS_ERR;
}

@hiteric
Copy link
Author

hiteric commented Nov 6, 2015

redis version is 3.0.3

The following is the result
redis /tmp/redis.sock[3]> savedb 3 dump3.rdb
OK

@antirez
Copy link
Contributor

antirez commented Nov 6, 2015

Hello, we had no plan for such a feature since Redis DBs are a namespacing facility within the same application with the same durability requirements. If you want to split data with different logical requirements it's suggested to run multiple Redis servers. This way you use multiple cores, and can configure each instance on purpose. Thanks. Closing.

@antirez antirez closed this as completed Nov 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants