Merge pull request #28385 from taosdata/fix/TS-5529-3.0
fix: remove invalid error code check and add meta data recover and compact function
This commit is contained in:
commit
1febe0b400
|
@ -182,6 +182,7 @@ static void dmSetSignalHandle() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
extern bool generateNewMeta;
|
||||||
|
|
||||||
static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
||||||
global.startTime = taosGetTimestampMs();
|
global.startTime = taosGetTimestampMs();
|
||||||
|
@ -221,6 +222,8 @@ static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
||||||
global.dumpSdb = true;
|
global.dumpSdb = true;
|
||||||
} else if (strcmp(argv[i], "-dTxn") == 0) {
|
} else if (strcmp(argv[i], "-dTxn") == 0) {
|
||||||
global.deleteTrans = true;
|
global.deleteTrans = true;
|
||||||
|
} else if (strcmp(argv[i], "-r") == 0) {
|
||||||
|
generateNewMeta = true;
|
||||||
} else if (strcmp(argv[i], "-E") == 0) {
|
} else if (strcmp(argv[i], "-E") == 0) {
|
||||||
if (i < argc - 1) {
|
if (i < argc - 1) {
|
||||||
if (strlen(argv[++i]) >= PATH_MAX) {
|
if (strlen(argv[++i]) >= PATH_MAX) {
|
||||||
|
|
|
@ -81,6 +81,9 @@ typedef struct SCommitInfo SCommitInfo;
|
||||||
typedef struct SCompactInfo SCompactInfo;
|
typedef struct SCompactInfo SCompactInfo;
|
||||||
typedef struct SQueryNode SQueryNode;
|
typedef struct SQueryNode SQueryNode;
|
||||||
|
|
||||||
|
#define VNODE_META_TMP_DIR "meta.tmp"
|
||||||
|
#define VNODE_META_BACKUP_DIR "meta.backup"
|
||||||
|
|
||||||
#define VNODE_META_DIR "meta"
|
#define VNODE_META_DIR "meta"
|
||||||
#define VNODE_TSDB_DIR "tsdb"
|
#define VNODE_TSDB_DIR "tsdb"
|
||||||
#define VNODE_TQ_DIR "tq"
|
#define VNODE_TQ_DIR "tq"
|
||||||
|
|
|
@ -133,7 +133,7 @@ static void doScan(SMeta *pMeta) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
|
static int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, int8_t rollback) {
|
||||||
SMeta *pMeta = NULL;
|
SMeta *pMeta = NULL;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
int32_t lino;
|
int32_t lino;
|
||||||
|
@ -144,7 +144,11 @@ int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
|
||||||
// create handle
|
// create handle
|
||||||
vnodeGetPrimaryDir(pVnode->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
vnodeGetPrimaryDir(pVnode->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
||||||
offset = strlen(path);
|
offset = strlen(path);
|
||||||
snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, VNODE_META_DIR);
|
snprintf(path + offset, TSDB_FILENAME_LEN - offset - 1, "%s%s", TD_DIRSEP, metaDir);
|
||||||
|
|
||||||
|
if (strncmp(metaDir, VNODE_META_TMP_DIR, strlen(VNODE_META_TMP_DIR)) == 0) {
|
||||||
|
taosRemoveDir(path);
|
||||||
|
}
|
||||||
|
|
||||||
if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + strlen(path) + 1)) == NULL) {
|
if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + strlen(path) + 1)) == NULL) {
|
||||||
TSDB_CHECK_CODE(code = terrno, lino, _exit);
|
TSDB_CHECK_CODE(code = terrno, lino, _exit);
|
||||||
|
@ -245,6 +249,188 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool generateNewMeta = false;
|
||||||
|
|
||||||
|
static int32_t metaGenerateNewMeta(SMeta **ppMeta) {
|
||||||
|
SMeta *pNewMeta = NULL;
|
||||||
|
SMeta *pMeta = *ppMeta;
|
||||||
|
SVnode *pVnode = pMeta->pVnode;
|
||||||
|
|
||||||
|
metaInfo("vgId:%d start to generate new meta", TD_VID(pMeta->pVnode));
|
||||||
|
|
||||||
|
// Open a new meta for orgainzation
|
||||||
|
int32_t code = metaOpenImpl(pMeta->pVnode, &pNewMeta, VNODE_META_TMP_DIR, false);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// i == 0, scan super table
|
||||||
|
// i == 1, scan normal table and child table
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
TBC *uidCursor = NULL;
|
||||||
|
int32_t counter = 0;
|
||||||
|
|
||||||
|
code = tdbTbcOpen(pMeta->pUidIdx, &uidCursor, NULL);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to open uid index cursor, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tdbTbcMoveToFirst(uidCursor);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to move to first, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
tdbTbcClose(uidCursor);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
const void *pKey;
|
||||||
|
int kLen;
|
||||||
|
const void *pVal;
|
||||||
|
int vLen;
|
||||||
|
|
||||||
|
if (tdbTbcGet(uidCursor, &pKey, &kLen, &pVal, &vLen) < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tb_uid_t uid = *(tb_uid_t *)pKey;
|
||||||
|
SUidIdxVal *pUidIdxVal = (SUidIdxVal *)pVal;
|
||||||
|
if ((i == 0 && (pUidIdxVal->suid && pUidIdxVal->suid == uid)) // super table
|
||||||
|
|| (i == 1 && (pUidIdxVal->suid == 0 || pUidIdxVal->suid != uid)) // normal table and child table
|
||||||
|
) {
|
||||||
|
counter++;
|
||||||
|
if (i == 0) {
|
||||||
|
metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter, "super", uid);
|
||||||
|
} else {
|
||||||
|
metaInfo("vgId:%d counter:%d new meta handle %s table uid:%" PRId64, TD_VID(pVnode), counter,
|
||||||
|
pUidIdxVal->suid == 0 ? "normal" : "child", uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch table entry
|
||||||
|
void *value = NULL;
|
||||||
|
int valueSize = 0;
|
||||||
|
if (tdbTbGet(pMeta->pTbDb,
|
||||||
|
&(STbDbKey){
|
||||||
|
.version = pUidIdxVal->version,
|
||||||
|
.uid = uid,
|
||||||
|
},
|
||||||
|
sizeof(uid), &value, &valueSize) == 0) {
|
||||||
|
SDecoder dc = {0};
|
||||||
|
SMetaEntry me = {0};
|
||||||
|
tDecoderInit(&dc, value, valueSize);
|
||||||
|
if (metaDecodeEntry(&dc, &me) == 0) {
|
||||||
|
if (metaHandleEntry(pNewMeta, &me) != 0) {
|
||||||
|
metaError("vgId:%d failed to handle entry, uid:%" PRId64, TD_VID(pVnode), uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tDecoderClear(&dc);
|
||||||
|
}
|
||||||
|
tdbFree(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = tdbTbcMoveToNext(uidCursor);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to move to next, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tdbTbcClose(uidCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = metaCommit(pNewMeta, pNewMeta->txn);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to commit, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = metaFinishCommit(pNewMeta, pNewMeta->txn);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to finish commit, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((code = metaBegin(pNewMeta, META_BEGIN_HEAP_NIL)) != 0) {
|
||||||
|
metaError("vgId:%d failed to begin new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
}
|
||||||
|
metaClose(&pNewMeta);
|
||||||
|
metaInfo("vgId:%d finish to generate new meta", TD_VID(pVnode));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t metaOpen(SVnode *pVnode, SMeta **ppMeta, int8_t rollback) {
|
||||||
|
if (generateNewMeta) {
|
||||||
|
char path[TSDB_FILENAME_LEN] = {0};
|
||||||
|
char oldMetaPath[TSDB_FILENAME_LEN] = {0};
|
||||||
|
char newMetaPath[TSDB_FILENAME_LEN] = {0};
|
||||||
|
char backupMetaPath[TSDB_FILENAME_LEN] = {0};
|
||||||
|
|
||||||
|
vnodeGetPrimaryDir(pVnode->path, pVnode->diskPrimary, pVnode->pTfs, path, TSDB_FILENAME_LEN);
|
||||||
|
snprintf(oldMetaPath, sizeof(oldMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_DIR);
|
||||||
|
snprintf(newMetaPath, sizeof(newMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_TMP_DIR);
|
||||||
|
snprintf(backupMetaPath, sizeof(backupMetaPath) - 1, "%s%s%s", path, TD_DIRSEP, VNODE_META_BACKUP_DIR);
|
||||||
|
|
||||||
|
bool oldMetaExist = taosCheckExistFile(oldMetaPath);
|
||||||
|
bool newMetaExist = taosCheckExistFile(newMetaPath);
|
||||||
|
bool backupMetaExist = taosCheckExistFile(backupMetaPath);
|
||||||
|
|
||||||
|
if ((!backupMetaExist && !oldMetaExist && newMetaExist) // case 2
|
||||||
|
|| (backupMetaExist && !oldMetaExist && !newMetaExist) // case 4
|
||||||
|
|| (backupMetaExist && oldMetaExist && newMetaExist) // case 8
|
||||||
|
) {
|
||||||
|
metaError("vgId:%d invalid meta state, please check", TD_VID(pVnode));
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
} else if ((backupMetaExist && oldMetaExist && !newMetaExist) // case 7
|
||||||
|
|| (!backupMetaExist && !oldMetaExist && !newMetaExist) // case 1
|
||||||
|
) {
|
||||||
|
return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
|
||||||
|
} else if (backupMetaExist && !oldMetaExist && newMetaExist) {
|
||||||
|
if (taosRenameFile(newMetaPath, oldMetaPath) != 0) {
|
||||||
|
metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
|
||||||
|
} else {
|
||||||
|
int32_t code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
|
||||||
|
if (code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = metaGenerateNewMeta(ppMeta);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to generate new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
metaClose(ppMeta);
|
||||||
|
if (taosRenameFile(oldMetaPath, backupMetaPath) != 0) {
|
||||||
|
metaError("vgId:%d failed to rename old meta to backup, reason:%s", TD_VID(pVnode), tstrerror(terrno));
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename the new meta to old meta
|
||||||
|
if (taosRenameFile(newMetaPath, oldMetaPath) != 0) {
|
||||||
|
metaError("vgId:%d failed to rename new meta to old meta, reason:%s", TD_VID(pVnode), tstrerror(terrno));
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
code = metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, false);
|
||||||
|
if (code) {
|
||||||
|
metaError("vgId:%d failed to open new meta, reason:%s", TD_VID(pVnode), tstrerror(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return metaOpenImpl(pVnode, ppMeta, VNODE_META_DIR, rollback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
|
int32_t metaUpgrade(SVnode *pVnode, SMeta **ppMeta) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
int32_t lino;
|
int32_t lino;
|
||||||
|
|
|
@ -2985,9 +2985,6 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
if (terrno != 0) {
|
|
||||||
ret = terrno;
|
|
||||||
}
|
|
||||||
tDecoderClear(&dc);
|
tDecoderClear(&dc);
|
||||||
tdbFree(pData);
|
tdbFree(pData);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -1446,6 +1446,9 @@ static int tdbBtreeDecodePayload(SPage *pPage, const SCell *pCell, int nHeader,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
ofpCell = tdbPageGetCell(ofp, 0);
|
ofpCell = tdbPageGetCell(ofp, 0);
|
||||||
|
if (ofpCell == NULL) {
|
||||||
|
return TSDB_CODE_INVALID_DATA_FMT;
|
||||||
|
}
|
||||||
|
|
||||||
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
if (nLeft <= ofp->maxLocal - sizeof(SPgno)) {
|
||||||
bytes = nLeft;
|
bytes = nLeft;
|
||||||
|
|
Loading…
Reference in New Issue