redis 启动 报错 The RDB file contains module data I can't load: no matching module '

1,147 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

问题 redis启动报错

The RDB file contains module data I can't load: no matching module 'MBbloom-- '

原因.rdb快照异常

可参考 这里. RDB就像是一个redis快照

src/rdb.c  redis抽象出一个rio层,负责处理IO操作的,通过rio进行rdb文件恢复redis(快照保存的逆操作)。 rdbload

1 /* Like rdbLoadRio() but takes a filename instead of a rio stream. The
 2  * filename is open for reading and a rio stream object created in order
 3  * to do the actual loading. Moreover the ETA displayed in the INFO
 4  * output is initialized and finalized.
 5  *
 6  * If you pass an 'rsi' structure initialied with RDB_SAVE_OPTION_INIT, the
 7  * loading code will fiil the information fields in the structure. */
 8 int rdbLoad(char *filename, rdbSaveInfo *rsi) {
 9     FILE *fp;
10     rio rdb;
11     int retval;
12 
13     if ((fp = fopen(filename,"r")) == NULL) return C_ERR;
14     startLoading(fp);
15     rioInitWithFile(&rdb,fp);
16     retval = rdbLoadRio(&rdb,rsi,0);
17     fclose(fp);
18     stopLoading();
19     return retval;
20 }

rdbLoadRio

1 /* Load an RDB file from the rio stream 'rdb'. On success C_OK is returned,
  2  * otherwise C_ERR is returned and 'errno' is set accordingly. */
  3 int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
  4     uint64_t dbid;
  5     int type, rdbver;
  6     redisDb *db = server.db+0;
  7     char buf[1024];
  8 
  9     rdb->update_cksum = rdbLoadProgressCallback;
 10     rdb->max_processing_chunk = server.loading_process_events_interval_bytes;
 11     if (rioRead(rdb,buf,9) == 0) goto eoferr;
 12     buf[9] = '\0';
 13     if (memcmp(buf,"REDIS",5) != 0) {
 14         serverLog(LL_WARNING,"Wrong signature trying to load DB from file");
 15         errno = EINVAL;
 16         return C_ERR;
 17     }
 18     rdbver = atoi(buf+5);
 19     if (rdbver < 1 || rdbver > RDB_VERSION) {
 20         serverLog(LL_WARNING,"Can't handle RDB format version %d",rdbver);
 21         errno = EINVAL;
 22         return C_ERR;
 23     }
 24 
 25     /* Key-specific attributes, set by opcodes before the key type. */
 26     long long lru_idle = -1, lfu_freq = -1, expiretime = -1, now = mstime();
 27     long long lru_clock = LRU_CLOCK();
 28     
 29     while(1) {
 30         robj *key, *val;
 31 
 32         /* Read type. */
 33         if ((type = rdbLoadType(rdb)) == -1) goto eoferr;
 34 
 35         /* Handle special types. */
 36         if (type == RDB_OPCODE_EXPIRETIME) {
 37             /* EXPIRETIME: load an expire associated with the next key
 38              * to load. Note that after loading an expire we need to
 39              * load the actual type, and continue. */
 40             expiretime = rdbLoadTime(rdb);
 41             expiretime *= 1000;
 42             continue; /* Read next opcode. */
 43         } else if (type == RDB_OPCODE_EXPIRETIME_MS) {
 44             /* EXPIRETIME_MS: milliseconds precision expire times introduced
 45              * with RDB v3. Like EXPIRETIME but no with more precision. */
 46             expiretime = rdbLoadMillisecondTime(rdb,rdbver);
 47             continue; /* Read next opcode. */
 48         } else if (type == RDB_OPCODE_FREQ) {
 49             /* FREQ: LFU frequency. */
 50             uint8_t byte;
 51             if (rioRead(rdb,&byte,1) == 0) goto eoferr;
 52             lfu_freq = byte;
 53             continue; /* Read next opcode. */
 54         } else if (type == RDB_OPCODE_IDLE) {
 55             /* IDLE: LRU idle time. */
 56             uint64_t qword;
 57             if ((qword = rdbLoadLen(rdb,NULL)) == RDB_LENERR) goto eoferr;
 58             lru_idle = qword;
 59             continue; /* Read next opcode. */
 60         } else if (type == RDB_OPCODE_EOF) {
 61             /* EOF: End of file, exit the main loop. */
 62             break;
 63         } else if (type == RDB_OPCODE_SELECTDB) {
 64             /* SELECTDB: Select the specified database. */
 65             if ((dbid = rdbLoadLen(rdb,NULL)) == RDB_LENERR) goto eoferr;
 66             if (dbid >= (unsigned)server.dbnum) {
 67                 serverLog(LL_WARNING,
 68                     "FATAL: Data file was created with a Redis "
 69                     "server configured to handle more than %d "
 70                     "databases. Exiting\n", server.dbnum);
 71                 exit(1);
 72             }
 73             db = server.db+dbid;
 74             continue; /* Read next opcode. */
 75         } else if (type == RDB_OPCODE_RESIZEDB) {
 76             /* RESIZEDB: Hint about the size of the keys in the currently
 77              * selected data base, in order to avoid useless rehashing. */
 78             uint64_t db_size, expires_size;
 79             if ((db_size = rdbLoadLen(rdb,NULL)) == RDB_LENERR)
 80                 goto eoferr;
 81             if ((expires_size = rdbLoadLen(rdb,NULL)) == RDB_LENERR)
 82                 goto eoferr;
 83             dictExpand(db->dict,db_size);
 84             dictExpand(db->expires,expires_size);
 85             continue; /* Read next opcode. */
 86         } else if (type == RDB_OPCODE_AUX) {
 87             /* AUX: generic string-string fields. Use to add state to RDB
 88              * which is backward compatible. Implementations of RDB loading
 89              * are requierd to skip AUX fields they don't understand.
 90              *
 91              * An AUX field is composed of two strings: key and value. */
 92             robj *auxkey, *auxval;
 93             if ((auxkey = rdbLoadStringObject(rdb)) == NULL) goto eoferr;
 94             if ((auxval = rdbLoadStringObject(rdb)) == NULL) goto eoferr;
 95 
 96             if (((char*)auxkey->ptr)[0] == '%') {
 97                 /* All the fields with a name staring with '%' are considered
 98                  * information fields and are logged at startup with a log
 99                  * level of NOTICE. */
100                 serverLog(LL_NOTICE,"RDB '%s': %s",
101                     (char*)auxkey->ptr,
102                     (char*)auxval->ptr);
103             } else if (!strcasecmp(auxkey->ptr,"repl-stream-db")) {
104                 if (rsi) rsi->repl_stream_db = atoi(auxval->ptr);
105             } else if (!strcasecmp(auxkey->ptr,"repl-id")) {
106                 if (rsi && sdslen(auxval->ptr) == CONFIG_RUN_ID_SIZE) {
107                     memcpy(rsi->repl_id,auxval->ptr,CONFIG_RUN_ID_SIZE+1);
108                     rsi->repl_id_is_set = 1;
109                 }
110             } else if (!strcasecmp(auxkey->ptr,"repl-offset")) {
111                 if (rsi) rsi->repl_offset = strtoll(auxval->ptr,NULL,10);
112             } else if (!strcasecmp(auxkey->ptr,"lua")) {
113                 /* Load the script back in memory. */
114                 if (luaCreateFunction(NULL,server.lua,auxval) == NULL) {
115                     rdbExitReportCorruptRDB(
116                         "Can't load Lua script from RDB file! "
117                         "BODY: %s", auxval->ptr);
118                 }
119             } else {
120                 /* We ignore fields we don't understand, as by AUX field
121                  * contract. */
122                 serverLog(LL_DEBUG,"Unrecognized RDB AUX field: '%s'",
123                     (char*)auxkey->ptr);
124             }
125 
126             decrRefCount(auxkey);
127             decrRefCount(auxval);
128             continue; /* Read type again. */
129         } else if (type == RDB_OPCODE_MODULE_AUX) {
130             /* This is just for compatibility with the future: we have plans
131              * to add the ability for modules to store anything in the RDB
132              * file, like data that is not related to the Redis key space.
133              * Such data will potentially be stored both before and after the
134              * RDB keys-values section. For this reason since RDB version 9,
135              * we have the ability to read a MODULE_AUX opcode followed by an
136              * identifier of the module, and a serialized value in "MODULE V2"
137              * format. */
138             uint64_t moduleid = rdbLoadLen(rdb,NULL);
139             moduleType *mt = moduleTypeLookupModuleByID(moduleid);
140             char name[10];
141             moduleTypeNameByID(name,moduleid);
142 
143             if (!rdbCheckMode && mt == NULL) {
144                 /* Unknown module. */
145                 serverLog(LL_WARNING,"The RDB file contains AUX module data I can't load: no matching module '%s'", name);
146                 exit(1);
147             } else if (!rdbCheckMode && mt != NULL) {
148                 /* This version of Redis actually does not know what to do
149                  * with modules AUX data... */
150                 serverLog(LL_WARNING,"The RDB file contains AUX module data I can't load for the module '%s'. Probably you want to use a newer version of Redis which implements aux data callbacks", name);
151                 exit(1);
152             } else {
153                 /* RDB check mode. */
154                 robj *aux = rdbLoadCheckModuleValue(rdb,name);
155                 decrRefCount(aux);
156             }
157         }
158 
159         /* Read key */
160         if ((key = rdbLoadStringObject(rdb)) == NULL) goto eoferr;
161         /* Read value */
162         if ((val = rdbLoadObject(type,rdb)) == NULL) goto eoferr;
163         /* Check if the key already expired. This function is used when loading
164          * an RDB file from disk, either at startup, or when an RDB was
165          * received from the master. In the latter case, the master is
166          * responsible for key expiry. If we would expire keys here, the
167          * snapshot taken by the master may not be reflected on the slave. */
168         if (server.masterhost == NULL && !loading_aof && expiretime != -1 && expiretime < now) {
169             decrRefCount(key);
170             decrRefCount(val);
171         } else {
172             /* Add the new object in the hash table */
173             dbAdd(db,key,val);
174 
175             /* Set the expire time if needed */
176             if (expiretime != -1) setExpire(NULL,db,key,expiretime);
177             
178             /* Set usage information (for eviction). */
179             objectSetLRUOrLFU(val,lfu_freq,lru_idle,lru_clock);
180 
181             /* Decrement the key refcount since dbAdd() will take its
182              * own reference. */
183             decrRefCount(key);
184         }
185 
186         /* Reset the state that is key-specified and is populated by
187          * opcodes before the key, so that we start from scratch again. */
188         expiretime = -1;
189         lfu_freq = -1;
190         lru_idle = -1;
191     }
192     /* Verify the checksum if RDB version is >= 5 */
193     if (rdbver >= 5) {
194         uint64_t cksum, expected = rdb->cksum;
195 
196         if (rioRead(rdb,&cksum,8) == 0) goto eoferr;
197         if (server.rdb_checksum) {
198             memrev64ifbe(&cksum);
199             if (cksum == 0) {
200                 serverLog(LL_WARNING,"RDB file was saved with checksum disabled: no check performed.");
201             } else if (cksum != expected) {
202                 serverLog(LL_WARNING,"Wrong RDB checksum. Aborting now.");
203                 rdbExitReportCorruptRDB("RDB CRC error");
204             }
205         }
206     }
207     return C_OK;
208 
209 eoferr: /* unexpected end of file is handled here with a fatal exit */
210     serverLog(LL_WARNING,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
211     rdbExitReportCorruptRDB("Unexpected EOF reading RDB file");
212     return C_ERR; /* Just to avoid warning */
213 }


解决

mv /data/data1/redis/slave/dump.rdb /data/data1/redis/slave/dump.rdb.bak

图片: rdb文件位置 重启即可