From 4922cade4451ad0a96341a9e9e17c5a0810c108c Mon Sep 17 00:00:00 2001 From: Hongze Cheng Date: Wed, 11 Dec 2024 17:04:26 +0800 Subject: [PATCH] feat: refact drop super table --- source/dnode/vnode/src/meta/metaEntry2.c | 159 +++++++++++++++++++++-- source/dnode/vnode/src/meta/metaTable2.c | 67 +++++++++- 2 files changed, 215 insertions(+), 11 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaEntry2.c b/source/dnode/vnode/src/meta/metaEntry2.c index bbc9a14d02..879693e7b0 100644 --- a/source/dnode/vnode/src/meta/metaEntry2.c +++ b/source/dnode/vnode/src/meta/metaEntry2.c @@ -388,8 +388,9 @@ static int32_t metaSUidIdxInsert(SMeta *pMeta, const SMetaHandleParam *pParam) { } static int32_t metaSUidIdxDelete(SMeta *pMeta, const SMetaHandleParam *pParam) { - const SMetaEntry *pEntry = pParam->pEntry; - int32_t code = tdbTbDelete(pMeta->pSuidIdx, &pEntry->uid, sizeof(pEntry->uid), pMeta->txn); + const SMetaEntry *pEntry = pParam->pOldEntry; + + int32_t code = tdbTbDelete(pMeta->pSuidIdx, &pEntry->uid, sizeof(pEntry->uid), pMeta->txn); if (code) { metaErr(TD_VID(pMeta->pVnode), code); } @@ -1009,7 +1010,7 @@ static int32_t metaHandleNormalTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) return code; } -static int32_t metaHandleChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam *pParam) { +static int32_t metaHandleChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam *pParam, bool superDropped) { int32_t code = TSDB_CODE_SUCCESS; const SMetaEntry *pEntry = pParam->pEntry; @@ -1029,6 +1030,10 @@ static int32_t metaHandleChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) { SMetaTableOp *op = &ops[i]; + if (op->table == META_ENTRY_TABLE && superDropped) { + continue; + } + code = metaTableOpFn[op->table][op->op](pMeta, pParam); if (code) { metaErr(TD_VID(pMeta->pVnode), code); @@ -1050,7 +1055,7 @@ static int32_t metaHandleChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam return code; } -static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) { +static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry, bool superDropped) { int32_t code = TSDB_CODE_SUCCESS; SMetaEntry *pChild = NULL; SMetaEntry *pSuper = NULL; @@ -1078,7 +1083,7 @@ static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) // do the drop metaWLock(pMeta); - code = metaHandleChildTableDropImpl(pMeta, ¶m); + code = metaHandleChildTableDropImpl(pMeta, ¶m, superDropped); metaULock(pMeta); if (code) { metaErr(TD_VID(pMeta->pVnode), code); @@ -1121,9 +1126,145 @@ static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) return code; } -static int32_t metaHandleSuperTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) { +static int32_t metaGetChildUidsOfSuperTable(SMeta *pMeta, tb_uid_t suid, SArray **childList) { int32_t code = TSDB_CODE_SUCCESS; - // TODO + void *key = NULL; + int32_t keySize = 0; + int32_t c; + + *childList = taosArrayInit(64, sizeof(tb_uid_t)); + if (*childList == NULL) { + return terrno; + } + + TBC *cursor = NULL; + code = tdbTbcOpen(pMeta->pCtbIdx, &cursor, NULL); + if (code) { + taosArrayDestroy(*childList); + *childList = NULL; + return code; + } + + int32_t rc = tdbTbcMoveTo(cursor, + &(SCtbIdxKey){ + .suid = suid, + .uid = INT64_MIN, + }, + sizeof(SCtbIdxKey), &c); + if (rc < 0) { + tdbTbcClose(cursor); + return 0; + } + + for (;;) { + if (tdbTbcNext(cursor, &key, &keySize, NULL, NULL) < 0) { + break; + } + + if (((SCtbIdxKey *)key)->suid < suid) { + continue; + } else if (((SCtbIdxKey *)key)->suid > suid) { + break; + } + + if (taosArrayPush(*childList, &(((SCtbIdxKey *)key)->uid)) == NULL) { + tdbFreeClear(key); + tdbTbcClose(cursor); + taosArrayDestroy(*childList); + *childList = NULL; + return terrno; + } + } + + tdbTbcClose(cursor); + tdbFreeClear(key); + return code; +} + +static int32_t metaHandleSuperTableDropImpl(SMeta *pMeta, const SMetaHandleParam *pParam) { + int32_t code = TSDB_CODE_SUCCESS; + const SMetaEntry *pEntry = pParam->pEntry; + + SMetaTableOp ops[] = { + {META_ENTRY_TABLE, META_TABLE_OP_DELETE}, // + {META_UID_IDX, META_TABLE_OP_DELETE}, // + {META_NAME_IDX, META_TABLE_OP_DELETE}, // + {META_SUID_IDX, META_TABLE_OP_DELETE}, // + + // {META_SCHEMA_TABLE, META_TABLE_OP_UPDATA}, // TODO: here should be insert + }; + + for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) { + SMetaTableOp *op = &ops[i]; + + code = metaTableOpFn[op->table][op->op](pMeta, pParam); + if (TSDB_CODE_SUCCESS != code) { + metaErr(TD_VID(pMeta->pVnode), code); + return code; + } + } + + int32_t ret = metaStatsCacheDrop(pMeta, pEntry->uid); + if (ret < 0) { + metaErr(TD_VID(pMeta->pVnode), ret); + } + return code; +} + +static int32_t metaHandleSuperTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) { + int32_t code = TSDB_CODE_SUCCESS; + SArray *childList = NULL; + SMetaEntry *pOldEntry = NULL; + + code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry); + if (code) { + metaErr(TD_VID(pMeta->pVnode), code); + return code; + } + + code = metaGetChildUidsOfSuperTable(pMeta, pEntry->uid, &childList); + if (code) { + metaErr(TD_VID(pMeta->pVnode), code); + metaFetchEntryFree(&pOldEntry); + return code; + } + + // loop to drop all child tables + for (int32_t i = 0; i < taosArrayGetSize(childList); i++) { + SMetaEntry childEntry = { + .version = pEntry->version, + .uid = *(tb_uid_t *)taosArrayGet(childList, i), + .type = -TSDB_CHILD_TABLE, + }; + + code = metaHandleChildTableDrop(pMeta, &childEntry, true); + if (code) { + metaErr(TD_VID(pMeta->pVnode), code); + } + } + + // do drop super table + SMetaHandleParam param = { + .pEntry = pEntry, + .pOldEntry = pOldEntry, + }; + metaWLock(pMeta); + code = metaHandleSuperTableDropImpl(pMeta, ¶m); + metaULock(pMeta); + if (code) { + metaErr(TD_VID(pMeta->pVnode), code); + taosArrayDestroy(childList); + metaFetchEntryFree(&pOldEntry); + return code; + } + + // do other stuff + metaUpdTimeSeriesNum(pMeta); + pMeta->changed = true; + + // free resource and return + taosArrayDestroy(childList); + metaFetchEntryFree(&pOldEntry); return code; } @@ -1177,11 +1318,11 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) { } else { switch (type) { case TSDB_SUPER_TABLE: { - // code = metaHandleSuperTableDrop(pMeta, pEntry); + code = metaHandleSuperTableDrop(pMeta, pEntry); break; } case TSDB_CHILD_TABLE: { - code = metaHandleChildTableDrop(pMeta, pEntry); + code = metaHandleChildTableDrop(pMeta, pEntry, false); break; } case TSDB_NORMAL_TABLE: { diff --git a/source/dnode/vnode/src/meta/metaTable2.c b/source/dnode/vnode/src/meta/metaTable2.c index 9c20f8c8ba..1798a26a1d 100644 --- a/source/dnode/vnode/src/meta/metaTable2.c +++ b/source/dnode/vnode/src/meta/metaTable2.c @@ -109,6 +109,49 @@ static int32_t metaCheckDropTableReq(SMeta *pMeta, int64_t version, SVDropTbReq return code; } +static int32_t metaCheckDropSuperTableReq(SMeta *pMeta, int64_t version, SVDropStbReq *pReq) { + int32_t code = TSDB_CODE_SUCCESS; + void *value = NULL; + int32_t valueSize = 0; + SMetaInfo info; + + if (NULL == pReq->name || strlen(pReq->name) == 0) { + metaError("vgId:%d, %s failed at %s:%d since invalid name:%s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, + __FILE__, __LINE__, pReq->name, version); + return TSDB_CODE_INVALID_MSG; + } + + code = tdbTbGet(pMeta->pNameIdx, pReq->name, strlen(pReq->name) + 1, &value, &valueSize); + if (code) { + metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, + __FILE__, __LINE__, pReq->name, version); + return TSDB_CODE_TDB_STB_NOT_EXIST; + } else { + int64_t uid = *(int64_t *)value; + tdbFreeClear(value); + + if (uid != pReq->suid) { + metaError("vgId:%d, %s failed at %s:%d since table %s uid:%" PRId64 " not match, version:%" PRId64, + TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version); + return TSDB_CODE_TDB_STB_NOT_EXIST; + } + } + + code = metaGetInfo(pMeta, pReq->suid, &info, NULL); + if (code) { + metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 + " not found, this is an internal error, version:%" PRId64, + TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version); + return TSDB_CODE_INTERNAL_ERROR; + } + if (info.suid != info.uid) { + metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a super table, version:%" PRId64, + TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->name, pReq->suid, version); + return TSDB_CODE_INVALID_MSG; + } + return code; +} + // Create Super Table int32_t metaCreateSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) { int32_t code = TSDB_CODE_SUCCESS; @@ -155,9 +198,29 @@ int32_t metaCreateSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq } // Drop Super Table -int32_t metaDropSuperTable() { +int32_t metaDropSuperTable(SMeta *pMeta, int64_t verison, SVDropStbReq *pReq) { int32_t code = TSDB_CODE_SUCCESS; - // TODO + + // check request + code = metaCheckDropSuperTableReq(pMeta, verison, pReq); + if (code) { + TAOS_RETURN(code); + } + + // handle entry + SMetaEntry entry = { + .version = verison, + .type = -TSDB_SUPER_TABLE, + .uid = pReq->suid, + }; + code = metaHandleEntry2(pMeta, &entry); + if (code) { + metaError("vgId:%d, failed to drop stb:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), pReq->name, pReq->suid, + tstrerror(code)); + } else { + metaInfo("vgId:%d, super table %s uid:%" PRId64 " is dropped, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name, + pReq->suid, verison); + } return code; }