void rdb_load_triggle(rio *rdb) { //save event //db_num int int int int //db //scripts_num //key event lua_scripts //key event lua_scripts //....... int i=0; for(i=0;i<server.dbnum;i++){ int eventid=rioRead(rdb,&eventid,4); server.bridge_db.bridge_event[i]=eventid; // printf('read from dump file eventid:%d',eventid); } long j=0; for(i=0;i<server.dbnum;i++) { int dsize; rioRead(rdb,&dsize,4); // redisLog(REDIS_NOTICE,"read triggle dbsize, dbid:%d size:%d",i,dsize); for(j=0;j<dsize;j++) { struct bridge_db_triggle_t *tmptrg=zmalloc(sizeof(struct bridge_db_triggle_t)); robj* key=rdbLoadStringObject(rdb); rioRead(rdb,&tmptrg->event,4); rioRead(rdb,&tmptrg->dbid,4); int type; type=rdbLoadType(rdb); robj *mm=rdbLoadObject(type,rdb); tmptrg->lua_scripts=mm; // redisLog(REDIS_NOTICE,"redis one triggle row, key:%s event:%d db:%d script:%s",copy,tmptrg->event,tmptrg->dbid,tmptrg->lua_scripts->ptr); sds copy=sdsdup(key->ptr); dictAdd(server.bridge_db.triggle_scipts[i],copy,tmptrg); decrRefCount(key); } } }
robj *vmReadObjectFromSwap(off page, int type) { robj *o; if (server.vm_enabled) pthread_mutex_lock(&server.io_swapfile_mutex); if (fseeko(server.vm_fp,page*server.vm_page_size,SEEK_SET) == -1) { redisLog(REDIS_WARNING, "Unrecoverable VM problem in vmReadObjectFromSwap(): can't seek: %s", strerror(errno)); _exit(1); } o = rdbLoadObject(type,server.vm_fp); if (o == NULL) { redisLog(REDIS_WARNING, "Unrecoverable VM problem in vmReadObjectFromSwap(): can't load object from swap file: %s", strerror(errno)); _exit(1); } if (server.vm_enabled) pthread_mutex_unlock(&server.io_swapfile_mutex); return o; }
/* Check the specified RDB file. Return 0 if the RDB looks sane, otherwise * 1 is returned. */ int redis_check_rdb(char *rdbfilename) { uint64_t dbid; int type, rdbver; char buf[1024]; long long expiretime, now = mstime(); FILE *fp; static rio rdb; /* Pointed by global struct riostate. */ if ((fp = fopen(rdbfilename,"r")) == NULL) return 1; rioInitWithFile(&rdb,fp); rdbstate.rio = &rdb; rdb.update_cksum = rdbLoadProgressCallback; if (rioRead(&rdb,buf,9) == 0) goto eoferr; buf[9] = '\0'; if (memcmp(buf,"REDIS",5) != 0) { rdbCheckError("Wrong signature trying to load DB from file"); return 1; } rdbver = atoi(buf+5); if (rdbver < 1 || rdbver > RDB_VERSION) { rdbCheckError("Can't handle RDB format version %d",rdbver); return 1; } startLoading(fp); while(1) { robj *key, *val; expiretime = -1; /* Read type. */ rdbstate.doing = RDB_CHECK_DOING_READ_TYPE; if ((type = rdbLoadType(&rdb)) == -1) goto eoferr; /* Handle special types. */ if (type == RDB_OPCODE_EXPIRETIME) { rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE; /* EXPIRETIME: load an expire associated with the next key * to load. Note that after loading an expire we need to * load the actual type, and continue. */ if ((expiretime = rdbLoadTime(&rdb)) == -1) goto eoferr; /* We read the time so we need to read the object type again. */ rdbstate.doing = RDB_CHECK_DOING_READ_TYPE; if ((type = rdbLoadType(&rdb)) == -1) goto eoferr; /* the EXPIRETIME opcode specifies time in seconds, so convert * into milliseconds. */ expiretime *= 1000; } else if (type == RDB_OPCODE_EXPIRETIME_MS) { /* EXPIRETIME_MS: milliseconds precision expire times introduced * with RDB v3. Like EXPIRETIME but no with more precision. */ rdbstate.doing = RDB_CHECK_DOING_READ_EXPIRE; if ((expiretime = rdbLoadMillisecondTime(&rdb)) == -1) goto eoferr; /* We read the time so we need to read the object type again. */ rdbstate.doing = RDB_CHECK_DOING_READ_TYPE; if ((type = rdbLoadType(&rdb)) == -1) goto eoferr; } else if (type == RDB_OPCODE_EOF) { /* EOF: End of file, exit the main loop. */ break; } else if (type == RDB_OPCODE_SELECTDB) { /* SELECTDB: Select the specified database. */ rdbstate.doing = RDB_CHECK_DOING_READ_LEN; if ((dbid = rdbLoadLen(&rdb,NULL)) == RDB_LENERR) goto eoferr; rdbCheckInfo("Selecting DB ID %d", dbid); continue; /* Read type again. */ } else if (type == RDB_OPCODE_RESIZEDB) { /* RESIZEDB: Hint about the size of the keys in the currently * selected data base, in order to avoid useless rehashing. */ uint64_t db_size, expires_size; rdbstate.doing = RDB_CHECK_DOING_READ_LEN; if ((db_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR) goto eoferr; if ((expires_size = rdbLoadLen(&rdb,NULL)) == RDB_LENERR) goto eoferr; continue; /* Read type again. */ } else if (type == RDB_OPCODE_AUX) { /* AUX: generic string-string fields. Use to add state to RDB * which is backward compatible. Implementations of RDB loading * are requierd to skip AUX fields they don't understand. * * An AUX field is composed of two strings: key and value. */ robj *auxkey, *auxval; rdbstate.doing = RDB_CHECK_DOING_READ_AUX; if ((auxkey = rdbLoadStringObject(&rdb)) == NULL) goto eoferr; if ((auxval = rdbLoadStringObject(&rdb)) == NULL) goto eoferr; rdbCheckInfo("AUX FIELD %s = '%s'", (char*)auxkey->ptr, (char*)auxval->ptr); decrRefCount(auxkey); decrRefCount(auxval); continue; /* Read type again. */ } else { if (!rdbIsObjectType(type)) { rdbCheckError("Invalid object type: %d", type); return 1; } rdbstate.key_type = type; } /* Read key */ rdbstate.doing = RDB_CHECK_DOING_READ_KEY; if ((key = rdbLoadStringObject(&rdb)) == NULL) goto eoferr; rdbstate.key = key; rdbstate.keys++; /* Read value */ rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE; if ((val = rdbLoadObject(type,&rdb)) == NULL) goto eoferr; /* Check if the key already expired. This function is used when loading * an RDB file from disk, either at startup, or when an RDB was * received from the master. In the latter case, the master is * responsible for key expiry. If we would expire keys here, the * snapshot taken by the master may not be reflected on the slave. */ if (server.masterhost == NULL && expiretime != -1 && expiretime < now) rdbstate.already_expired++; if (expiretime != -1) rdbstate.expires++; rdbstate.key = NULL; decrRefCount(key); decrRefCount(val); rdbstate.key_type = -1; } /* Verify the checksum if RDB version is >= 5 */ if (rdbver >= 5 && server.rdb_checksum) { uint64_t cksum, expected = rdb.cksum; rdbstate.doing = RDB_CHECK_DOING_CHECK_SUM; if (rioRead(&rdb,&cksum,8) == 0) goto eoferr; memrev64ifbe(&cksum); if (cksum == 0) { rdbCheckInfo("RDB file was saved with checksum disabled: no check performed."); } else if (cksum != expected) { rdbCheckError("RDB CRC error"); } else { rdbCheckInfo("Checksum OK"); } } fclose(fp); return 0; eoferr: /* unexpected end of file is handled here with a fatal exit */ if (rdbstate.error_set) { rdbCheckError(rdbstate.error); } else { rdbCheckError("Unexpected EOF reading RDB file"); } return 1; }
/* * * slotsrestore key ttl val [key ttl val ...] * */ void slotsrestoreCommand(redisClient *c) { if (c->argc < 4 || (c->argc - 1) % 3 != 0) { addReplyErrorFormat(c, "wrong number of arguments for 'slotsrestore' command"); return; } int n = (c->argc - 1) / 3; long long *ttls = zmalloc(sizeof(long long) * n); robj **vals = zmalloc(sizeof(robj *) * n); for (int i = 0; i < n; i ++) { vals[i] = NULL; } for (int i = 0; i < n; i ++) { robj *key = c->argv[i * 3 + 1]; robj *ttl = c->argv[i * 3 + 2]; robj *val = c->argv[i * 3 + 3]; if (lookupKeyWrite(c->db, key) != NULL) { redisLog(REDIS_WARNING, "slotsrestore: slot = %d, key = '%s' already exists", slots_num(key->ptr, NULL), (char *)key->ptr); } if (getLongLongFromObjectOrReply(c, ttl, &ttls[i], NULL) != REDIS_OK) { goto cleanup; } else if (ttls[i] < 0) { addReplyError(c, "invalid ttl value, must be >= 0"); goto cleanup; } rio payload; int type; if (verifyDumpPayload(val->ptr, sdslen(val->ptr)) != REDIS_OK) { addReplyError(c, "dump payload version or checksum are wrong"); goto cleanup; } rioInitWithBuffer(&payload, val->ptr); if (((type = rdbLoadObjectType(&payload)) == -1) || ((vals[i] = rdbLoadObject(type, &payload)) == NULL)) { addReplyError(c, "bad data format"); goto cleanup; } } for (int i = 0; i < n; i ++) { robj *key = c->argv[i * 3 + 1]; long long ttl = ttls[i]; robj *val = vals[i]; dbDelete(c->db, key); dbAdd(c->db, key, val); incrRefCount(val); if (ttl) { setExpire(c->db, key, mstime() + ttl); } signalModifiedKey(c->db, key); server.dirty ++; } addReply(c, shared.ok); cleanup: for (int i = 0; i < n; i ++) { if (vals[i] != NULL) { decrRefCount(vals[i]); } } zfree(vals); zfree(ttls); }