diff --git a/src/tsdb/inc/tsdbMain.h b/src/tsdb/inc/tsdbMain.h index f42c00f1711a276c2a4d6682f93d0b92864aabb9..678e167351b274c536688377c8c27e8f66b01e44 100644 --- a/src/tsdb/inc/tsdbMain.h +++ b/src/tsdb/inc/tsdbMain.h @@ -186,6 +186,7 @@ typedef struct { typedef struct { int fileId; + int state; // 0 for health, 1 for problem SFile files[TSDB_FILE_TYPE_MAX]; } SFileGroup; diff --git a/src/tsdb/src/tsdbFile.c b/src/tsdb/src/tsdbFile.c index b8173d41b398747c4742a7c6e3cdd06b71030f67..71d88ff29eab369c400c9f85c34d296afa8b4f3d 100644 --- a/src/tsdb/src/tsdbFile.c +++ b/src/tsdb/src/tsdbFile.c @@ -13,6 +13,8 @@ * along with this program. If not, see . */ #define _DEFAULT_SOURCE +#include + #include "os.h" #include "talgo.h" #include "tchecksum.h" @@ -23,10 +25,11 @@ const char *tsdbFileSuffix[] = {".head", ".data", ".last", ".stat", ".h", ".d", ".l", ".s"}; -static int tsdbInitFile(SFile *pFile, STsdbRepo *pRepo, int fid, int type); -static void tsdbDestroyFile(SFile *pFile); -static int compFGroup(const void *arg1, const void *arg2); -static int keyFGroupCompFunc(const void *key, const void *fgroup); +static int tsdbInitFile(SFile *pFile, STsdbRepo *pRepo, int fid, int type); +static void tsdbDestroyFile(SFile *pFile); +static int compFGroup(const void *arg1, const void *arg2); +static int keyFGroupCompFunc(const void *key, const void *fgroup); +static void tsdbInitFileGroup(SFileGroup *pFGroup, STsdbRepo *pRepo); // ---------------- INTERNAL FUNCTIONS ---------------- STsdbFileH *tsdbNewFileH(STsdbCfg *pCfg) { @@ -69,12 +72,14 @@ void tsdbFreeFileH(STsdbFileH *pFileH) { int tsdbOpenFileH(STsdbRepo *pRepo) { ASSERT(pRepo != NULL && pRepo->tsdbFileH != NULL); - char *tDataDir = NULL; - DIR * dir = NULL; - int fid = 0; - int vid = 0; + char * tDataDir = NULL; + DIR * dir = NULL; + int fid = 0; + int vid = 0; + regex_t regex1, regex2; + int code = 0; - SFileGroup fileGroup = {0}; + SFileGroup fileGroup = {0}; STsdbFileH *pFileH = pRepo->tsdbFileH; tDataDir = tsdbGetDataDirName(pRepo->rootDir); @@ -90,28 +95,56 @@ int tsdbOpenFileH(STsdbRepo *pRepo) { goto _err; } + code = regcomp(®ex1, "^v[0-9]+f[0-9]+\\.(head|data|last|stat)$", REG_EXTENDED); + if (code != 0) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + goto _err; + } + + code = regcomp(®ex2, "^v[0-9]+f[0-9]+\\.(h|d|l|s)$", REG_EXTENDED); + if (code != 0) { + terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; + goto _err; + } + struct dirent *dp = NULL; while ((dp = readdir(dir)) != NULL) { - if (strncmp(dp->d_name, ".", 1) == 0 || strncmp(dp->d_name, "..", 2) == 0) continue; - sscanf(dp->d_name, "v%df%d", &vid, &fid); - - if (tsdbSearchFGroup(pRepo->tsdbFileH, fid, TD_EQ) != NULL) continue; + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; + + code = regexec(®ex1, dp->d_name, 0, NULL, 0); + if (code == 0) { + sscanf(dp->d_name, "v%df%d", &vid, &fid); + if (vid != REPO_ID(pRepo)) { + tsdbError("vgId:%d invalid file %s exists, ignore it", REPO_ID(pRepo), dp->d_name); + continue; + } - memset((void *)(&fileGroup), 0, sizeof(SFileGroup)); - fileGroup.fileId = fid; - for (int type = 0; type < TSDB_FILE_TYPE_MAX; type++) { - if (tsdbInitFile(&fileGroup.files[type], pRepo, fid, type) < 0) { - tsdbError("vgId:%d failed to init file fid %d type %d", REPO_ID(pRepo), fid, type); + if (tsdbSearchFGroup(pFileH, fid, TD_EQ) != NULL) continue; + memset((void *)(&fileGroup), 0, sizeof(SFileGroup)); + fileGroup.fileId = fid; + + tsdbInitFileGroup(&fileGroup, pRepo); + } else if (code == REG_NOMATCH) { + code = regexec(®ex2, dp->d_name, 0, NULL, 0); + if (code == 0) { + tsdbDebug("vgId:%d invalid file %s exists, remove it", REPO_ID(pRepo), dp->d_name); + remove(dp->d_name); + } else if (code == REG_NOMATCH) { + tsdbError("vgId:%d invalid file %s exists, ignore it", REPO_ID(pRepo), dp->d_name); + continue; + } else { goto _err; } + } else { + goto _err; } - tsdbDebug("vgId:%d file group %d init", REPO_ID(pRepo), fid); - pFileH->pFGroup[pFileH->nFGroups++] = fileGroup; qsort((void *)(pFileH->pFGroup), pFileH->nFGroups, sizeof(SFileGroup), compFGroup); } + regfree(®ex1); + regfree(®ex2); taosTFree(tDataDir); closedir(dir); return 0; @@ -119,6 +152,9 @@ int tsdbOpenFileH(STsdbRepo *pRepo) { _err: for (int type = 0; type < TSDB_FILE_TYPE_MAX; type++) tsdbDestroyFile(&fileGroup.files[type]); + regfree(®ex1); + regfree(®ex2); + taosTFree(tDataDir); if (dir != NULL) closedir(dir); tsdbCloseFileH(pRepo); @@ -450,3 +486,14 @@ static int keyFGroupCompFunc(const void *key, const void *fgroup) { return fid > pFGroup->fileId ? 1 : -1; } } + +static void tsdbInitFileGroup(SFileGroup *pFGroup, STsdbRepo *pRepo) { + for (int type = 0; type < TSDB_FILE_TYPE_MAX; type++) { + if (tsdbInitFile(&pFGroup->files[type], pRepo, pFGroup->fileId, type) < 0) { + memset(&pFGroup->files[type].info, 0, sizeof(STsdbFileInfo)); + pFGroup->files[type].info.magic = TSDB_FILE_INIT_MAGIC; + pFGroup->state = 1; + terrno = TSDB_CODE_TDB_FILE_CORRUPTED; + } + } +} \ No newline at end of file diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 3acad055042a2479cf3293baa16ce2fabf1c7a71..628a8bac81ccaf9c4c0c4d5741bafd99f9cf3523 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -71,6 +71,8 @@ static void tsdbStopStream(STsdbRepo *pRepo); // Function declaration int32_t tsdbCreateRepo(char *rootDir, STsdbCfg *pCfg) { + taosRemoveDir(rootDir); + if (mkdir(rootDir, 0755) < 0) { tsdbError("vgId:%d failed to create rootDir %s since %s", pCfg->tsdbId, rootDir, strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); @@ -95,6 +97,8 @@ TSDB_REPO_T *tsdbOpenRepo(char *rootDir, STsdbAppH *pAppH) { STsdbCfg config = {0}; STsdbRepo *pRepo = NULL; + terrno = TSDB_CODE_SUCCESS; + if (tsdbLoadConfig(rootDir, &config) < 0) { tsdbError("failed to open repo in rootDir %s since %s", rootDir, tstrerror(terrno)); return NULL; @@ -799,6 +803,7 @@ static int tsdbRestoreInfo(STsdbRepo *pRepo) { tsdbInitFileGroupIter(pFileH, &iter, TSDB_ORDER_DESC); while ((pFGroup = tsdbGetFileGroupNext(&iter)) != NULL) { + if (pFGroup->state) continue; if (tsdbSetAndOpenHelperFile(&rhelper, pFGroup) < 0) goto _err; if (tsdbLoadCompIdx(&rhelper, NULL) < 0) goto _err; for (int i = 1; i < pMeta->maxTables; i++) { diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 9695f90c30856510572dbabbd3878c84b9b18402..f191c6f1e5c076bbe2e6dc80f9fa0db0d972cc9b 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -257,7 +257,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) { if (pVnode->tsdb == NULL) { vnodeCleanUp(pVnode); return terrno; - } else if (terrno != 0 && pVnode->syncCfg.replica <= 1) { + } else if (terrno != TSDB_CODE_SUCCESS && pVnode->syncCfg.replica <= 1) { vError("vgId:%d, failed to open tsdb, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica, tstrerror(terrno)); vnodeCleanUp(pVnode);