redis啟動報錯詳解(2)Unrecoverable error: corrupted cluster config file.
阿新 • • 發佈:2018-12-25
➜ 7000 ../redis-server redis.conf & [1] 11045 11045:C 24 Oct 2018 19:26:52.320 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 11045:C 24 Oct 2018 19:26:52.320 # Redis version=999.999.999, bits=64, commit=54e8dd11, modified=0, pid=11045, just started 11045:C 24 Oct 2018 19:26:52.320 # Configuration loaded 11045:M 24 Oct 2018 19:26:52.322 * Increased maximum number of open files to 10032 (it was originally set to 7168). 11045:M 24 Oct 2018 19:26:52.323 # Unrecoverable error: corrupted cluster config file.
從字面意思理解是損壞的cluster配置,同樣到原始碼中查詢相應的錯誤丟擲點找到如下資訊
1.錯誤日誌的輸出點是下邊的這段程式碼
fmterr:
serverLog(LL_WARNING,
"Unrecoverable error: corrupted cluster config file.");
zfree(line);
if (fp) fclose(fp);
exit(1);
}
根據原始碼解讀發現,我們沒有建立nodes.conf檔案,預設此方法會返回一個C_ERR,然後由呼叫方clusterInit函式新建此檔案並建立cluster,clusterLoadConfig函式整體程式碼如下。但是現在找到了此檔案,並進行解讀時報錯,證明redis.conf配置檔案中配置的內容有誤。查詢配置檔案發現cluster-config-file引數配置錯誤,改成cluster-config-file nodes.conf問題解決。
/* Load the cluster config from 'filename'. * * If the file does not exist or is zero-length (this may happen because * when we lock the nodes.conf file, we create a zero-length one for the * sake of locking if it does not already exist), C_ERR is returned. * If the configuration was loaded from the file, C_OK is returned. */ int clusterLoadConfig(char *filename) { FILE *fp = fopen(filename,"r"); struct stat sb; char *line; int maxline, j; if (fp == NULL) { if (errno == ENOENT) { return C_ERR; } else { serverLog(LL_WARNING, "Loading the cluster node config from %s: %s", filename, strerror(errno)); exit(1); } } /* Check if the file is zero-length: if so return C_ERR to signal * we have to write the config. */ if (fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) { fclose(fp); return C_ERR; } /* Parse the file. Note that single lines of the cluster config file can * be really long as they include all the hash slots of the node. * This means in the worst possible case, half of the Redis slots will be * present in a single line, possibly in importing or migrating state, so * together with the node ID of the sender/receiver. * * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */ maxline = 1024+CLUSTER_SLOTS*128; line = zmalloc(maxline); while(fgets(line,maxline,fp) != NULL) { int argc; sds *argv; clusterNode *n, *master; char *p, *s; /* Skip blank lines, they can be created either by users manually * editing nodes.conf or by the config writing process if stopped * before the truncate() call. */ if (line[0] == '\n' || line[0] == '\0') continue; /* Split the line into arguments for processing. */ argv = sdssplitargs(line,&argc); if (argv == NULL) goto fmterr; /* Handle the special "vars" line. Don't pretend it is the last * line even if it actually is when generated by Redis. */ if (strcasecmp(argv[0],"vars") == 0) { for (j = 1; j < argc; j += 2) { if (strcasecmp(argv[j],"currentEpoch") == 0) { server.cluster->currentEpoch = strtoull(argv[j+1],NULL,10); } else if (strcasecmp(argv[j],"lastVoteEpoch") == 0) { server.cluster->lastVoteEpoch = strtoull(argv[j+1],NULL,10); } else { serverLog(LL_WARNING, "Skipping unknown cluster config variable '%s'", argv[j]); } } sdsfreesplitres(argv,argc); continue; } /* Regular config lines have at least eight fields */ if (argc < 8) goto fmterr; /* Create this node if it does not exist */ n = clusterLookupNode(argv[0]); if (!n) { n = createClusterNode(argv[0],0); clusterAddNode(n); } /* Address and port */ if ((p = strrchr(argv[1],':')) == NULL) goto fmterr; *p = '\0'; memcpy(n->ip,argv[1],strlen(argv[1])+1); char *port = p+1; char *busp = strchr(port,'@'); if (busp) { *busp = '\0'; busp++; } n->port = atoi(port); /* In older versions of nodes.conf the "@busport" part is missing. * In this case we set it to the default offset of 10000 from the * base port. */ n->cport = busp ? atoi(busp) : n->port + CLUSTER_PORT_INCR; /* Parse flags */ p = s = argv[2]; while(p) { p = strchr(s,','); if (p) *p = '\0'; if (!strcasecmp(s,"myself")) { serverAssert(server.cluster->myself == NULL); myself = server.cluster->myself = n; n->flags |= CLUSTER_NODE_MYSELF; } else if (!strcasecmp(s,"master")) { n->flags |= CLUSTER_NODE_MASTER; } else if (!strcasecmp(s,"slave")) { n->flags |= CLUSTER_NODE_SLAVE; } else if (!strcasecmp(s,"fail?")) { n->flags |= CLUSTER_NODE_PFAIL; } else if (!strcasecmp(s,"fail")) { n->flags |= CLUSTER_NODE_FAIL; n->fail_time = mstime(); } else if (!strcasecmp(s,"handshake")) { n->flags |= CLUSTER_NODE_HANDSHAKE; } else if (!strcasecmp(s,"noaddr")) { n->flags |= CLUSTER_NODE_NOADDR; } else if (!strcasecmp(s,"nofailover")) { n->flags |= CLUSTER_NODE_NOFAILOVER; } else if (!strcasecmp(s,"noflags")) { /* nothing to do */ } else { serverPanic("Unknown flag in redis cluster config file"); } if (p) s = p+1; } /* Get master if any. Set the master and populate master's * slave list. */ if (argv[3][0] != '-') { master = clusterLookupNode(argv[3]); if (!master) { master = createClusterNode(argv[3],0); clusterAddNode(master); } n->slaveof = master; clusterNodeAddSlave(master,n); } /* Set ping sent / pong received timestamps */ if (atoi(argv[4])) n->ping_sent = mstime(); if (atoi(argv[5])) n->pong_received = mstime(); /* Set configEpoch for this node. */ n->configEpoch = strtoull(argv[6],NULL,10); /* Populate hash slots served by this instance. */ for (j = 8; j < argc; j++) { int start, stop; if (argv[j][0] == '[') { /* Here we handle migrating / importing slots */ int slot; char direction; clusterNode *cn; p = strchr(argv[j],'-'); serverAssert(p != NULL); *p = '\0'; direction = p[1]; /* Either '>' or '<' */ slot = atoi(argv[j]+1); if (slot < 0 || slot >= CLUSTER_SLOTS) goto fmterr; p += 3; cn = clusterLookupNode(p); if (!cn) { cn = createClusterNode(p,0); clusterAddNode(cn); } if (direction == '>') { server.cluster->migrating_slots_to[slot] = cn; } else { server.cluster->importing_slots_from[slot] = cn; } continue; } else if ((p = strchr(argv[j],'-')) != NULL) { *p = '\0'; start = atoi(argv[j]); stop = atoi(p+1); } else { start = stop = atoi(argv[j]); } if (start < 0 || start >= CLUSTER_SLOTS) goto fmterr; if (stop < 0 || stop >= CLUSTER_SLOTS) goto fmterr; while(start <= stop) clusterAddSlot(n, start++); } sdsfreesplitres(argv,argc); } /* Config sanity check */ if (server.cluster->myself == NULL) goto fmterr; zfree(line); fclose(fp); serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name); /* Something that should never happen: currentEpoch smaller than * the max epoch found in the nodes configuration. However we handle this * as some form of protection against manual editing of critical files. */ if (clusterGetMaxEpoch() > server.cluster->currentEpoch) { server.cluster->currentEpoch = clusterGetMaxEpoch(); } return C_OK; fmterr: serverLog(LL_WARNING, "Unrecoverable error: corrupted cluster config file."); zfree(line); if (fp) fclose(fp); exit(1); }