From 6beee204d825ef8a5fc0a2412f1064a1bb9ae615 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Tue, 21 Dec 2021 20:07:32 +0800 Subject: [PATCH 01/22] add tq query --- include/dnode/vnode/tq/tq.h | 29 +++-- include/dnode/vnode/vnode.h | 10 ++ include/libs/wal/wal.h | 5 +- include/util/ttimer.h | 2 + source/dnode/vnode/tq/CMakeLists.txt | 1 + source/dnode/vnode/tq/inc/tqInt.h | 1 + source/dnode/vnode/tq/src/tq.c | 182 ++++++++++++++++++++++----- source/libs/wal/src/walRead.c | 8 +- 8 files changed, 197 insertions(+), 41 deletions(-) diff --git a/include/dnode/vnode/tq/tq.h b/include/dnode/vnode/tq/tq.h index 60a8c252c0..5eeaaa1011 100644 --- a/include/dnode/vnode/tq/tq.h +++ b/include/dnode/vnode/tq/tq.h @@ -22,6 +22,7 @@ #include "taoserror.h" #include "taosmsg.h" #include "tlist.h" +#include "trpc.h" #include "tutil.h" #ifdef __cplusplus @@ -54,6 +55,7 @@ typedef struct STqSetCurReq { typedef struct STqConsumeReq { STqMsgHead head; + int64_t blockingTime; // milisec STqAcks acks; } STqConsumeReq; @@ -107,6 +109,17 @@ typedef struct STqExec { struct STqExec* (*deserialize)(char*); } STqExec; +typedef struct STqRspHandle { + void* handle; + void* ahandle; +} STqRspHandle; + +typedef enum { + TQ_ITEM_READY, + TQ_ITEM_PROCESS, + TQ_ITEM_EMPTY +} STqItemStatus; + typedef struct STqBufferItem { int64_t offset; // executors are identical but not concurrent @@ -135,13 +148,13 @@ typedef struct STqListHandle { } STqList; typedef struct STqGroup { - int64_t clientId; - int64_t cgId; - void* ahandle; - int32_t topicNum; - STqList* head; - SList* topicList; // SList - void* returnMsg; // SVReadMsg + int64_t clientId; + int64_t cgId; + void* ahandle; + int32_t topicNum; + //STqList* head; + SList* topicList; // SList + STqRspHandle rspHandle; } STqGroup; typedef struct STqQueryMsg { @@ -264,7 +277,7 @@ void tqClose(STQ*); // void* will be replace by a msg type int tqPushMsg(STQ*, void* msg, int64_t version); int tqCommit(STQ*); -int tqConsume(STQ*, STqConsumeReq*); +int tqConsume(STQ*, SRpcMsg* pReq, SRpcMsg** pRsp); int tqSetCursor(STQ*, STqSetCurReq* pMsg); int tqBufferSetOffset(STqTopic*, int64_t offset); diff --git a/include/dnode/vnode/vnode.h b/include/dnode/vnode/vnode.h index 8458ad9da3..a373828ebd 100644 --- a/include/dnode/vnode/vnode.h +++ b/include/dnode/vnode/vnode.h @@ -122,6 +122,16 @@ int vnodeProcessWMsgs(SVnode *pVnode, SArray *pMsgs); */ int vnodeApplyWMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); +/** + * @brief Process a consume message. + * + * @param pVnode The vnode object. + * @param pMsg The request message + * @param pRsp The response message + * @return int 0 for success, -1 for failure + */ +int vnodeProcessCMsg(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp); + /** * @brief Process the sync request * diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h index 89f24cf3a4..67d2009d3b 100644 --- a/include/libs/wal/wal.h +++ b/include/libs/wal/wal.h @@ -174,8 +174,11 @@ SWalReadHandle *walOpenReadHandle(SWal *); void walCloseReadHandle(SWalReadHandle *); int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver); +// deprecated +#if 0 int32_t walRead(SWal *, SWalHead **, int64_t ver); -// int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum); +int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum); +#endif // lifecycle check int64_t walGetFirstVer(SWal *); diff --git a/include/util/ttimer.h b/include/util/ttimer.h index 987d3f3cdc..89ec6cd8d9 100644 --- a/include/util/ttimer.h +++ b/include/util/ttimer.h @@ -16,6 +16,8 @@ #ifndef _TD_UTIL_TIMER_H #define _TD_UTIL_TIMER_H +#include "os.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/source/dnode/vnode/tq/CMakeLists.txt b/source/dnode/vnode/tq/CMakeLists.txt index 8d59c7b07a..7cb7499d64 100644 --- a/source/dnode/vnode/tq/CMakeLists.txt +++ b/source/dnode/vnode/tq/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries( PUBLIC os PUBLIC util PUBLIC common + PUBLIC transport ) if(${BUILD_TEST}) diff --git a/source/dnode/vnode/tq/inc/tqInt.h b/source/dnode/vnode/tq/inc/tqInt.h index 5685a29d03..107f5d5103 100644 --- a/source/dnode/vnode/tq/inc/tqInt.h +++ b/source/dnode/vnode/tq/inc/tqInt.h @@ -18,6 +18,7 @@ #include "tq.h" #include "tlog.h" +#include "trpc.h" #ifdef __cplusplus extern "C" { #endif diff --git a/source/dnode/vnode/tq/src/tq.c b/source/dnode/vnode/tq/src/tq.c index d8dfe4ddcf..972740183d 100644 --- a/source/dnode/vnode/tq/src/tq.c +++ b/source/dnode/vnode/tq/src/tq.c @@ -14,7 +14,9 @@ */ #include "tqInt.h" +#include "osSocket.h" #include "tqMetaStore.h" +#include "osAtomic.h" // static // read next version data @@ -51,16 +53,22 @@ STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemA } pTq->tqMeta = tqStoreOpen(path, (FTqSerialize)tqSerializeGroup, (FTqDeserialize)tqDeserializeGroup, free, 0); if (pTq->tqMeta == NULL) { - // TODO: free STQ + free(pTq); + allocFac->destroy(allocFac, pTq->tqMemRef.pAllocator); return NULL; } + return pTq; } + void tqClose(STQ* pTq) { // TODO } -static int tqProtoCheck(STqMsgHead* pMsg) { return pMsg->protoVer == 0; } +static int tqProtoCheck(STqMsgHead* pMsg) { + // TODO + return pMsg->protoVer == 0; +} static int tqAckOneTopic(STqTopic* pTopic, STqOneAck* pAck, STqQueryMsg** ppQuery) { // clean old item and move forward @@ -121,9 +129,15 @@ int tqCreateGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId, STqGroup // TODO return -1; } - *ppGroup = pGroup; memset(pGroup, 0, sizeof(STqGroup)); + pGroup->topicList = tdListNew(sizeof(STqTopic)); + if(pGroup->topicList == NULL) { + free(pGroup); + return -1; + } + *ppGroup = pGroup; + return 0; } @@ -152,46 +166,55 @@ int tqDropGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { return 0; } -static int tqFetch(STqGroup* pGroup, void** msg) { - STqList* head = pGroup->head; - STqList* node = head; +static int tqFetch(STqGroup* pGroup, STqConsumeRsp** pRsp) { + STqList* pHead = pGroup->head; + STqList* pNode = pHead; int totSize = 0; + int numOfMsgs = 0; // TODO: make it a macro - int sizeLimit = 4 * 1024; - STqMsgContent* buffer = malloc(sizeLimit); - if (buffer == NULL) { - // TODO:memory insufficient + int sizeLimit = 4 * 1024; + + void* ptr = realloc(*pRsp, sizeof(STqConsumeRsp) + sizeLimit); + if (ptr == NULL) { + terrno = TSDB_CODE_TQ_OUT_OF_MEMORY; return -1; } + *pRsp = ptr; + STqMsgContent* buffer = (*pRsp)->msgs; + // iterate the list to get msgs of all topics // until all topic iterated or msgs over sizeLimit - while (node->next) { - node = node->next; - STqTopic* topicHandle = &node->topic; - int idx = topicHandle->nextConsumeOffset % TQ_BUFFER_SIZE; - if (topicHandle->buffer[idx].content != NULL && topicHandle->buffer[idx].offset == topicHandle->nextConsumeOffset) { - totSize += topicHandle->buffer[idx].size; + while (pNode->next) { + pNode = pNode->next; + STqTopic* pTopic = &pNode->topic; + int idx = pTopic->nextConsumeOffset % TQ_BUFFER_SIZE; + if (pTopic->buffer[idx].content != NULL && pTopic->buffer[idx].offset == pTopic->nextConsumeOffset) { + totSize += pTopic->buffer[idx].size; if (totSize > sizeLimit) { - void* ptr = realloc(buffer, totSize); + void* ptr = realloc(*pRsp, sizeof(STqConsumeRsp) + totSize); if (ptr == NULL) { - totSize -= topicHandle->buffer[idx].size; - // TODO:memory insufficient + totSize -= pTopic->buffer[idx].size; + terrno = TSDB_CODE_TQ_OUT_OF_MEMORY; // return msgs already copied break; } + *pRsp = ptr; + break; } - *((int64_t*)buffer) = topicHandle->topicId; + *((int64_t*)buffer) = pTopic->topicId; buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); - *((int64_t*)buffer) = topicHandle->buffer[idx].size; + *((int64_t*)buffer) = pTopic->buffer[idx].size; buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); - memcpy(buffer, topicHandle->buffer[idx].content, topicHandle->buffer[idx].size); - buffer = POINTER_SHIFT(buffer, topicHandle->buffer[idx].size); + memcpy(buffer, pTopic->buffer[idx].content, pTopic->buffer[idx].size); + buffer = POINTER_SHIFT(buffer, pTopic->buffer[idx].size); + numOfMsgs++; if (totSize > sizeLimit) { break; } } } - return totSize; + (*pRsp)->bodySize = totSize; + return numOfMsgs; } STqGroup* tqGetGroup(STQ* pTq, int64_t clientId) { return tqHandleGet(pTq->tqMeta, clientId); } @@ -273,7 +296,22 @@ int tqSetCursor(STQ* pTq, STqSetCurReq* pMsg) { return 0; } -int tqConsume(STQ* pTq, STqConsumeReq* pMsg) { +// temporary +int tqProcessCMsg(STQ* pTq, STqConsumeReq* pMsg, STqRspHandle* pRsp) { + int64_t clientId = pMsg->head.clientId; + STqGroup* pGroup = tqGetGroup(pTq, clientId); + if (pGroup == NULL) { + terrno = TSDB_CODE_TQ_GROUP_NOT_SET; + return -1; + } + pGroup->rspHandle.handle = pRsp->handle; + pGroup->rspHandle.ahandle = pRsp->ahandle; + + return 0; +} + +int tqConsume(STQ* pTq, SRpcMsg* pReq, SRpcMsg** pRsp) { + STqConsumeReq *pMsg = pReq->pCont; int64_t clientId = pMsg->head.clientId; STqGroup* pGroup = tqGetGroup(pTq, clientId); if (pGroup == NULL) { @@ -281,17 +319,103 @@ int tqConsume(STQ* pTq, STqConsumeReq* pMsg) { return -1; } - STqConsumeRsp* pRsp = (STqConsumeRsp*)pMsg; - int numOfMsgs = tqFetch(pGroup, (void**)&pRsp->msgs); + SList* topicList = pGroup->topicList; + + int totSize = 0; + int numOfMsgs = 0; + int sizeLimit = 4096; + + + STqConsumeRsp *pCsmRsp = (*pRsp)->pCont; + void* ptr = realloc((*pRsp)->pCont, sizeof(STqConsumeRsp) + sizeLimit); + if (ptr == NULL) { + terrno = TSDB_CODE_TQ_OUT_OF_MEMORY; + return -1; + } + (*pRsp)->pCont = ptr; + + SListIter iter; + tdListInitIter(topicList, &iter, TD_LIST_FORWARD); + + STqMsgContent* buffer = NULL; + SArray* pArray = taosArrayInit(0, sizeof(void*)); + + SListNode *pn; + while((pn = tdListNext(&iter)) != NULL) { + STqTopic* pTopic = *(STqTopic**)pn->data; + int idx = pTopic->floatingCursor % TQ_BUFFER_SIZE; + STqMsgItem* pItem = &pTopic->buffer[idx]; + if (pItem->content != NULL && pItem->offset == pTopic->floatingCursor) { + if(pItem->status == TQ_ITEM_READY) { + //if has data + totSize += pTopic->buffer[idx].size; + if (totSize > sizeLimit) { + void* ptr = realloc((*pRsp)->pCont, sizeof(STqConsumeRsp) + totSize); + if (ptr == NULL) { + totSize -= pTopic->buffer[idx].size; + terrno = TSDB_CODE_TQ_OUT_OF_MEMORY; + // return msgs already copied + break; + } + (*pRsp)->pCont = ptr; + break; + } + *((int64_t*)buffer) = htonll(pTopic->topicId); + buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); + *((int64_t*)buffer) = htonll(pTopic->buffer[idx].size); + buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); + memcpy(buffer, pTopic->buffer[idx].content, pTopic->buffer[idx].size); + buffer = POINTER_SHIFT(buffer, pTopic->buffer[idx].size); + numOfMsgs++; + if (totSize > sizeLimit) { + break; + } + } else if(pItem->status == TQ_ITEM_PROCESS) { + //if not have data but in process + + } else if(pItem->status == TQ_ITEM_EMPTY){ + //if not have data and not in process + int32_t old = atomic_val_compare_exchange_32(&pItem->status, TQ_ITEM_EMPTY, TQ_ITEM_PROCESS); + if(old != TQ_ITEM_EMPTY) { + continue; + } + pItem->offset = pTopic->floatingCursor; + taosArrayPush(pArray, &pItem); + } else { + ASSERT(0); + } + + } + } + + for(int i = 0; i < pArray->size; i++) { + STqMsgItem* pItem = taosArrayGet(pArray, i); + + void* raw; + //read from wal + //get msgType + //if submitblk + pItem->executor->assign(pItem->executor->runtimeEnv, raw); + SSDataBlock* content = pItem->executor->exec(pItem->executor->runtimeEnv); + pItem->content = content; + //if other type, send just put into buffer + pItem->content = raw; + + int32_t old = atomic_val_compare_exchange_32(&pItem->status, TQ_ITEM_PROCESS, TQ_ITEM_READY); + ASSERT(old == TQ_ITEM_PROCESS); + + } + if (numOfMsgs < 0) { return -1; } + if (numOfMsgs == 0) { // most recent data has been fetched // enable timer for blocking wait - // once new data written during wait time - // launch query and response + // once new data written when waiting, launch query and rsp + return -1; } // fetched a num of msgs, rpc response diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index 48eb84b536..c80fb4eed8 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -170,6 +170,7 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { return 0; } +#if 0 int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) { int code; code = walSeekVer(pWal, ver); @@ -207,6 +208,7 @@ int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) { return 0; } -/*int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) {*/ -/*return 0;*/ -/*}*/ +int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) { +return 0; +} +#endif From 82f898753451e8feeacac99af4d0e1a056c55eef Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Wed, 22 Dec 2021 17:45:52 +0800 Subject: [PATCH 02/22] add raftServer code --- contrib/test/craft/raftMain.c | 107 ++++++++++++++++++++++++++++++++ contrib/test/craft/raftServer.c | 20 ++++++ contrib/test/craft/raftServer.h | 42 +++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 contrib/test/craft/raftMain.c create mode 100644 contrib/test/craft/raftServer.c create mode 100644 contrib/test/craft/raftServer.h diff --git a/contrib/test/craft/raftMain.c b/contrib/test/craft/raftMain.c new file mode 100644 index 0000000000..6e9f3b5dfb --- /dev/null +++ b/contrib/test/craft/raftMain.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "raftServer.h" + +#define COMMAND_LEN 128 + +const char *exe_name; + +void *startServerFunc(void *param) { + SRaftServer *pServer = (SRaftServer*)param; + int32_t r = raftServerStart(pServer); + assert(r == 0); + + return NULL; +} + +// Console --------------------------------- +void console(SRaftServer *pRaftServer) { + while (1) { + char cmd_buf[COMMAND_LEN]; + memset(cmd_buf, 0, sizeof(cmd_buf)); + char *ret = fgets(cmd_buf, COMMAND_LEN, stdin); + if (!ret) { + exit(-1); + } + + int pos = strlen(cmd_buf); + if(cmd_buf[pos - 1] == '\n') { + cmd_buf[pos - 1] = '\0'; + } + + if (strncmp(cmd_buf, "", COMMAND_LEN) == 0) { + continue; + } + + printf("cmd_buf: [%s] \n", cmd_buf); + } +} + +void *startConsoleFunc(void *param) { + SRaftServer *pServer = (SRaftServer*)param; + console(pServer); + return NULL; +} + +// Config --------------------------------- +#define DIR_LEN 128 +#define HOST_LEN 128 +typedef struct SRaftServerConfig { + char host[HOST_LEN]; + uint32_t port; + char dir[DIR_LEN]; +} SRaftServerConfig; + +void parseConf(int argc, char **argv, SRaftServerConfig *pConf) { + snprintf(pConf->dir, sizeof(pConf->dir), "%s", argv[1]); + sscanf(argv[2], "%u", &pConf->port); + snprintf(pConf->dir, sizeof(pConf->dir), "%s", argv[3]); +} + +// ----------------------------------------- +void usage() { + printf("\n"); + printf("usage: %s host port dir \n", exe_name); + printf("eg : %s 127.0.0.1 10000 ./data \n", exe_name); + printf("\n"); +} + +int main(int argc, char **argv) { + srand(time(NULL)); + int32_t ret; + + exe_name = argv[0]; + if (argc != 4) { + usage(); + exit(-1); + } + + SRaftServerConfig conf; + parseConf(argc, argv, &conf); + + struct raft_fsm fsm; + initFsm(&fsm); + + SRaftServer raftServer; + ret = raftServerInit(&raftServer, &conf, &fsm); + + pthread_t tidRaftServer; + pthread_create(&tidRaftServer, NULL, startServerFunc, &raftServer); + + pthread_t tidConsole; + pthread_create(&tidConsole, NULL, startConsoleFunc, &raftServer); + + while (1) { + sleep(10); + } + + return 0; +} diff --git a/contrib/test/craft/raftServer.c b/contrib/test/craft/raftServer.c new file mode 100644 index 0000000000..5633b211ac --- /dev/null +++ b/contrib/test/craft/raftServer.c @@ -0,0 +1,20 @@ +#include "raftServer.h" + +int32_t raftServerInit(SRaftServer *pRaftServer, struct SRaftServerConfig *pConf, struct raft_fsm *pFsm) { + + return 0; +} + +int32_t raftServerStart(SRaftServer *pRaftServer) { + +} + + +void raftServerClose(SRaftServer *pRaftServer) { + +} + +int32_t initFsm(struct raft_fsm *fsm) { + + return 0; +} diff --git a/contrib/test/craft/raftServer.h b/contrib/test/craft/raftServer.h new file mode 100644 index 0000000000..9a717260de --- /dev/null +++ b/contrib/test/craft/raftServer.h @@ -0,0 +1,42 @@ +#ifndef TDENGINE_RAFT_SERVER_H +#define TDENGINE_RAFT_SERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "raft.h" +#include "raft/uv.h" + + + +#define DIR_LEN 128 +#define ADDRESS_LEN 128 +typedef struct { + char dir[DIR_LEN]; /* Data dir of UV I/O backend */ + char address[ADDRESS_LEN]; /* Raft instance address */ + raft_id raftId; /* For vote */ + struct raft_fsm *fsm; /* Sample application FSM */ + + struct raft raft; /* Raft instance */ + struct raft_io io; /* UV I/O backend */ + struct uv_loop_s loop; /* UV loop */ + struct raft_uv_transport transport; /* UV I/O backend transport */ +} SRaftServer; + +struct SRaftServerConfig; +int32_t raftServerInit(SRaftServer *pRaftServer, struct SRaftServerConfig *pConf, struct raft_fsm *pFsm); +int32_t raftServerStart(SRaftServer *pRaftServer); +void raftServerClose(SRaftServer *pRaftServer); + + +int initFsm(struct raft_fsm *fsm); + + + + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_RAFT_SERVER_H From 6dc92d703d3c7b3f5e5dc8e4524a01210abcd3cf Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Wed, 22 Dec 2021 20:40:18 +0800 Subject: [PATCH 03/22] add raft code --- contrib/test/craft/clear.sh | 1 + contrib/test/craft/common.h | 17 +++++++++ contrib/test/craft/raftMain.c | 25 ++++++++----- contrib/test/craft/raftServer.c | 65 ++++++++++++++++++++++++++++++++- contrib/test/craft/raftServer.h | 14 ++++--- 5 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 contrib/test/craft/common.h diff --git a/contrib/test/craft/clear.sh b/contrib/test/craft/clear.sh index 6412656d77..398b3088f2 100644 --- a/contrib/test/craft/clear.sh +++ b/contrib/test/craft/clear.sh @@ -1,3 +1,4 @@ #!/bin/bash rm -rf 127.0.0.1* +rm -rf ./data diff --git a/contrib/test/craft/common.h b/contrib/test/craft/common.h new file mode 100644 index 0000000000..670e5fb927 --- /dev/null +++ b/contrib/test/craft/common.h @@ -0,0 +1,17 @@ +#ifndef TDENGINE_COMMON_H +#define TDENGINE_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define COMMAND_LEN 256 +#define DIR_LEN 128 +#define HOST_LEN 128 +#define ADDRESS_LEN (HOST_LEN + 16) + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_COMMON_H diff --git a/contrib/test/craft/raftMain.c b/contrib/test/craft/raftMain.c index 6e9f3b5dfb..9d00cb4f70 100644 --- a/contrib/test/craft/raftMain.c +++ b/contrib/test/craft/raftMain.c @@ -1,6 +1,4 @@ #include -#include -#include #include #include #include @@ -8,9 +6,10 @@ #include #include #include +#include +#include #include "raftServer.h" - -#define COMMAND_LEN 128 +#include "common.h" const char *exe_name; @@ -52,8 +51,6 @@ void *startConsoleFunc(void *param) { } // Config --------------------------------- -#define DIR_LEN 128 -#define HOST_LEN 128 typedef struct SRaftServerConfig { char host[HOST_LEN]; uint32_t port; @@ -61,16 +58,22 @@ typedef struct SRaftServerConfig { } SRaftServerConfig; void parseConf(int argc, char **argv, SRaftServerConfig *pConf) { - snprintf(pConf->dir, sizeof(pConf->dir), "%s", argv[1]); + snprintf(pConf->host, sizeof(pConf->host), "%s", argv[1]); sscanf(argv[2], "%u", &pConf->port); snprintf(pConf->dir, sizeof(pConf->dir), "%s", argv[3]); } +void printConf(SRaftServerConfig *pConf) { + printf("conf: %s:%u %s \n", pConf->host, pConf->port, pConf->dir); +} + // ----------------------------------------- void usage() { printf("\n"); printf("usage: %s host port dir \n", exe_name); - printf("eg : %s 127.0.0.1 10000 ./data \n", exe_name); + printf("\n"); + printf("eg: \n"); + printf("%s 127.0.0.1 10000 ./data \n", exe_name); printf("\n"); } @@ -86,12 +89,14 @@ int main(int argc, char **argv) { SRaftServerConfig conf; parseConf(argc, argv, &conf); - + printConf(&conf); + struct raft_fsm fsm; initFsm(&fsm); SRaftServer raftServer; - ret = raftServerInit(&raftServer, &conf, &fsm); + ret = raftServerInit(&raftServer, conf.host, conf.port, conf.dir, &fsm); + assert(ret == 0); pthread_t tidRaftServer; pthread_create(&tidRaftServer, NULL, startServerFunc, &raftServer); diff --git a/contrib/test/craft/raftServer.c b/contrib/test/craft/raftServer.c index 5633b211ac..4a4d6cb7a3 100644 --- a/contrib/test/craft/raftServer.c +++ b/contrib/test/craft/raftServer.c @@ -1,12 +1,65 @@ +#include +#include "common.h" #include "raftServer.h" -int32_t raftServerInit(SRaftServer *pRaftServer, struct SRaftServerConfig *pConf, struct raft_fsm *pFsm) { +uint64_t raftId(const char *host, uint32_t port) { + uint32_t host_uint32 = (uint32_t)inet_addr(host); + assert(host_uint32 != (uint32_t)-1); + uint64_t code = ((uint64_t)host_uint32) << 32 | port; + return code; +} + +int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port, const char *dir, struct raft_fsm *pFsm) { + int ret; + + char cmd_buf[COMMAND_LEN]; + snprintf(cmd_buf, sizeof(cmd_buf), "mkdir -p %s", dir); + system(cmd_buf); + + snprintf(pRaftServer->host, sizeof(pRaftServer->host), "%s", host); + pRaftServer->port = port; + snprintf(pRaftServer->address, sizeof(pRaftServer->address), "%s:%u", host, port); + strncpy(pRaftServer->dir, dir, sizeof(pRaftServer->dir)); + + pRaftServer->raftId = raftId(pRaftServer->host, pRaftServer->port); + pRaftServer->fsm = pFsm; + + ret = uv_loop_init(&pRaftServer->loop); + if (!ret) { + fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); + } + + ret = raft_uv_tcp_init(&pRaftServer->transport, &pRaftServer->loop); + if (!ret) { + fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); + } + + ret = raft_uv_init(&pRaftServer->io, &pRaftServer->loop, dir, &pRaftServer->transport); + if (!ret) { + fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); + } + + ret = raft_init(&pRaftServer->raft, &pRaftServer->io, pRaftServer->fsm, pRaftServer->raftId, pRaftServer->address); + if (!ret) { + fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); + } + + struct raft_configuration conf; + raft_configuration_init(&conf); + raft_configuration_add(&conf, pRaftServer->raftId, pRaftServer->address, RAFT_VOTER); + raft_bootstrap(&pRaftServer->raft, &conf); return 0; } int32_t raftServerStart(SRaftServer *pRaftServer) { + int ret; + ret = raft_start(&pRaftServer->raft); + if (!ret) { + fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); + } + uv_run(&pRaftServer->loop, UV_RUN_DEFAULT); } @@ -14,7 +67,15 @@ void raftServerClose(SRaftServer *pRaftServer) { } -int32_t initFsm(struct raft_fsm *fsm) { +int fsmApplyCb(struct raft_fsm *pFsm, const struct raft_buffer *buf, void **result) { + char *msg = (char*)buf->base; + printf("%s \n", msg); + + return 0; +} + +int32_t initFsm(struct raft_fsm *fsm) { + fsm->apply = fsmApplyCb; return 0; } diff --git a/contrib/test/craft/raftServer.h b/contrib/test/craft/raftServer.h index 9a717260de..44cfa54dfe 100644 --- a/contrib/test/craft/raftServer.h +++ b/contrib/test/craft/raftServer.h @@ -5,15 +5,20 @@ extern "C" { #endif +#include +#include +#include +#include #include "raft.h" #include "raft/uv.h" - - #define DIR_LEN 128 -#define ADDRESS_LEN 128 +#define HOST_LEN 128 +#define ADDRESS_LEN (HOST_LEN + 16) typedef struct { char dir[DIR_LEN]; /* Data dir of UV I/O backend */ + char host[HOST_LEN]; + uint32_t port; char address[ADDRESS_LEN]; /* Raft instance address */ raft_id raftId; /* For vote */ struct raft_fsm *fsm; /* Sample application FSM */ @@ -24,8 +29,7 @@ typedef struct { struct raft_uv_transport transport; /* UV I/O backend transport */ } SRaftServer; -struct SRaftServerConfig; -int32_t raftServerInit(SRaftServer *pRaftServer, struct SRaftServerConfig *pConf, struct raft_fsm *pFsm); +int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port, const char *dir, struct raft_fsm *pFsm); int32_t raftServerStart(SRaftServer *pRaftServer); void raftServerClose(SRaftServer *pRaftServer); From 766039a7a961d5c53a59789ee2041d9798484933 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 10:30:51 +0800 Subject: [PATCH 04/22] TD-10431 minor changes --- source/dnode/mgmt/impl/test/CMakeLists.txt | 2 +- .../dnode/mgmt/impl/test/mnode/CMakeLists.txt | 11 + source/dnode/mgmt/impl/test/mnode/mnode.cpp | 260 ++++++++++++++++++ source/dnode/mnode/impl/src/mndMnode.c | 137 +++++---- 4 files changed, 334 insertions(+), 76 deletions(-) create mode 100644 source/dnode/mgmt/impl/test/mnode/CMakeLists.txt create mode 100644 source/dnode/mgmt/impl/test/mnode/mnode.cpp diff --git a/source/dnode/mgmt/impl/test/CMakeLists.txt b/source/dnode/mgmt/impl/test/CMakeLists.txt index a29926c802..dcce270d7d 100644 --- a/source/dnode/mgmt/impl/test/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(cluster) add_subdirectory(db) add_subdirectory(dnode) # add_subdirectory(func) -# add_subdirectory(mnode) +add_subdirectory(mnode) add_subdirectory(profile) add_subdirectory(show) add_subdirectory(stb) diff --git a/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt new file mode 100644 index 0000000000..d6b3b16fb6 --- /dev/null +++ b/source/dnode/mgmt/impl/test/mnode/CMakeLists.txt @@ -0,0 +1,11 @@ +aux_source_directory(. MTEST_SRC) +add_executable(dnode_test_mnode ${MTEST_SRC}) +target_link_libraries( + dnode_test_mnode + PUBLIC sut +) + +add_test( + NAME dnode_test_mnode + COMMAND dnode_test_mnode +) diff --git a/source/dnode/mgmt/impl/test/mnode/mnode.cpp b/source/dnode/mgmt/impl/test/mnode/mnode.cpp new file mode 100644 index 0000000000..1f5a63ae8e --- /dev/null +++ b/source/dnode/mgmt/impl/test/mnode/mnode.cpp @@ -0,0 +1,260 @@ +/** + * @file dnode.cpp + * @author slguan (slguan@taosdata.com) + * @brief DNODE module dnode-msg tests + * @version 0.1 + * @date 2021-12-15 + * + * @copyright Copyright (c) 2021 + * + */ + +#include "base.h" + +class DndTestMnode : public ::testing::Test { + public: + void SetUp() override {} + void TearDown() override {} + + public: + static void SetUpTestSuite() { + test.Init("/tmp/dnode_test_mnode1", 9061); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9061"; + + server2.Start("/tmp/dnode_test_mnode2", fqdn, 9062, firstEp); + server3.Start("/tmp/dnode_test_mnode3", fqdn, 9063, firstEp); + server4.Start("/tmp/dnode_test_mnode4", fqdn, 9064, firstEp); + server5.Start("/tmp/dnode_test_mnode5", fqdn, 9065, firstEp); + taosMsleep(300); + } + + static void TearDownTestSuite() { + server2.Stop(); + server3.Stop(); + server4.Stop(); + server5.Stop(); + test.Cleanup(); + } + + static Testbase test; + static TestServer server2; + static TestServer server3; + static TestServer server4; + static TestServer server5; +}; + +Testbase DndTestMnode::test; +TestServer DndTestMnode::server2; +TestServer DndTestMnode::server3; +TestServer DndTestMnode::server4; +TestServer DndTestMnode::server5; + +TEST_F(DndTestMnode, 01_ShowDnode) { + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + + CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); + CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vnodes"); + CHECK_SCHEMA(3, TSDB_DATA_TYPE_SMALLINT, 2, "max_vnodes"); + CHECK_SCHEMA(4, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "status"); + CHECK_SCHEMA(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); + CHECK_SCHEMA(6, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "offline_reason"); + + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(1); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckBinary("", 24); +} + +#if 0 +TEST_F(DndTestMnode, 02_ConfigDnode) { + int32_t contLen = sizeof(SCfgDnodeMsg); + + SCfgDnodeMsg* pReq = (SCfgDnodeMsg*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); + strcpy(pReq->config, "ddebugflag 131"); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CONFIG_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); +} + +TEST_F(DndTestMnode, 03_Create_Drop_Restart_Dnode) { + { + int32_t contLen = sizeof(SCreateDnodeMsg); + + SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); + strcpy(pReq->ep, "localhost:9062"); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + taosMsleep(1300); + + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckBinary("localhost:9062", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(1); + CheckInt16(1); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + + { + int32_t contLen = sizeof(SDropDnodeMsg); + + SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(1); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckBinary("", 24); + + { + int32_t contLen = sizeof(SCreateDnodeMsg); + + SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); + strcpy(pReq->ep, "localhost:9063"); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + { + int32_t contLen = sizeof(SCreateDnodeMsg); + + SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); + strcpy(pReq->ep, "localhost:9064"); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + { + int32_t contLen = sizeof(SCreateDnodeMsg); + + SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); + strcpy(pReq->ep, "localhost:9065"); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + taosMsleep(1300); + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 4); + + CheckInt16(1); + CheckInt16(3); + CheckInt16(4); + CheckInt16(5); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckBinary("localhost:9063", TSDB_EP_LEN); + CheckBinary("localhost:9064", TSDB_EP_LEN); + CheckBinary("localhost:9065", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + + // restart + uInfo("stop all server"); + test.Restart(); + server2.Restart(); + server3.Restart(); + server4.Restart(); + server5.Restart(); + + taosMsleep(1300); + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + CHECK_META("show dnodes", 7); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 4); + + CheckInt16(1); + CheckInt16(3); + CheckInt16(4); + CheckInt16(5); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckBinary("localhost:9063", TSDB_EP_LEN); + CheckBinary("localhost:9064", TSDB_EP_LEN); + CheckBinary("localhost:9065", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); +} + +#endif \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 869b6e538b..111ed60632 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -23,13 +23,13 @@ #define TSDB_MNODE_RESERVE_SIZE 64 static int32_t mndCreateDefaultMnode(SMnode *pMnode); -static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pMnodeObj); +static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj); static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw); -static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pMnodeObj); -static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pMnodeObj); +static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj); +static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj); static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj *pNewMnode); -static int32_t mndProcessCreateMnodeMsg(SMnodeMsg *pMsg); -static int32_t mndProcessDropMnodeMsg(SMnodeMsg *pMsg); +static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg); +static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg); static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg); static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg); static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); @@ -46,8 +46,8 @@ int32_t mndInitMnode(SMnode *pMnode) { .updateFp = (SdbUpdateFp)mndMnodeActionUpdate, .deleteFp = (SdbDeleteFp)mndMnodeActionDelete}; - mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_MNODE, mndProcessCreateMnodeMsg); - mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_MNODE, mndProcessDropMnodeMsg); + mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_MNODE, mndProcessCreateMnodeReq); + mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_MNODE, mndProcessDropMnodeReq); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_MNODE_IN_RSP, mndProcessCreateMnodeRsp); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_MNODE_IN_RSP, mndProcessDropMnodeRsp); @@ -69,9 +69,9 @@ static SMnodeObj *mndAcquireMnode(SMnode *pMnode, int32_t mnodeId) { return pObj; } -static void mndReleaseMnode(SMnode *pMnode, SMnodeObj *pMnodeObj) { +static void mndReleaseMnode(SMnode *pMnode, SMnodeObj *pObj) { SSdb *pSdb = pMnode->pSdb; - sdbRelease(pSdb, pMnodeObj); + sdbRelease(pSdb, pObj); } char *mndGetRoleStr(int32_t showType) { @@ -101,14 +101,14 @@ static int32_t mndCreateDefaultMnode(SMnode *pMnode) { return sdbWrite(pMnode->pSdb, pRaw); } -static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pMnodeObj) { +static SSdbRaw *mndMnodeActionEncode(SMnodeObj *pObj) { SSdbRaw *pRaw = sdbAllocRaw(SDB_MNODE, TSDB_MNODE_VER_NUMBER, sizeof(SMnodeObj) + TSDB_MNODE_RESERVE_SIZE); if (pRaw == NULL) return NULL; int32_t dataPos = 0; - SDB_SET_INT32(pRaw, dataPos, pMnodeObj->id); - SDB_SET_INT64(pRaw, dataPos, pMnodeObj->createdTime) - SDB_SET_INT64(pRaw, dataPos, pMnodeObj->updateTime) + SDB_SET_INT32(pRaw, dataPos, pObj->id); + SDB_SET_INT64(pRaw, dataPos, pObj->createdTime) + SDB_SET_INT64(pRaw, dataPos, pObj->updateTime) SDB_SET_RESERVE(pRaw, dataPos, TSDB_MNODE_RESERVE_SIZE) return pRaw; @@ -125,42 +125,38 @@ static SSdbRow *mndMnodeActionDecode(SSdbRaw *pRaw) { } SSdbRow *pRow = sdbAllocRow(sizeof(SMnodeObj)); - SMnodeObj *pMnodeObj = sdbGetRowObj(pRow); - if (pMnodeObj == NULL) return NULL; + SMnodeObj *pObj = sdbGetRowObj(pRow); + if (pObj == NULL) return NULL; int32_t dataPos = 0; - SDB_GET_INT32(pRaw, pRow, dataPos, &pMnodeObj->id) - SDB_GET_INT64(pRaw, pRow, dataPos, &pMnodeObj->createdTime) - SDB_GET_INT64(pRaw, pRow, dataPos, &pMnodeObj->updateTime) + SDB_GET_INT32(pRaw, pRow, dataPos, &pObj->id) + SDB_GET_INT64(pRaw, pRow, dataPos, &pObj->createdTime) + SDB_GET_INT64(pRaw, pRow, dataPos, &pObj->updateTime) SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_MNODE_RESERVE_SIZE) return pRow; } -static void mnodeResetMnode(SMnodeObj *pMnodeObj) { - pMnodeObj->role = TAOS_SYNC_STATE_FOLLOWER; - pMnodeObj->roleTerm = 0; - pMnodeObj->roleTime = 0; -} +static void mnodeResetMnode(SMnodeObj *pObj) { pObj->role = TAOS_SYNC_STATE_FOLLOWER; } -static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pMnodeObj) { - mTrace("mnode:%d, perform insert action", pMnodeObj->id); - pMnodeObj->pDnode = sdbAcquire(pSdb, SDB_DNODE, &pMnodeObj->id); - if (pMnodeObj->pDnode == NULL) { +static int32_t mndMnodeActionInsert(SSdb *pSdb, SMnodeObj *pObj) { + mTrace("mnode:%d, perform insert action", pObj->id); + pObj->pDnode = sdbAcquire(pSdb, SDB_DNODE, &pObj->id); + if (pObj->pDnode == NULL) { terrno = TSDB_CODE_MND_DNODE_NOT_EXIST; - mError("mnode:%d, failed to perform insert action since %s", pMnodeObj->id, terrstr()); + mError("mnode:%d, failed to perform insert action since %s", pObj->id, terrstr()); return -1; } - mnodeResetMnode(pMnodeObj); + mnodeResetMnode(pObj); return 0; } -static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pMnodeObj) { - mTrace("mnode:%d, perform delete action", pMnodeObj->id); - if (pMnodeObj->pDnode != NULL) { - sdbRelease(pSdb, pMnodeObj->pDnode); - pMnodeObj->pDnode = NULL; +static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pObj) { + mTrace("mnode:%d, perform delete action", pObj->id); + if (pObj->pDnode != NULL) { + sdbRelease(pSdb, pObj->pDnode); + pObj->pDnode = NULL; } return 0; @@ -168,8 +164,6 @@ static int32_t mndMnodeActionDelete(SSdb *pSdb, SMnodeObj *pMnodeObj) { static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj *pNewMnode) { mTrace("mnode:%d, perform update action", pOldMnode->id); - pOldMnode->id = pNewMnode->id; - pOldMnode->createdTime = pNewMnode->createdTime; pOldMnode->updateTime = pNewMnode->updateTime; return 0; } @@ -177,12 +171,12 @@ static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj bool mndIsMnode(SMnode *pMnode, int32_t dnodeId) { SSdb *pSdb = pMnode->pSdb; - SMnodeObj *pMnodeObj = sdbAcquire(pSdb, SDB_MNODE, &dnodeId); - if (pMnodeObj == NULL) { + SMnodeObj *pObj = sdbAcquire(pSdb, SDB_MNODE, &dnodeId); + if (pObj == NULL) { return false; } - sdbRelease(pSdb, pMnodeObj); + sdbRelease(pSdb, pObj); return true; } @@ -193,14 +187,14 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { void *pIter = NULL; while (1) { - SMnodeObj *pMnodeObj = NULL; - pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMnodeObj); + SMnodeObj *pObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj); if (pIter == NULL) break; - if (pMnodeObj->pDnode == NULL) break; + if (pObj->pDnode == NULL) break; - pEpSet->port[pEpSet->numOfEps] = htons(pMnodeObj->pDnode->port); - tstrncpy(pEpSet->fqdn[pEpSet->numOfEps], pMnodeObj->pDnode->fqdn, TSDB_FQDN_LEN); - if (pMnodeObj->role == TAOS_SYNC_STATE_LEADER) { + pEpSet->port[pEpSet->numOfEps] = htons(pObj->pDnode->port); + memcpy(pEpSet->fqdn[pEpSet->numOfEps], pObj->pDnode->fqdn, TSDB_FQDN_LEN); + if (pObj->role == TAOS_SYNC_STATE_LEADER) { pEpSet->inUse = pEpSet->numOfEps; } @@ -210,7 +204,7 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg *pCreate) { SMnodeObj mnodeObj = {0}; - mnodeObj.id = 1; // todo + mnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_MNODE); mnodeObj.createdTime = taosGetTimestampMs(); mnodeObj.updateTime = mnodeObj.createdTime; @@ -255,7 +249,7 @@ static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg * return 0; } -static int32_t mndProcessCreateMnodeMsg(SMnodeMsg *pMsg) { +static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SCreateMnodeMsg *pCreate = pMsg->rpcMsg.pCont; @@ -271,9 +265,9 @@ static int32_t mndProcessCreateMnodeMsg(SMnodeMsg *pMsg) { } mndReleaseDnode(pMnode, pDnode); - SMnodeObj *pMnodeObj = mndAcquireMnode(pMnode, pCreate->dnodeId); - if (pMnodeObj != NULL) { - mError("mnode:%d, mnode already exist", pMnodeObj->id); + SMnodeObj *pObj = mndAcquireMnode(pMnode, pCreate->dnodeId); + if (pObj != NULL) { + mError("mnode:%d, mnode already exist", pObj->id); terrno = TSDB_CODE_MND_MNODE_ALREADY_EXIST; return -1; } @@ -288,15 +282,15 @@ static int32_t mndProcessCreateMnodeMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pMnodeObj) { +static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pObj) { STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); if (pTrans == NULL) { - mError("mnode:%d, failed to drop since %s", pMnodeObj->id, terrstr()); + mError("mnode:%d, failed to drop since %s", pObj->id, terrstr()); return -1; } - mDebug("trans:%d, used to drop user:%d", pTrans->id, pMnodeObj->id); + mDebug("trans:%d, used to drop user:%d", pTrans->id, pObj->id); - SSdbRaw *pRedoRaw = mndMnodeActionEncode(pMnodeObj); + SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); @@ -304,7 +298,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pMnodeOb } sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING); - SSdbRaw *pUndoRaw = mndMnodeActionEncode(pMnodeObj); + SSdbRaw *pUndoRaw = mndMnodeActionEncode(pObj); if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); @@ -312,7 +306,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pMnodeOb } sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - SSdbRaw *pCommitRaw = mndMnodeActionEncode(pMnodeObj); + SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj); if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); @@ -330,7 +324,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pMnodeOb return 0; } -static int32_t mndProcessDropMnodeMsg(SMnodeMsg *pMsg) { +static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SDropMnodeMsg *pDrop = pMsg->rpcMsg.pCont; pDrop->dnodeId = htonl(pDrop->dnodeId); @@ -343,14 +337,14 @@ static int32_t mndProcessDropMnodeMsg(SMnodeMsg *pMsg) { return -1; } - SMnodeObj *pMnodeObj = mndAcquireMnode(pMnode, pDrop->dnodeId); - if (pMnodeObj == NULL) { + SMnodeObj *pObj = mndAcquireMnode(pMnode, pDrop->dnodeId); + if (pObj == NULL) { mError("mnode:%d, not exist", pDrop->dnodeId); terrno = TSDB_CODE_MND_DNODE_NOT_EXIST; return -1; } - int32_t code = mndDropMnode(pMnode, pMsg, pMnodeObj); + int32_t code = mndDropMnode(pMnode, pMsg, pObj); if (code != 0) { mError("mnode:%d, failed to drop since %s", pMnode->dnodeId, terrstr()); @@ -422,46 +416,39 @@ static int32_t mndRetrieveMnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i SSdb *pSdb = pMnode->pSdb; int32_t numOfRows = 0; int32_t cols = 0; - SMnodeObj *pMnodeObj = NULL; + SMnodeObj *pObj = NULL; char *pWrite; while (numOfRows < rows) { - pShow->pIter = sdbFetch(pSdb, SDB_MNODE, pShow->pIter, (void **)&pMnodeObj); + pShow->pIter = sdbFetch(pSdb, SDB_MNODE, pShow->pIter, (void **)&pObj); if (pShow->pIter == NULL) break; cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pMnodeObj->id; + *(int16_t *)pWrite = pObj->id; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - - SDnodeObj *pDnode = mndAcquireDnode(pMnode, pMnodeObj->id); - if (pDnode != NULL) { - STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->ep, pShow->bytes[cols]); - } else { - STR_WITH_MAXSIZE_TO_VARSTR(pWrite, "invalid ep", pShow->bytes[cols]); - } - mndReleaseDnode(pMnode, pDnode); + STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pObj->pDnode->ep, pShow->bytes[cols]); cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - char *roles = mndGetRoleStr(pMnodeObj->role); + char *roles = mndGetRoleStr(pObj->role); STR_WITH_MAXSIZE_TO_VARSTR(pWrite, roles, pShow->bytes[cols]); cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int64_t *)pWrite = pMnodeObj->roleTime; + *(int64_t *)pWrite = pObj->roleTime; cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int64_t *)pWrite = pMnodeObj->createdTime; + *(int64_t *)pWrite = pObj->createdTime; cols++; numOfRows++; - sdbRelease(pSdb, pMnodeObj); + sdbRelease(pSdb, pObj); } mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); From ad0995c2070bfd9945a94c67b95dbf1da256ede6 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 12:09:37 +0800 Subject: [PATCH 05/22] TD-10431 refact create mnode msg --- include/common/taosmsg.h | 3 + source/dnode/mnode/impl/src/mndMnode.c | 219 +++++++++++++++++++------ 2 files changed, 172 insertions(+), 50 deletions(-) diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index 2a4512ef48..5b82e807a1 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -907,6 +907,7 @@ typedef struct { typedef struct { int32_t dnodeId; + int32_t reserve[8]; } SCreateMnodeMsg, SDropMnodeMsg; typedef struct { @@ -914,10 +915,12 @@ typedef struct { int8_t align[3]; int8_t replica; SReplica replicas[TSDB_MAX_REPLICA]; + int32_t reserve[8]; } SCreateMnodeInMsg, SAlterMnodeInMsg; typedef struct { int32_t dnodeId; + int32_t reserve[8]; } SDropMnodeInMsg; typedef struct { diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 111ed60632..9120b7fe27 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -202,51 +202,137 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { } } +static SCreateMnodeInMsg *mndBuildCreateMnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SMnodeObj *pObj) { + SCreateMnodeInMsg *pCreate = calloc(1, sizeof(SCreateMnodeInMsg)); + if (pCreate == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + + pCreate->dnodeId = htonl(pObj->id); + + int32_t numOfReplicas = 0; + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + + while (numOfReplicas < TSDB_MAX_REPLICA - 1) { + SMnodeObj *pObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj); + if (pIter == NULL) break; + if (pObj->pDnode == NULL) break; + + SReplica *pReplica = &pCreate->replicas[numOfReplicas]; + pReplica->id = htonl(pObj->id); + pReplica->port = htons(pObj->pDnode->port); + memcpy(pReplica->fqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN); + numOfReplicas++; + } + + numOfReplicas++; + SReplica *pReplica = &pCreate->replicas[numOfReplicas]; + pReplica->id = htonl(pObj->id); + pReplica->port = htons(pDnode->port); + memcpy(pReplica->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + + return pCreate; +} + +static SDropMnodeInMsg *mndBuildDropMnodeMsg(SMnode *pMnode, SMnodeObj *pObj) { + SDropMnodeInMsg *pDrop = calloc(1, sizeof(SDropMnodeInMsg)); + if (pDrop == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + + pDrop->dnodeId = htonl(pObj->id); + return pDrop; +} + +static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); + if (pRedoRaw == NULL) return -1; + if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1; + if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING) != 0) return -1; + return 0; +} + +static int32_t mndSetCreateMnodeUndoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pUndoRaw = mndMnodeActionEncode(pObj); + if (pUndoRaw == NULL) return -1; + if (mndTransAppendUndolog(pTrans, pUndoRaw) != 0) return -1; + if (sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED) != 0) return -1; + return 0; +} + +static int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj); + if (pCommitRaw == NULL) return -1; + if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1; + if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY) != 0) return -1; + return 0; +} + +static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + STransAction action = {0}; + + SDnodeObj *pDnode = mndAcquireDnode(pMnode, pObj->id); + if (pDnode == NULL) return -1; + action.epSet = mndGetDnodeEpset(pDnode); + mndReleaseDnode(pMnode, pDnode); + + SCreateMnodeInMsg *pMsg = mndBuildCreateMnodeMsg(pMnode, pDnode, pObj); + if (pMsg == NULL) return -1; + + action.pCont = pMsg; + action.contLen = sizeof(SCreateMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_CREATE_MNODE_IN; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + return -1; + } + + return 0; +} + static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg *pCreate) { SMnodeObj mnodeObj = {0}; mnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_MNODE); mnodeObj.createdTime = taosGetTimestampMs(); mnodeObj.updateTime = mnodeObj.createdTime; - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); + int32_t code = -1; + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, pMsg->rpcMsg.handle); if (pTrans == NULL) { - mError("dnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); - return -1; + mError("mnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); + goto CREATE_MNODE_OVER; } - mDebug("trans:%d, used to create dnode:%d", pTrans->id, pCreate->dnodeId); + mDebug("trans:%d, used to create mnode:%d", pTrans->id, pCreate->dnodeId); - SSdbRaw *pRedoRaw = mndMnodeActionEncode(&mnodeObj); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, &mnodeObj) != 0) { + mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); + goto CREATE_MNODE_OVER; } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING); - SSdbRaw *pUndoRaw = mndMnodeActionEncode(&mnodeObj); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, &mnodeObj) != 0) { + mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); + goto CREATE_MNODE_OVER; } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED); - SSdbRaw *pCommitRaw = mndMnodeActionEncode(&mnodeObj); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + if (mndSetCreateMnodeRedoActions(pMnode, pTrans, &mnodeObj) != 0) { + mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); + goto CREATE_MNODE_OVER; } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + goto CREATE_MNODE_OVER; } + code = 0; + +CREATE_MNODE_OVER: mndTransDrop(pTrans); - return 0; + return code; } static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { @@ -282,46 +368,79 @@ static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } +static int32_t mndSetDropMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); + if (pRedoRaw == NULL) return -1; + if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1; + if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING) != 0) return -1; + return 0; +} + +static int32_t mndSetDropMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj); + if (pCommitRaw == NULL) return -1; + if (mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) return -1; + if (sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED) != 0) return -1; + return 0; +} + +static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { + STransAction action = {0}; + + SDnodeObj *pDnode = mndAcquireDnode(pMnode, pObj->id); + if (pDnode == NULL) return -1; + action.epSet = mndGetDnodeEpset(pDnode); + mndReleaseDnode(pMnode, pDnode); + + SDropMnodeInMsg *pMsg = mndBuildDropMnodeMsg(pMnode, pObj); + if (pMsg == NULL) return -1; + + action.pCont = pMsg; + action.contLen = sizeof(SDropMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_CREATE_MNODE_IN; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + return -1; + } + + return 0; +} + static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pObj) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); + int32_t code = -1; + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, pMsg->rpcMsg.handle); if (pTrans == NULL) { mError("mnode:%d, failed to drop since %s", pObj->id, terrstr()); - return -1; + goto DROP_MNODE_OVER; } - mDebug("trans:%d, used to drop user:%d", pTrans->id, pObj->id); - SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING); + mDebug("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id); - SSdbRaw *pUndoRaw = mndMnodeActionEncode(pObj); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, pObj) != 0) { + mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); + goto DROP_MNODE_OVER; } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - SSdbRaw *pCommitRaw = mndMnodeActionEncode(pObj); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, pObj) != 0) { + mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); + goto DROP_MNODE_OVER; + } + + if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pObj) != 0) { + mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); + goto DROP_MNODE_OVER; } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; + goto DROP_MNODE_OVER; } + code = 0; + +DROP_MNODE_OVER: mndTransDrop(pTrans); - return 0; + return code; } static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { From 4b25449576ac0d0c182e5f1b57ba2238f9233b5e Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 23 Dec 2021 13:25:55 +0800 Subject: [PATCH 06/22] tq consume refactor --- include/dnode/vnode/tq/tq.h | 65 +++++++++++++++++----------- source/dnode/vnode/tq/src/tq.c | 78 ++++++++++++++++++++-------------- 2 files changed, 87 insertions(+), 56 deletions(-) diff --git a/include/dnode/vnode/tq/tq.h b/include/dnode/vnode/tq/tq.h index 5eeaaa1011..f5d5cc9a16 100644 --- a/include/dnode/vnode/tq/tq.h +++ b/include/dnode/vnode/tq/tq.h @@ -23,6 +23,7 @@ #include "taosmsg.h" #include "tlist.h" #include "trpc.h" +#include "ttimer.h" #include "tutil.h" #ifdef __cplusplus @@ -103,7 +104,7 @@ typedef struct STqTopicVhandle { typedef struct STqExec { void* runtimeEnv; SSDataBlock* (*exec)(void* runtimeEnv); - void* (*assign)(void* runtimeEnv, SSubmitBlk* inputData); + void* (*assign)(void* runtimeEnv, void* inputData); void (*clear)(void* runtimeEnv); char* (*serialize)(struct STqExec*); struct STqExec* (*deserialize)(char*); @@ -114,33 +115,33 @@ typedef struct STqRspHandle { void* ahandle; } STqRspHandle; -typedef enum { - TQ_ITEM_READY, - TQ_ITEM_PROCESS, - TQ_ITEM_EMPTY -} STqItemStatus; +typedef enum { TQ_ITEM_READY, TQ_ITEM_PROCESS, TQ_ITEM_EMPTY } STqItemStatus; + +typedef struct STqTopic STqTopic; typedef struct STqBufferItem { int64_t offset; // executors are identical but not concurrent // so there must be a copy in each item - STqExec* executor; - int32_t status; - int64_t size; - void* content; + STqExec* executor; + int32_t status; + int64_t size; + void* content; + STqTopic* pTopic; } STqMsgItem; -typedef struct STqTopic { +struct STqTopic { // char* topic; //c style, end with '\0' // int64_t cgId; // void* ahandle; + // int32_t head; + // int32_t tail; int64_t nextConsumeOffset; int64_t floatingCursor; int64_t topicId; - int32_t head; - int32_t tail; + void* logReader; STqMsgItem buffer[TQ_BUFFER_SIZE]; -} STqTopic; +}; typedef struct STqListHandle { STqTopic topic; @@ -148,11 +149,11 @@ typedef struct STqListHandle { } STqList; typedef struct STqGroup { - int64_t clientId; - int64_t cgId; - void* ahandle; - int32_t topicNum; - //STqList* head; + int64_t clientId; + int64_t cgId; + void* ahandle; + int32_t topicNum; + STqList* head; SList* topicList; // SList STqRspHandle rspHandle; } STqGroup; @@ -162,20 +163,23 @@ typedef struct STqQueryMsg { struct STqQueryMsg* next; } STqQueryMsg; -typedef struct STqLogReader { +typedef struct STqLogHandle { void* logHandle; - int32_t (*logRead)(void* logHandle, void** data, int64_t ver); + void* (*openLogReader)(void* logHandle); + void (*closeLogReader)(void* logReader); + int32_t (*logRead)(void* logReader, void** data, int64_t ver); + int64_t (*logGetFirstVer)(void* logHandle); int64_t (*logGetSnapshotVer)(void* logHandle); int64_t (*logGetLastVer)(void* logHandle); -} STqLogReader; +} STqLogHandle; typedef struct STqCfg { // TODO } STqCfg; typedef struct STqMemRef { - SMemAllocatorFactory* pAlloctorFactory; + SMemAllocatorFactory* pAllocatorFactory; SMemAllocator* pAllocator; } STqMemRef; @@ -265,13 +269,24 @@ typedef struct STQ { // the handle of meta kvstore char* path; STqCfg* tqConfig; - STqLogReader* tqLogReader; + STqLogHandle* tqLogHandle; STqMemRef tqMemRef; STqMetaStore* tqMeta; } STQ; +typedef struct STqMgmt { + int8_t inited; + tmr_h timer; +} STqMgmt; + +static STqMgmt tqMgmt; + +// init once +int tqInit(); +void tqCleanUp(); + // open in each vnode -STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemAllocatorFactory* allocFac); +STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogHandle* tqLogHandle, SMemAllocatorFactory* allocFac); void tqClose(STQ*); // void* will be replace by a msg type diff --git a/source/dnode/vnode/tq/src/tq.c b/source/dnode/vnode/tq/src/tq.c index 972740183d..9e5aaf61fc 100644 --- a/source/dnode/vnode/tq/src/tq.c +++ b/source/dnode/vnode/tq/src/tq.c @@ -37,7 +37,22 @@ void* tqSerializeItem(STqMsgItem* pItem, void* ptr); const void* tqDeserializeTopic(const void* pBytes, STqTopic* pTopic); const void* tqDeserializeItem(const void* pBytes, STqMsgItem* pItem); -STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemAllocatorFactory* allocFac) { +int tqInit() { + int8_t old = atomic_val_compare_exchange_8(&tqMgmt.inited, 0, 1); + if(old == 1) return 0; + + tqMgmt.timer = taosTmrInit(0, 0, 0, "TQ"); + return 0; +} + +void tqCleanUp() { + int8_t old = atomic_val_compare_exchange_8(&tqMgmt.inited, 1, 0); + if(old == 0) return; + taosTmrStop(tqMgmt.timer); + taosTmrCleanUp(tqMgmt.timer); +} + +STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogHandle* tqLogHandle, SMemAllocatorFactory* allocFac) { STQ* pTq = malloc(sizeof(STQ)); if (pTq == NULL) { terrno = TSDB_CODE_TQ_OUT_OF_MEMORY; @@ -45,8 +60,8 @@ STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemA } pTq->path = strdup(path); pTq->tqConfig = tqConfig; - pTq->tqLogReader = tqLogReader; - pTq->tqMemRef.pAlloctorFactory = allocFac; + pTq->tqLogHandle = tqLogHandle; + pTq->tqMemRef.pAllocatorFactory = allocFac; pTq->tqMemRef.pAllocator = allocFac->create(allocFac); if (pTq->tqMemRef.pAllocator == NULL) { // TODO: error code of buffer pool @@ -360,9 +375,9 @@ int tqConsume(STQ* pTq, SRpcMsg* pReq, SRpcMsg** pRsp) { (*pRsp)->pCont = ptr; break; } - *((int64_t*)buffer) = htonll(pTopic->topicId); + *((int64_t*)buffer) = htobe64(pTopic->topicId); buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); - *((int64_t*)buffer) = htonll(pTopic->buffer[idx].size); + *((int64_t*)buffer) = htobe64(pTopic->buffer[idx].size); buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); memcpy(buffer, pTopic->buffer[idx].content, pTopic->buffer[idx].size); buffer = POINTER_SHIFT(buffer, pTopic->buffer[idx].size); @@ -384,41 +399,42 @@ int tqConsume(STQ* pTq, SRpcMsg* pReq, SRpcMsg** pRsp) { } else { ASSERT(0); } - } } + if (numOfMsgs > 0) { + // set code and other msg + rpcSendResponse(*pRsp); + } else { + // most recent data has been fetched + + // enable timer for blocking wait + // once new data written when waiting, launch query and rsp + } + + // fetched a num of msgs, rpc response for(int i = 0; i < pArray->size; i++) { STqMsgItem* pItem = taosArrayGet(pArray, i); - void* raw; //read from wal + void* raw = NULL; + /*int code = pTq->tqLogReader->logRead(, &raw, pItem->offset);*/ + int code = pTq->tqLogHandle->logRead(pItem->pTopic->logReader, &raw, pItem->offset); + if(code < 0) { + //TODO: error + } //get msgType //if submitblk pItem->executor->assign(pItem->executor->runtimeEnv, raw); SSDataBlock* content = pItem->executor->exec(pItem->executor->runtimeEnv); pItem->content = content; //if other type, send just put into buffer - pItem->content = raw; + /*pItem->content = raw;*/ int32_t old = atomic_val_compare_exchange_32(&pItem->status, TQ_ITEM_PROCESS, TQ_ITEM_READY); ASSERT(old == TQ_ITEM_PROCESS); - } - - if (numOfMsgs < 0) { - return -1; - } - - if (numOfMsgs == 0) { - // most recent data has been fetched - - // enable timer for blocking wait - // once new data written when waiting, launch query and rsp - return -1; - } - - // fetched a num of msgs, rpc response + taosArrayDestroy(pArray); return 0; } @@ -500,10 +516,10 @@ void* tqSerializeTopic(STqTopic* pTopic, void* ptr) { ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); *(int64_t*)ptr = pTopic->topicId; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); - *(int32_t*)ptr = pTopic->head; - ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); - *(int32_t*)ptr = pTopic->tail; - ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); + /**(int32_t*)ptr = pTopic->head;*/ + /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/ + /**(int32_t*)ptr = pTopic->tail;*/ + /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/ for (int i = 0; i < TQ_BUFFER_SIZE; i++) { ptr = tqSerializeItem(&pTopic->buffer[i], ptr); } @@ -557,10 +573,10 @@ const void* tqDeserializeTopic(const void* pBytes, STqTopic* topic) { ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); topic->topicId = *(int64_t*)ptr; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); - topic->head = *(int32_t*)ptr; - ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); - topic->tail = *(int32_t*)ptr; - ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); + /*topic->head = *(int32_t*)ptr;*/ + /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/ + /*topic->tail = *(int32_t*)ptr;*/ + /*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/ for (int i = 0; i < TQ_BUFFER_SIZE; i++) { ptr = tqDeserializeItem(ptr, &topic->buffer[i]); } From b2574fa2f4831950d3f19719a86b933566116f13 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 23 Dec 2021 13:35:22 +0800 Subject: [PATCH 07/22] fix compile error --- source/dnode/vnode/tq/src/tq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/vnode/tq/src/tq.c b/source/dnode/vnode/tq/src/tq.c index 4529e868e1..5ceb062bf2 100644 --- a/source/dnode/vnode/tq/src/tq.c +++ b/source/dnode/vnode/tq/src/tq.c @@ -71,7 +71,7 @@ STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogHandle* tqLogHandle, SMemA free(pTq); #if 0 allocFac->destroy(allocFac, pTq->tqMemRef.pAllocator); -#endi +#endif return NULL; } From fa861e8d838ce82ca47b906f57512c9a60127dba Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 23 Dec 2021 00:50:20 -0500 Subject: [PATCH 08/22] TD-12451 insert physical plan serialization --- include/libs/planner/planner.h | 6 +- source/libs/planner/inc/plannerInt.h | 5 +- source/libs/planner/src/physicalPlan.c | 24 ++++++- source/libs/planner/src/physicalPlanJson.c | 82 +++++++++++++++++++++- source/libs/planner/src/planner.c | 4 +- source/libs/planner/test/phyPlanTests.cpp | 3 +- source/libs/scheduler/src/scheduler.c | 4 +- 7 files changed, 117 insertions(+), 11 deletions(-) diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index 153cf0bb3e..d4469be5e3 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -119,9 +119,9 @@ typedef struct SSubplanId { typedef struct SSubplan { SSubplanId id; // unique id of the subplan - int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN + int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN|QUERY_TYPE_MODIFY int32_t level; // the execution level of current subplan, starting from 0. - SEpSet execEpSet; // for the scan sub plan, the optional execution node + SEpSet execEpSet; // for the scan/modify subplan, the optional execution node SArray *pChildern; // the datasource subplan,from which to fetch the result SArray *pParents; // the data destination subplan, get data from current subplan SPhyNode *pNode; // physical plan of current subplan @@ -152,7 +152,7 @@ int32_t qExplainQuery(const struct SQueryNode* pQueryInfo, struct SEpSet* pQnode /** * Convert to subplan to string for the scheduler to send to the executor */ -int32_t qSubPlanToString(const SSubplan* subplan, char** str); +int32_t qSubPlanToString(const SSubplan* subplan, char** str, int32_t* len); int32_t qStringToSubplan(const char* str, SSubplan** subplan); diff --git a/source/libs/planner/inc/plannerInt.h b/source/libs/planner/inc/plannerInt.h index 1bee95b8e5..ed29839905 100644 --- a/source/libs/planner/inc/plannerInt.h +++ b/source/libs/planner/inc/plannerInt.h @@ -102,7 +102,7 @@ int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql); int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryDag** pDag); int32_t setSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SEpAddr* ep); -int32_t subPlanToString(const SSubplan *pPhyNode, char** str); +int32_t subPlanToString(const SSubplan *pPhyNode, char** str, int32_t* len); int32_t stringToSubplan(const char* str, SSubplan** subplan); /** @@ -121,6 +121,9 @@ void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode); const char* opTypeToOpName(int32_t type); int32_t opNameToOpType(const char* name); +const char* dsinkTypeToDsinkName(int32_t type); +int32_t dsinkNameToDsinkType(const char* name); + #ifdef __cplusplus } #endif diff --git a/source/libs/planner/src/physicalPlan.c b/source/libs/planner/src/physicalPlan.c index 9db9e059b3..8388458b4c 100644 --- a/source/libs/planner/src/physicalPlan.c +++ b/source/libs/planner/src/physicalPlan.c @@ -47,16 +47,38 @@ const char* opTypeToOpName(int32_t type) { int32_t opNameToOpType(const char* name) { for (int32_t i = 1; i < sizeof(gOpName) / sizeof(gOpName[0]); ++i) { - if (strcmp(name, gOpName[i])) { + if (0 == strcmp(name, gOpName[i])) { return i; } } return OP_Unknown; } +const char* dsinkTypeToDsinkName(int32_t type) { + switch (type) { + case DSINK_Dispatch: + return "Dispatch"; + case DSINK_Insert: + return "Insert"; + default: + break; + } + return "Unknown"; +} + +int32_t dsinkNameToDsinkType(const char* name) { + if (0 == strcmp(name, "Dispatch")) { + return DSINK_Dispatch; + } else if (0 == strcmp(name, "Insert")) { + return DSINK_Insert; + } + return DSINK_Unknown; +} + static SDataSink* initDataSink(int32_t type, int32_t size) { SDataSink* sink = (SDataSink*)vailidPointer(calloc(1, size)); sink->info.type = type; + sink->info.name = dsinkTypeToDsinkName(type); return sink; } diff --git a/source/libs/planner/src/physicalPlanJson.c b/source/libs/planner/src/physicalPlanJson.c index 15c0e632a7..bf052f34b4 100644 --- a/source/libs/planner/src/physicalPlanJson.c +++ b/source/libs/planner/src/physicalPlanJson.c @@ -695,6 +695,70 @@ static bool phyNodeFromJson(const cJSON* json, void* obj) { return res; } +static const char* jkInserterNumOfTables = "NumOfTables"; +static const char* jkInserterDataSize = "DataSize"; + +static bool inserterToJson(const void* obj, cJSON* json) { + const SDataInserter* inserter = (const SDataInserter*)obj; + bool res = cJSON_AddNumberToObject(json, jkInserterNumOfTables, inserter->numOfTables); + if (res) { + res = cJSON_AddNumberToObject(json, jkInserterDataSize, inserter->size); + } + // todo pData + return res; +} + +static bool inserterFromJson(const cJSON* json, void* obj) { + SDataInserter* inserter = (SDataInserter*)obj; + inserter->numOfTables = getNumber(json, jkInserterNumOfTables); + inserter->size = getNumber(json, jkInserterDataSize); + // todo pData +} + +static bool specificDataSinkToJson(const void* obj, cJSON* json) { + const SDataSink* dsink = (const SDataSink*)obj; + switch (dsink->info.type) { + case DSINK_Dispatch: + return true; + case DSINK_Insert: + return inserterToJson(obj, json); + default: + break; + } + return false; +} + +static bool specificDataSinkFromJson(const cJSON* json, void* obj) { + SDataSink* dsink = (SDataSink*)obj; + switch (dsink->info.type) { + case DSINK_Dispatch: + return true; + case DSINK_Insert: + return inserterFromJson(json, obj); + default: + break; + } + return false; +} + +static const char* jkDataSinkName = "Name"; + +static bool dataSinkToJson(const void* obj, cJSON* json) { + const SDataSink* dsink = (const SDataSink*)obj; + bool res = cJSON_AddStringToObject(json, jkDataSinkName, dsink->info.name); + if (res) { + res = addObject(json, dsink->info.name, specificDataSinkToJson, dsink); + } + return res; +} + +static bool dataSinkFromJson(const cJSON* json, void* obj) { + SDataSink* dsink = (SDataSink*)obj; + dsink->info.name = getString(json, jkDataSinkName); + dsink->info.type = dsinkNameToDsinkType(dsink->info.name); + return fromObject(json, dsink->info.name, specificDataSinkFromJson, dsink, true); +} + static const char* jkIdQueryId = "QueryId"; static const char* jkIdTemplateId = "TemplateId"; static const char* jkIdSubplanId = "SubplanId"; @@ -721,6 +785,7 @@ static bool subplanIdFromJson(const cJSON* json, void* obj) { static const char* jkSubplanId = "Id"; static const char* jkSubplanNode = "Node"; +static const char* jkSubplanDataSink = "DataSink"; static cJSON* subplanToJson(const SSubplan* subplan) { cJSON* jSubplan = cJSON_CreateObject(); @@ -734,6 +799,9 @@ static cJSON* subplanToJson(const SSubplan* subplan) { if (res) { res = addObject(jSubplan, jkSubplanNode, phyNodeToJson, subplan->pNode); } + if (res) { + res = addObject(jSubplan, jkSubplanDataSink, dataSinkToJson, subplan->pDataSink); + } if (!res) { cJSON_Delete(jSubplan); @@ -751,6 +819,9 @@ static SSubplan* subplanFromJson(const cJSON* json) { if (res) { res = fromObjectWithAlloc(json, jkSubplanNode, phyNodeFromJson, (void**)&subplan->pNode, sizeof(SPhyNode), false); } + if (res) { + res = fromObjectWithAlloc(json, jkSubplanDataSink, dataSinkFromJson, (void**)&subplan->pDataSink, sizeof(SDataSink), false); + } if (!res) { qDestroySubplan(subplan); @@ -759,13 +830,22 @@ static SSubplan* subplanFromJson(const cJSON* json) { return subplan; } -int32_t subPlanToString(const SSubplan* subplan, char** str) { +int32_t subPlanToString(const SSubplan* subplan, char** str, int32_t* len) { + if (QUERY_TYPE_MODIFY == subplan->type) { + SDataInserter* insert = (SDataInserter*)(subplan->pDataSink); + *len = insert->size; + *str = insert->pData; + insert->pData == NULL; + return TSDB_CODE_SUCCESS; + } + cJSON* json = subplanToJson(subplan); if (NULL == json) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return TSDB_CODE_FAILED; } *str = cJSON_Print(json); + *len = strlen(*str); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index 7722a7d363..e8523249e4 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -50,8 +50,8 @@ int32_t qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SEpAddr return setSubplanExecutionNode(subplan, templateId, ep); } -int32_t qSubPlanToString(const SSubplan *subplan, char** str) { - return subPlanToString(subplan, str); +int32_t qSubPlanToString(const SSubplan *subplan, char** str, int32_t* len) { + return subPlanToString(subplan, str, len); } int32_t qStringToSubplan(const char* str, SSubplan** subplan) { diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index 3be3337304..ddd1151742 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -62,8 +62,9 @@ protected: size_t num = taosArrayGetSize(subplans); for (size_t j = 0; j < num; ++j) { std::cout << "no " << j << ":" << std::endl; + int32_t len = 0; char* str = nullptr; - ASSERT_EQ (TSDB_CODE_SUCCESS, qSubPlanToString((const SSubplan*)taosArrayGetP(subplans, j), &str)); + ASSERT_EQ (TSDB_CODE_SUCCESS, qSubPlanToString((const SSubplan*)taosArrayGetP(subplans, j), &str, &len)); std::cout << str << std::endl; free(str); } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 99a9b06fe4..5671a0d747 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -521,8 +521,8 @@ _return: int32_t schLaunchTask(SQueryJob *job, SQueryTask *task) { SSubplan *plan = task->plan; - - SCH_ERR_RET(qSubPlanToString(plan, &task->msg)); + int32_t len = 0; + SCH_ERR_RET(qSubPlanToString(plan, &task->msg, &len)); if (plan->execEpSet.numOfEps <= 0) { SCH_ERR_RET(schSetTaskExecEpSet(job, &plan->execEpSet)); } From 5335c084498078d5e41f13db2bd504780507a4e6 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 14:09:05 +0800 Subject: [PATCH 09/22] TD-10431 refact drop mnode msg --- source/dnode/mnode/impl/src/mndMnode.c | 240 ++++++++++++++++--------- 1 file changed, 154 insertions(+), 86 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 9120b7fe27..68f47cf392 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -202,52 +202,6 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { } } -static SCreateMnodeInMsg *mndBuildCreateMnodeMsg(SMnode *pMnode, SDnodeObj *pDnode, SMnodeObj *pObj) { - SCreateMnodeInMsg *pCreate = calloc(1, sizeof(SCreateMnodeInMsg)); - if (pCreate == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return NULL; - } - - pCreate->dnodeId = htonl(pObj->id); - - int32_t numOfReplicas = 0; - SSdb *pSdb = pMnode->pSdb; - void *pIter = NULL; - - while (numOfReplicas < TSDB_MAX_REPLICA - 1) { - SMnodeObj *pObj = NULL; - pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj); - if (pIter == NULL) break; - if (pObj->pDnode == NULL) break; - - SReplica *pReplica = &pCreate->replicas[numOfReplicas]; - pReplica->id = htonl(pObj->id); - pReplica->port = htons(pObj->pDnode->port); - memcpy(pReplica->fqdn, pObj->pDnode->fqdn, TSDB_FQDN_LEN); - numOfReplicas++; - } - - numOfReplicas++; - SReplica *pReplica = &pCreate->replicas[numOfReplicas]; - pReplica->id = htonl(pObj->id); - pReplica->port = htons(pDnode->port); - memcpy(pReplica->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); - - return pCreate; -} - -static SDropMnodeInMsg *mndBuildDropMnodeMsg(SMnode *pMnode, SMnodeObj *pObj) { - SDropMnodeInMsg *pDrop = calloc(1, sizeof(SDropMnodeInMsg)); - if (pDrop == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return NULL; - } - - pDrop->dnodeId = htonl(pObj->id); - return pDrop; -} - static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { SSdbRaw *pRedoRaw = mndMnodeActionEncode(pObj); if (pRedoRaw == NULL) return -1; @@ -272,29 +226,86 @@ static int32_t mndSetCreateMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnod return 0; } -static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { - STransAction action = {0}; +static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + int32_t numOfReplicas = 0; - SDnodeObj *pDnode = mndAcquireDnode(pMnode, pObj->id); - if (pDnode == NULL) return -1; - action.epSet = mndGetDnodeEpset(pDnode); - mndReleaseDnode(pMnode, pDnode); + SCreateMnodeInMsg createMsg = {0}; + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; - SCreateMnodeInMsg *pMsg = mndBuildCreateMnodeMsg(pMnode, pDnode, pObj); - if (pMsg == NULL) return -1; + SReplica *pReplica = &createMsg.replicas[numOfReplicas]; + pReplica->id = htonl(pMObj->id); + pReplica->port = htons(pMObj->pDnode->port); + memcpy(pReplica->fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + numOfReplicas++; - action.pCont = pMsg; - action.contLen = sizeof(SCreateMnodeInMsg); - action.msgType = TSDB_MSG_TYPE_CREATE_MNODE_IN; - if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); - return -1; + sdbRelease(pSdb, pMObj); + } + + SReplica *pReplica = &createMsg.replicas[numOfReplicas]; + pReplica->id = htonl(pDnode->id); + pReplica->port = htons(pDnode->port); + memcpy(pReplica->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); + numOfReplicas++; + + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; + + STransAction action = {0}; + + SAlterMnodeInMsg *pMsg = malloc(sizeof(SAlterMnodeInMsg)); + if (pMsg == NULL) { + sdbCancelFetch(pSdb, pIter); + sdbRelease(pSdb, pMObj); + return -1; + } + memcpy(pMsg, &createMsg, sizeof(SAlterMnodeInMsg)); + + pMsg->dnodeId = htonl(pMObj->id); + action.epSet = mndGetDnodeEpset(pMObj->pDnode); + action.pCont = pMsg; + action.contLen = sizeof(SAlterMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_ALTER_MNODE_IN; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + sdbCancelFetch(pSdb, pIter); + sdbRelease(pSdb, pMObj); + return -1; + } + + sdbRelease(pSdb, pMObj); + } + + { + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + + SCreateMnodeInMsg *pMsg = malloc(sizeof(SCreateMnodeInMsg)); + if (pMsg == NULL) return -1; + memcpy(pMsg, &createMsg, sizeof(SAlterMnodeInMsg)); + pMsg->dnodeId = htonl(pObj->id); + + action.epSet = mndGetDnodeEpset(pDnode); + action.pCont = pMsg; + action.contLen = sizeof(SCreateMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_CREATE_MNODE_IN; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + return -1; + } } return 0; } -static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg *pCreate) { +static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode, SCreateMnodeMsg *pCreate) { SMnodeObj mnodeObj = {0}; mnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_MNODE); mnodeObj.createdTime = taosGetTimestampMs(); @@ -318,7 +329,7 @@ static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg * goto CREATE_MNODE_OVER; } - if (mndSetCreateMnodeRedoActions(pMnode, pTrans, &mnodeObj) != 0) { + if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pDnode, &mnodeObj) != 0) { mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); goto CREATE_MNODE_OVER; } @@ -343,23 +354,24 @@ static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { mDebug("mnode:%d, start to create", pCreate->dnodeId); + SMnodeObj *pObj = mndAcquireMnode(pMnode, pCreate->dnodeId); + if (pObj != NULL) { + mndReleaseMnode(pMnode, pObj); + mError("mnode:%d, mnode already exist", pObj->id); + terrno = TSDB_CODE_MND_MNODE_ALREADY_EXIST; + return -1; + } + SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); if (pDnode == NULL) { mError("mnode:%d, dnode not exist", pDnode->id); terrno = TSDB_CODE_MND_DNODE_NOT_EXIST; return -1; } + + int32_t code = mndCreateMnode(pMnode, pMsg, pDnode, pCreate); mndReleaseDnode(pMnode, pDnode); - SMnodeObj *pObj = mndAcquireMnode(pMnode, pCreate->dnodeId); - if (pObj != NULL) { - mError("mnode:%d, mnode already exist", pObj->id); - terrno = TSDB_CODE_MND_MNODE_ALREADY_EXIST; - return -1; - } - - int32_t code = mndCreateMnode(pMnode, pMsg, pCreate); - if (code != 0) { mError("mnode:%d, failed to create since %s", pCreate->dnodeId, terrstr()); return -1; @@ -384,23 +396,79 @@ static int32_t mndSetDropMnodeCommitLogs(SMnode *pMnode, STrans *pTrans, SMnodeO return 0; } -static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { - STransAction action = {0}; +static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnodeObj *pDnode, SMnodeObj *pObj) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + int32_t numOfReplicas = 0; - SDnodeObj *pDnode = mndAcquireDnode(pMnode, pObj->id); - if (pDnode == NULL) return -1; - action.epSet = mndGetDnodeEpset(pDnode); - mndReleaseDnode(pMnode, pDnode); + SAlterMnodeInMsg alterMsg = {0}; + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; - SDropMnodeInMsg *pMsg = mndBuildDropMnodeMsg(pMnode, pObj); - if (pMsg == NULL) return -1; + if (pMObj->id != pObj->id) { + SReplica *pReplica = &alterMsg.replicas[numOfReplicas]; + pReplica->id = htonl(pMObj->id); + pReplica->port = htons(pMObj->pDnode->port); + memcpy(pReplica->fqdn, pMObj->pDnode->fqdn, TSDB_FQDN_LEN); + numOfReplicas++; + } - action.pCont = pMsg; - action.contLen = sizeof(SDropMnodeInMsg); - action.msgType = TSDB_MSG_TYPE_CREATE_MNODE_IN; - if (mndTransAppendRedoAction(pTrans, &action) != 0) { - free(pMsg); - return -1; + sdbRelease(pSdb, pMObj); + } + + while (1) { + SMnodeObj *pMObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); + if (pIter == NULL) break; + if (pMObj->id != pObj->id) { + STransAction action = {0}; + + SAlterMnodeInMsg *pMsg = malloc(sizeof(SAlterMnodeInMsg)); + if (pMsg == NULL) { + sdbCancelFetch(pSdb, pIter); + sdbRelease(pSdb, pMObj); + return -1; + } + memcpy(pMsg, &alterMsg, sizeof(SAlterMnodeInMsg)); + + pMsg->dnodeId = htonl(pMObj->id); + action.epSet = mndGetDnodeEpset(pMObj->pDnode); + action.pCont = pMsg; + action.contLen = sizeof(SAlterMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_ALTER_MNODE_IN; + + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + sdbCancelFetch(pSdb, pIter); + sdbRelease(pSdb, pMObj); + return -1; + } + } + + sdbRelease(pSdb, pMObj); + } + + { + STransAction action = {0}; + action.epSet = mndGetDnodeEpset(pDnode); + + SDropMnodeInMsg *pMsg = malloc(sizeof(SDropMnodeInMsg)); + if (pMsg == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + pMsg->dnodeId = htonl(pObj->id); + + action.epSet = mndGetDnodeEpset(pDnode); + action.pCont = pMsg; + action.contLen = sizeof(SDropMnodeInMsg); + action.msgType = TSDB_MSG_TYPE_DROP_MNODE_IN; + if (mndTransAppendRedoAction(pTrans, &action) != 0) { + free(pMsg); + return -1; + } } return 0; @@ -426,7 +494,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pObj) { goto DROP_MNODE_OVER; } - if (mndSetCreateMnodeRedoActions(pMnode, pTrans, pObj) != 0) { + if (mndSetDropMnodeRedoActions(pMnode, pTrans, pObj->pDnode, pObj) != 0) { mError("trans:%d, failed to set redo actions since %s", pTrans->id, terrstr()); goto DROP_MNODE_OVER; } From bb1d721ead58d27508b784770880f518a35c950b Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 22 Dec 2021 22:47:46 -0800 Subject: [PATCH 10/22] TD-10431 show mnode --- source/dnode/mgmt/impl/test/mnode/mnode.cpp | 18 +++++++----------- source/dnode/mnode/impl/inc/mndMnode.h | 1 + source/dnode/mnode/impl/src/mndMnode.c | 19 +++++++++++++++++++ source/dnode/mnode/impl/src/mndSync.c | 5 ++++- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/source/dnode/mgmt/impl/test/mnode/mnode.cpp b/source/dnode/mgmt/impl/test/mnode/mnode.cpp index 1f5a63ae8e..cc0d25edea 100644 --- a/source/dnode/mgmt/impl/test/mnode/mnode.cpp +++ b/source/dnode/mgmt/impl/test/mnode/mnode.cpp @@ -51,27 +51,23 @@ TestServer DndTestMnode::server4; TestServer DndTestMnode::server5; TEST_F(DndTestMnode, 01_ShowDnode) { - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); + test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); + CHECK_META("show mnodes", 5); CHECK_SCHEMA(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); CHECK_SCHEMA(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "endpoint"); - CHECK_SCHEMA(2, TSDB_DATA_TYPE_SMALLINT, 2, "vnodes"); - CHECK_SCHEMA(3, TSDB_DATA_TYPE_SMALLINT, 2, "max_vnodes"); - CHECK_SCHEMA(4, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "status"); - CHECK_SCHEMA(5, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); - CHECK_SCHEMA(6, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "offline_reason"); + CHECK_SCHEMA(2, TSDB_DATA_TYPE_BINARY, 12 + VARSTR_HEADER_SIZE, "role"); + CHECK_SCHEMA(3, TSDB_DATA_TYPE_TIMESTAMP, 8, "role_time"); + CHECK_SCHEMA(4, TSDB_DATA_TYPE_TIMESTAMP, 8, "create_time"); test.SendShowRetrieveMsg(); EXPECT_EQ(test.GetShowRows(), 1); CheckInt16(1); CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(1); - CheckBinary("ready", 10); + CheckBinary("master", 12); + CheckInt64(0); CheckTimestamp(); - CheckBinary("", 24); } #if 0 diff --git a/source/dnode/mnode/impl/inc/mndMnode.h b/source/dnode/mnode/impl/inc/mndMnode.h index 906d11aec2..5df1391563 100644 --- a/source/dnode/mnode/impl/inc/mndMnode.h +++ b/source/dnode/mnode/impl/inc/mndMnode.h @@ -27,6 +27,7 @@ void mndCleanupMnode(SMnode *pMnode); bool mndIsMnode(SMnode *pMnode, int32_t dnodeId); void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet); char *mndGetRoleStr(int32_t role); +void mndUpdateMnodeRole(SMnode *pMnode); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 68f47cf392..80b4fabca9 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -87,6 +87,24 @@ char *mndGetRoleStr(int32_t showType) { } } +void mndUpdateMnodeRole(SMnode *pMnode) { + SSdb *pSdb = pMnode->pSdb; + void *pIter = NULL; + while (1) { + SMnodeObj *pObj = NULL; + pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj); + if (pIter == NULL) break; + + if (pObj->id == 1) { + pObj->role = TAOS_SYNC_STATE_LEADER; + } else { + pObj->role = TAOS_SYNC_STATE_CANDIDATE; + } + + sdbRelease(pSdb, pObj); + } +} + static int32_t mndCreateDefaultMnode(SMnode *pMnode) { SMnodeObj mnodeObj = {0}; mnodeObj.id = 1; @@ -595,6 +613,7 @@ static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg * pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; strcpy(pMeta->tbFname, mndShowStr(pShow->type)); + mndUpdateMnodeRole(pMnode); return 0; } diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 59161b32f2..5e9165f898 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -33,4 +33,7 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw) { return code; } -bool mndIsMaster(SMnode *pMnode) { return true; } \ No newline at end of file +bool mndIsMaster(SMnode *pMnode) { + // pMnode->role = TAOS_SYNC_STATE_LEADER; + return true; +} \ No newline at end of file From 53928fffd9256bdbf4a1a3e3f02b16bee78a484e Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 23 Dec 2021 03:27:59 -0500 Subject: [PATCH 11/22] TD-12450 ut of combination of insert parser and insert planner --- include/libs/parser/parser.h | 1 - source/libs/parser/src/insertParser.c | 1 + source/libs/parser/test/mockCatalog.cpp | 8 +-- .../libs/parser/test/mockCatalogService.cpp | 14 ++++- source/libs/planner/test/phyPlanTests.cpp | 59 ++++++++++++++++--- 5 files changed, 68 insertions(+), 15 deletions(-) diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 03750a16a9..6fedb6b66b 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -35,7 +35,6 @@ typedef struct SParseContext { void *pRpc; struct SCatalog *pCatalog; const SEpSet *pEpSet; - int64_t id; // query id, generated by uuid generator int8_t schemaAttached; // denote if submit block is built with table schema or not const char *pSql; // sql string size_t sqlLen; // length of the sql string diff --git a/source/libs/parser/src/insertParser.c b/source/libs/parser/src/insertParser.c index 68aa755483..fb7790452d 100644 --- a/source/libs/parser/src/insertParser.c +++ b/source/libs/parser/src/insertParser.c @@ -909,6 +909,7 @@ int32_t parseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) { } *pInfo = context.pOutput; + context.pOutput->nodeType = TSDB_SQL_INSERT; context.pOutput->schemaAttache = pContext->schemaAttached; context.pOutput->payloadType = PAYLOAD_TYPE_KV; diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 6d89733668..d7f410a01e 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -23,20 +23,20 @@ namespace { void generateTestT1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("root.test", "t1", TSDB_NORMAL_TABLE, 3) + ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 3) .setPrecision(TSDB_TIME_PRECISION_MILLI).setVgid(1).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20); builder.done(); } void generateTestST1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("root.test", "st1", TSDB_SUPER_TABLE, 3, 2) + ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 2) .setPrecision(TSDB_TIME_PRECISION_MILLI).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) .addTag("tag1", TSDB_DATA_TYPE_INT).addTag("tag2", TSDB_DATA_TYPE_BINARY, 20) .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20); builder.done(); - mcs->createSubTable("root.test", "st1", "st1s1", 1); - mcs->createSubTable("root.test", "st1", "st1s2", 2); + mcs->createSubTable("test", "st1", "st1s1", 1); + mcs->createSubTable("test", "st1", "st1s2", 2); } } diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index e234f82da9..520ef3a89b 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -94,9 +94,9 @@ public: return 0; } - int32_t catalogGetTableMeta(const char* pDBName, const char* pTableName, STableMeta** pTableMeta) const { + int32_t catalogGetTableMeta(const char* pDbFullName, const char* pTableName, STableMeta** pTableMeta) const { std::unique_ptr table; - int32_t code = copyTableSchemaMeta(pDBName, pTableName, &table); + int32_t code = copyTableSchemaMeta(toDbname(pDbFullName), pTableName, &table); if (TSDB_CODE_SUCCESS != code) { return code; } @@ -104,7 +104,7 @@ public: return TSDB_CODE_SUCCESS; } - int32_t catalogGetTableHashVgroup(const char* pDBName, const char* pTableName, SVgroupInfo* vgInfo) const { + int32_t catalogGetTableHashVgroup(const char* pDbFullName, const char* pTableName, SVgroupInfo* vgInfo) const { // todo return 0; } @@ -195,6 +195,14 @@ private: typedef std::map> TableMetaCache; typedef std::map DbMetaCache; + std::string toDbname(const std::string& dbFullName) const { + std::string::size_type n = dbFullName.find("."); + if (n == std::string::npos) { + return dbFullName; + } + return dbFullName.substr(n + 1); + } + std::string ttToString(int8_t tableType) const { switch (tableType) { case TSDB_SUPER_TABLE: diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index ddd1151742..cafa22df24 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -33,10 +33,6 @@ protected: void pushScan(const string& db, const string& table, int32_t scanOp) { shared_ptr meta = mockCatalogService->getTableMeta(db, table); EXPECT_TRUE(meta); -// typedef struct SQueryPlanNode { -// SArray *pExpr; // the query functions or sql aggregations -// int32_t numOfExpr; // number of result columns, which is also the number of pExprs -// } SQueryPlanNode; unique_ptr scan((SQueryPlanNode*)calloc(1, sizeof(SQueryPlanNode))); scan->info.type = scanOp; scan->numOfCols = meta->schema->tableInfo.numOfColumns; @@ -54,6 +50,27 @@ protected: return code; } + int32_t run(const string& db, const string& sql) { + int32_t code = TSDB_CODE_SUCCESS; + SParseContext cxt; + buildParseContext(db, sql, &cxt); + SQueryNode* query; + if (qIsInsertSql(cxt.pSql, cxt.sqlLen)) { + code = qParseInsertSql(&cxt, (SInsertStmtInfo**)&query); + } else { + // todo + code = TSDB_CODE_FAILED; + } + if (TSDB_CODE_SUCCESS != code) { + cout << "error no:" << code << ", msg:" << cxt.pMsg << endl; + return code; + } + SQueryDag* dag = nullptr; + code = qCreateQueryDag(query, nullptr, &dag); + dag_.reset(dag); + return code; + } + void explain() { size_t level = taosArrayGetSize(dag_->pSubplans); for (size_t i = 0; i < level; ++i) { @@ -64,7 +81,8 @@ protected: std::cout << "no " << j << ":" << std::endl; int32_t len = 0; char* str = nullptr; - ASSERT_EQ (TSDB_CODE_SUCCESS, qSubPlanToString((const SSubplan*)taosArrayGetP(subplans, j), &str, &len)); + ASSERT_EQ(TSDB_CODE_SUCCESS, qSubPlanToString((const SSubplan*)taosArrayGetP(subplans, j), &str, &len)); + std::cout << "len:" << len << std::endl; std::cout << str << std::endl; free(str); } @@ -108,6 +126,25 @@ private: return info; } + void buildParseContext(const string& db, const string& sql, SParseContext* pCxt) { + static string _db; + static string _sql; + static const int32_t _msgMaxLen = 4096; + static char _msg[_msgMaxLen]; + + _db = db; + _sql = sql; + memset(_msg, 0, _msgMaxLen); + + pCxt->ctx.acctId = 1; + pCxt->ctx.db = _db.c_str(); + pCxt->ctx.requestId = 1; + pCxt->pSql = _sql.c_str(); + pCxt->sqlLen = _sql.length(); + pCxt->pMsg = _msg; + pCxt->msgLen = _msgMaxLen; + } + shared_ptr meta_; unique_ptr logicPlan_; unique_ptr dag_; @@ -115,7 +152,7 @@ private: // select * from table TEST_F(PhyPlanTest, tableScanTest) { - pushScan("root.test", "t1", QNODE_TABLESCAN); + pushScan("test", "t1", QNODE_TABLESCAN); ASSERT_EQ(run(), TSDB_CODE_SUCCESS); explain(); SQueryDag* dag = reslut(); @@ -124,9 +161,17 @@ TEST_F(PhyPlanTest, tableScanTest) { // select * from supertable TEST_F(PhyPlanTest, superTableScanTest) { - pushScan("root.test", "st1", QNODE_TABLESCAN); + pushScan("test", "st1", QNODE_TABLESCAN); ASSERT_EQ(run(), TSDB_CODE_SUCCESS); explain(); SQueryDag* dag = reslut(); // todo check } + +// insert into t values(...) +TEST_F(PhyPlanTest, insertTest) { + ASSERT_EQ(run("test", "insert into t1 values (now, 1, \"beijing\")"), TSDB_CODE_SUCCESS); + explain(); + SQueryDag* dag = reslut(); + // todo check +} From 0c82c253be6046b7e7e7de564c9cc44b3833d7b2 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 23 Dec 2021 04:33:41 -0500 Subject: [PATCH 12/22] TD-12450 perfect parser interface --- include/libs/parser/parsenodes.h | 6 +++ include/libs/parser/parser.h | 20 +--------- source/client/src/clientImpl.c | 47 ++++++++++------------- source/libs/parser/inc/parserInt.h | 2 +- source/libs/parser/src/astValidate.c | 22 +++++------ source/libs/parser/src/parser.c | 32 ++++++++++----- source/libs/parser/test/parserTests.cpp | 14 ++----- source/libs/planner/test/phyPlanTests.cpp | 8 +--- 8 files changed, 68 insertions(+), 83 deletions(-) diff --git a/include/libs/parser/parsenodes.h b/include/libs/parser/parsenodes.h index 62f36abcee..cc7df465f7 100644 --- a/include/libs/parser/parsenodes.h +++ b/include/libs/parser/parsenodes.h @@ -160,6 +160,12 @@ typedef struct SInsertStmtInfo { const char* sql; // current sql statement position } SInsertStmtInfo; +typedef struct SDclStmtInfo { + int16_t nodeType; + char* pMsg; + int32_t msgLen; +} SDclStmtInfo; + #ifdef __cplusplus } #endif diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 6fedb6b66b..7834bc6913 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -22,14 +22,6 @@ extern "C" { #include "parsenodes.h" -/** - * True will be returned if the input sql string is insert, false otherwise. - * @param pStr sql string - * @param length length of the sql string - * @return - */ -bool qIsInsertSql(const char* pStr, size_t length); - typedef struct SParseContext { SParseBasicCtx ctx; void *pRpc; @@ -50,17 +42,9 @@ typedef struct SParseContext { * @param msg extended error message if exists. * @return error code */ -int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCtx, int32_t* type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen); +int32_t qParseQuerySql(SParseContext* pContext, SQueryNode** pQuery); -/** - * Parse the insert sql statement. - * @param pStr sql string - * @param length length of the sql string - * @param id operator id, generated by uuid generator. - * @param msg extended error message if exists to help avoid the problem in sql statement. - * @return data in binary format to submit to vnode directly. - */ - int32_t qParseInsertSql(SParseContext* pContext, struct SInsertStmtInfo** pInfo); +bool qIsDclQuery(const SQueryNode* pQuery); /** * Convert a normal sql statement to only query tags information to enable that the subscribe client can be aware quickly of the true vgroup ids that diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 42de97fe6a..7cb5ad2e07 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -144,37 +144,32 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr); - int32_t code = 0; - if (qIsInsertSql(pRequest->sqlstr, sqlLen)) { - // todo add - } else { - int32_t type = 0; - void* output = NULL; - int32_t outputLen = 0; + SParseContext cxt = { + .ctx = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)}, + .pSql = pRequest->sqlstr, + .sqlLen = sqlLen, + .pMsg = pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE + }; + SQueryNode* pQuery = NULL; + int32_t code = qParseQuerySql(&cxt, &pQuery); + if (qIsDclQuery(pQuery)) { + SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery; + pRequest->type = pDcl->nodeType; + pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = pDcl->pMsg, .len = pDcl->msgLen}; - SParseBasicCtx c = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)}; - code = qParseQuerySql(pRequest->sqlstr, sqlLen, &c, &type, &output, &outputLen, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE); - if (type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER || - type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT || - type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB) { - pRequest->type = type; - pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = output, .len = outputLen}; + SRequestMsgBody body = {0}; + buildRequestMsgFp[pDcl->nodeType](pRequest, &body); - SRequestMsgBody body = {0}; - buildRequestMsgFp[type](pRequest, &body); + int64_t transporterId = 0; + sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId); - int64_t transporterId = 0; - sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId); - - tsem_wait(&pRequest->body.rspSem); - destroyRequestMsgBody(&body); - } else { - assert(0); - } - - tfree(c.db); + tsem_wait(&pRequest->body.rspSem); + destroyRequestMsgBody(&body); } + tfree(cxt.ctx.db); + if (code != TSDB_CODE_SUCCESS) { pRequest->code = code; return pRequest; diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h index 93df023fba..186a4869e6 100644 --- a/source/libs/parser/inc/parserInt.h +++ b/source/libs/parser/inc/parserInt.h @@ -68,7 +68,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ * @param type * @return */ -int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen); +int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStmtInfo* pDcl, char* msgBuf, int32_t msgBufLen); /** * Evaluate the numeric and timestamp arithmetic expression in the WHERE clause. diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index 33efeb469d..7cb52bb1d3 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -4308,13 +4308,13 @@ int32_t doCheckForCreateTable(SSqlInfo* pInfo, SMsgBuf* pMsgBuf) { return TSDB_CODE_SUCCESS; } -int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen) { +int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStmtInfo* pDcl, char* msgBuf, int32_t msgBufLen) { int32_t code = 0; SMsgBuf m = {.buf = msgBuf, .len = msgBufLen}; SMsgBuf *pMsgBuf = &m; - *type = pInfo->type; + pDcl->nodeType = pInfo->type; switch (pInfo->type) { case TSDB_SQL_CREATE_USER: @@ -4361,7 +4361,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** } } - *output = buildUserManipulationMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildUserManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } @@ -4397,18 +4397,18 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** } } - *output = buildAcctManipulationMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildAcctManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } case TSDB_SQL_DROP_ACCT: case TSDB_SQL_DROP_USER: { - *output = buildDropUserMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildDropUserMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } case TSDB_SQL_SHOW: { - code = setShowInfo(pInfo, output, outputLen, pMsgBuf); + code = setShowInfo(pInfo, (void**)&pDcl->pMsg, &pDcl->msgLen, pMsgBuf); break; } @@ -4429,8 +4429,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** SUseDbMsg *pUseDbMsg = (SUseDbMsg *) calloc(1, sizeof(SUseDbMsg)); tNameExtractFullName(&n, pUseDbMsg->db); - *output = pUseDbMsg; - *outputLen = sizeof(SUseDbMsg); + pDcl->pMsg = (char*)pUseDbMsg; + pDcl->msgLen = sizeof(SUseDbMsg); break; } @@ -4458,8 +4458,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** strncpy(pCreateMsg->db, token.z, token.n); - *output = pCreateMsg; - *outputLen = sizeof(SCreateDbMsg); + pDcl->pMsg = (char*)pCreateMsg; + pDcl->msgLen = sizeof(SCreateDbMsg); break; } @@ -4470,7 +4470,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** if ((code = doCheckForCreateTable(pInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) { return code; } - *output = buildCreateTableMsg(pCreateTable, outputLen, pCtx, pMsgBuf); + pDcl->pMsg = (char*)buildCreateTableMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf); } else if (pCreateTable->type == TSQL_CREATE_CTABLE) { // if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) { // return code; diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 3490580f15..25f18ad6f2 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -20,7 +20,7 @@ #include "function.h" #include "insertParser.h" -bool qIsInsertSql(const char* pStr, size_t length) { +bool isInsertSql(const char* pStr, size_t length) { int32_t index = 0; do { @@ -31,18 +31,26 @@ bool qIsInsertSql(const char* pStr, size_t length) { } while (1); } -int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCtx, int32_t *type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen) { - SSqlInfo info = doGenerateAST(pStr); +bool qIsDclQuery(const SQueryNode* pQuery) { + int16_t type = pQuery->type; + return type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER || + type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT || + type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB; +} + +int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { + SSqlInfo info = doGenerateAST(pCxt->pSql); if (!info.valid) { - strncpy(msg, info.msg, msgLen); + strncpy(pCxt->pMsg, info.msg, pCxt->msgLen); terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR; return terrno; } if (!isDqlSqlStatement(&info)) { - int32_t code = qParserValidateDclSqlNode(&info, pParseCtx, pOutput, outputLen, type, msg, msgLen); + SDclStmtInfo* pDcl = calloc(1, sizeof(SQueryStmtInfo)); + int32_t code = qParserValidateDclSqlNode(&info, &pCxt->ctx, pDcl, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { - // do nothing + *pQuery = (SQueryNode*)pDcl; } } else { SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo)); @@ -53,9 +61,9 @@ int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCt struct SCatalog* pCatalog = NULL; int32_t code = catalogGetHandle(NULL, &pCatalog); - code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, pParseCtx->requestId, msg, msgLen); + code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, pCxt->ctx.requestId, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { - *pOutput = pQueryInfo; + *pQuery = (SQueryNode*)pQueryInfo; } } @@ -63,8 +71,12 @@ int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCt return TSDB_CODE_SUCCESS; } -int32_t qParseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) { - return parseInsertSql(pContext, pInfo); +int32_t qParseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { + if (isInsertSql(pCxt->pSql, pCxt->sqlLen)) { + return parseInsertSql(pCxt, (SInsertStmtInfo**)pQuery); + } else { + return parseQuerySql(pCxt, pQuery); + } } int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) { diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index be68149e09..f2cb4864fb 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -714,12 +714,9 @@ TEST(testCase, show_user_Test) { SSqlInfo info1 = doGenerateAST(sql1); ASSERT_EQ(info1.valid, true); - void* output = NULL; - int32_t type = 0; - int32_t len = 0; - + SDclStmtInfo output; SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1}; - int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, &len, &type, msg, buf.len); + int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, msg, buf.len); ASSERT_EQ(code, 0); // convert the show command to be the select query @@ -738,12 +735,9 @@ TEST(testCase, create_user_Test) { ASSERT_EQ(info1.valid, true); ASSERT_EQ(isDclSqlStatement(&info1), true); - void* output = NULL; - int32_t type = 0; - int32_t len = 0; - + SDclStmtInfo output; SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1}; - int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, &len, &type, msg, buf.len); + int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, msg, buf.len); ASSERT_EQ(code, 0); destroySqlInfo(&info1); diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index cafa22df24..f14fd50e03 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -51,16 +51,10 @@ protected: } int32_t run(const string& db, const string& sql) { - int32_t code = TSDB_CODE_SUCCESS; SParseContext cxt; buildParseContext(db, sql, &cxt); SQueryNode* query; - if (qIsInsertSql(cxt.pSql, cxt.sqlLen)) { - code = qParseInsertSql(&cxt, (SInsertStmtInfo**)&query); - } else { - // todo - code = TSDB_CODE_FAILED; - } + int32_t code = qParseQuerySql(&cxt, &query); if (TSDB_CODE_SUCCESS != code) { cout << "error no:" << code << ", msg:" << cxt.pMsg << endl; return code; From 8e078d63223ecce9d4864058f2627d5746f04469 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 23 Dec 2021 17:42:40 +0800 Subject: [PATCH 13/22] feature/qnode --- include/common/taosmsg.h | 30 +- include/libs/qcom/query.h | 5 +- include/libs/qworker/qworker.h | 12 +- include/util/taoserror.h | 5 + include/util/thash.h | 2 + source/dnode/mgmt/impl/src/dndTransport.c | 4 + source/libs/catalog/test/catalogTests.cpp | 23 + source/libs/qworker/inc/qworkerInt.h | 45 +- source/libs/qworker/src/qworker.c | 983 +++++++++++++++++++--- source/libs/scheduler/src/scheduler.c | 13 +- source/util/src/terror.c | 5 +- source/util/src/thash.c | 2 +- 12 files changed, 968 insertions(+), 161 deletions(-) diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index a8281d95a5..770a118bd5 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -52,6 +52,10 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MQ_CONNECT, "mq-connect" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MQ_DISCONNECT, "mq-disconnect" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_MQ_SET_CUR, "mq-set-cur" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_RES_READY, "res-ready" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_TASKS_STATUS, "tasks-status" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CANCEL_TASK, "cancel-task" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_TASK, "drop-task" ) + // message from client to mnode TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CONNECT, "connect" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_ACCT, "create-acct" ) @@ -1093,29 +1097,29 @@ typedef struct { /* data */ } SUpdateTagValRsp; -typedef struct SSchedulerQueryMsg { +typedef struct SSubQueryMsg { uint64_t schedulerId; uint64_t queryId; uint64_t taskId; uint32_t contentLen; char msg[]; -} SSchedulerQueryMsg; +} SSubQueryMsg; -typedef struct SSchedulerReadyMsg { +typedef struct SResReadyMsg { uint64_t schedulerId; uint64_t queryId; uint64_t taskId; -} SSchedulerReadyMsg; +} SResReadyMsg; -typedef struct SSchedulerFetchMsg { +typedef struct SResFetchMsg { uint64_t schedulerId; uint64_t queryId; uint64_t taskId; -} SSchedulerFetchMsg; +} SResFetchMsg; -typedef struct SSchedulerStatusMsg { +typedef struct SSchTasksStatusMsg { uint64_t schedulerId; -} SSchedulerStatusMsg; +} SSchTasksStatusMsg; typedef struct STaskStatus { uint64_t queryId; @@ -1129,11 +1133,17 @@ typedef struct SSchedulerStatusRsp { } SSchedulerStatusRsp; -typedef struct SSchedulerCancelMsg { +typedef struct STaskCancelMsg { uint64_t schedulerId; uint64_t queryId; uint64_t taskId; -} SSchedulerCancelMsg; +} STaskCancelMsg; + +typedef struct STaskDropMsg { + uint64_t schedulerId; + uint64_t queryId; + uint64_t taskId; +} STaskDropMsg; #pragma pack(pop) diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 4fcbc1c528..31b96adec0 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -25,12 +25,15 @@ extern "C" { #include "tlog.h" enum { + JOB_TASK_STATUS_NULL = 0, JOB_TASK_STATUS_NOT_START = 1, JOB_TASK_STATUS_EXECUTING, + JOB_TASK_STATUS_PARTIAL_SUCCEED, JOB_TASK_STATUS_SUCCEED, JOB_TASK_STATUS_FAILED, JOB_TASK_STATUS_CANCELLING, - JOB_TASK_STATUS_CANCELLED + JOB_TASK_STATUS_CANCELLED, + JOB_TASK_STATUS_DROPPING, }; typedef struct STableComInfo { diff --git a/include/libs/qworker/qworker.h b/include/libs/qworker/qworker.h index 63a6b6f89b..8e36178497 100644 --- a/include/libs/qworker/qworker.h +++ b/include/libs/qworker/qworker.h @@ -42,15 +42,17 @@ typedef struct { int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt); -int32_t qWorkerProcessQueryMsg(void *qWorkerMgmt, SSchedulerQueryMsg *msg, SRpcMsg *rsp); +int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg **rsp); -int32_t qWorkerProcessReadyMsg(void *qWorkerMgmt, SSchedulerReadyMsg *msg, SRpcMsg *rsp); +int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); -int32_t qWorkerProcessStatusMsg(void *qWorkerMgmt, SSchedulerStatusMsg *msg, SRpcMsg *rsp); +int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); -int32_t qWorkerProcessFetchMsg(void *qWorkerMgmt, SSchedulerFetchMsg *msg, SRpcMsg *rsp); +int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); -int32_t qWorkerProcessCancelMsg(void *qWorkerMgmt, SSchedulerCancelMsg *msg, SRpcMsg *rsp); +int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); + +int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); void qWorkerDestroy(void **qWorkerMgmt); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 7e8df3add2..4362950844 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -314,6 +314,11 @@ int32_t* taosGetErrno(); #define TSDB_CODE_QRY_INVALID_TIME_CONDITION TAOS_DEF_ERROR_CODE(0, 0x070D) //"invalid time condition") #define TSDB_CODE_QRY_SYS_ERROR TAOS_DEF_ERROR_CODE(0, 0x070E) //"System error") #define TSDB_CODE_QRY_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x070F) //"invalid input") +#define TSDB_CODE_QRY_SCH_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0710) //"Scheduler not exist") +#define TSDB_CODE_QRY_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0711) //"Task not exist") +#define TSDB_CODE_QRY_TASK_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0712) //"Task already exist") +#define TSDB_CODE_QRY_RES_CACHE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0713) //"Task result cache not exist") +#define TSDB_CODE_QRY_TASK_CANCELLED TAOS_DEF_ERROR_CODE(0, 0x0714) //"Task cancelled") // grant diff --git a/include/util/thash.h b/include/util/thash.h index ebdc91f054..d0247a0729 100644 --- a/include/util/thash.h +++ b/include/util/thash.h @@ -33,6 +33,8 @@ typedef void (*_hash_free_fn_t)(void *); #define HASH_INDEX(v, c) ((v) & ((c)-1)) +#define HASH_NODE_EXIST(code) (code == -2) + /** * murmur hash algorithm * @key usually string diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index 50b1a1cf20..b0bb0bfc05 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -45,6 +45,10 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { pMgmt->msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = dndProcessVnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = dndProcessVnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_MQ_SET_CUR] = dndProcessVnodeWriteMsg; + pMgmt->msgFp[TSDB_MSG_TYPE_RES_READY] = dndProcessVnodeFetchMsg; + pMgmt->msgFp[TSDB_MSG_TYPE_TASKS_STATUS] = dndProcessVnodeFetchMsg; + pMgmt->msgFp[TSDB_MSG_TYPE_CANCEL_TASK] = dndProcessVnodeFetchMsg; + pMgmt->msgFp[TSDB_MSG_TYPE_DROP_TASK] = dndProcessVnodeFetchMsg; // msg from client to mnode pMgmt->msgFp[TSDB_MSG_TYPE_CONNECT] = dndProcessMnodeReadMsg; diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp index 29c80ae9ec..4f41d728eb 100644 --- a/source/libs/catalog/test/catalogTests.cpp +++ b/source/libs/catalog/test/catalogTests.cpp @@ -29,6 +29,8 @@ #include "catalog.h" #include "tep.h" #include "trpc.h" +#include "stub.h" +#include "addr_any.h" typedef struct SAppInstInfo { int64_t numOfConns; @@ -86,6 +88,27 @@ void sendCreateDbMsg(void *shandle, SEpSet *pEpSet) { ASSERT_EQ(rpcRsp.code, 0); } +void __rpcSendRecv(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { + SUseDbRsp *rspMsg = NULL; //todo + + return; +} + + +void initTestEnv() { + static Stub stub; + stub.set(rpcSendRecv, __rpcSendRecv); + { + AddrAny any("libtransport.so"); + std::map result; + any.get_global_func_addr_dynsym("^rpcSendRecv$", result); + for (const auto& f : result) { + stub.set(f.second, __rpcSendRecv); + } + } +} + + } TEST(testCase, normalCase) { diff --git a/source/libs/qworker/inc/qworkerInt.h b/source/libs/qworker/inc/qworkerInt.h index 1adc09def4..6f454e2f81 100644 --- a/source/libs/qworker/inc/qworkerInt.h +++ b/source/libs/qworker/inc/qworkerInt.h @@ -20,6 +20,8 @@ extern "C" { #endif +#include "tlockfree.h" + #define QWORKER_DEFAULT_SCHEDULER_NUMBER 10000 #define QWORKER_DEFAULT_RES_CACHE_NUMBER 10000 #define QWORKER_DEFAULT_SCH_TASK_NUMBER 10000 @@ -30,36 +32,63 @@ enum { QW_READY_RESPONSED, }; -typedef struct SQWorkerTaskStatus { - int8_t status; - int8_t ready; +enum { + QW_TASK_INFO_STATUS = 1, + QW_TASK_INFO_READY, +}; + +enum { + QW_READ = 1, + QW_WRITE, +}; + +typedef struct SQWorkerTaskStatus { + SRWLatch lock; + int32_t code; + int8_t status; + int8_t ready; + bool cancel; + bool drop; } SQWorkerTaskStatus; typedef struct SQWorkerResCache { + SRWLatch lock; void *data; } SQWorkerResCache; -typedef struct SQWorkerSchTaskStatus { +typedef struct SQWorkerSchStatus { int32_t lastAccessTs; // timestamp in second - SHashObj *taskStatus; // key:queryId+taskId, value: SQWorkerTaskStatus -} SQWorkerSchTaskStatus; + SRWLatch tasksLock; + SHashObj *tasksHash; // key:queryId+taskId, value: SQWorkerTaskStatus +} SQWorkerSchStatus; // Qnode/Vnode level task management typedef struct SQWorkerMgmt { SQWorkerCfg cfg; - SHashObj *scheduleHash; //key: schedulerId, value: SQWorkerSchTaskStatus + SRWLatch schLock; + SRWLatch resLock; + SHashObj *schHash; //key: schedulerId, value: SQWorkerSchStatus SHashObj *resHash; //key: queryId+taskId, value: SQWorkerResCache } SQWorkerMgmt; -#define QW_TASK_DONE(status) (status == JOB_TASK_STATUS_SUCCEED || status == JOB_TASK_STATUS_FAILED || status == status == JOB_TASK_STATUS_CANCELLED) +#define QW_GOT_RES_DATA(data) (false) +#define QW_LOW_RES_DATA(data) (false) + +#define QW_TASK_NOT_EXIST(code) (TSDB_CODE_QRY_SCH_NOT_EXIST == (code) || TSDB_CODE_QRY_TASK_NOT_EXIST == (code)) +#define QW_TASK_ALREADY_EXIST(code) (TSDB_CODE_QRY_TASK_ALREADY_EXIST == (code)) +#define QW_TASK_READY_RESP(status) (status == JOB_TASK_STATUS_SUCCEED || status == JOB_TASK_STATUS_FAILED || status == JOB_TASK_STATUS_CANCELLED || status == JOB_TASK_STATUS_PARTIAL_SUCCEED) #define QW_SET_QTID(id, qid, tid) do { *(uint64_t *)(id) = (qid); *(uint64_t *)((char *)(id) + sizeof(qid)) = (tid); } while (0) #define QW_GET_QTID(id, qid, tid) do { (qid) = *(uint64_t *)(id); (tid) = *(uint64_t *)((char *)(id) + sizeof(qid)); } while (0) + #define QW_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0) #define QW_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0) #define QW_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); terrno = _code; return _code; } } while (0) #define QW_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0) +#define QW_LOCK(type, _lock) (QW_READ == (type) ? taosRLockLatch(_lock) : taosWLockLatch(_lock)) +#define QW_UNLOCK(type, _lock) (QW_READ == (type) ? taosRUnLockLatch(_lock) : taosWUnLockLatch(_lock)) + #ifdef __cplusplus } diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 82bfd75b6a..628077a020 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -4,69 +4,79 @@ #include "qworkerInt.h" #include "planner.h" -int32_t qwAddTaskStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, int8_t taskStatus) { - SQWorkerTaskStatus tStatus = {0}; - tStatus.status = taskStatus; - - char id[sizeof(queryId) + sizeof(taskId)] = {0}; - QW_SET_QTID(id, queryId, taskId); +int32_t qwCheckStatusSwitch(int8_t oriStatus, int8_t newStatus) { + int32_t code = 0; - SQWorkerSchTaskStatus *schStatus = taosHashGet(mgmt->scheduleHash, &schedulerId, sizeof(schedulerId)); - if (NULL == schStatus) { - SQWorkerSchTaskStatus newSchStatus = {0}; - newSchStatus.taskStatus = taosHashInit(mgmt->cfg.maxSchTaskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); - if (NULL == newSchStatus.taskStatus) { - qError("taosHashInit %d failed", mgmt->cfg.maxSchTaskNum); - return TSDB_CODE_QRY_OUT_OF_MEMORY; + if (oriStatus == newStatus) { + if (newStatus == JOB_TASK_STATUS_CANCELLING) { + return TSDB_CODE_SUCCESS; } - - if (0 != taosHashPut(newSchStatus.taskStatus, id, sizeof(id), &tStatus, sizeof(tStatus))) { - qError("taosHashPut schedulerId[%"PRIx64"]queryId[%"PRIx64"] taskId[%"PRIx64"] to scheduleHash failed", schedulerId, queryId, taskId); - taosHashCleanup(newSchStatus.taskStatus); - return TSDB_CODE_QRY_APP_ERROR; - } - - newSchStatus.lastAccessTs = taosGetTimestampSec(); - - if (0 != taosHashPut(mgmt->scheduleHash, &schedulerId, sizeof(schedulerId), &newSchStatus, sizeof(newSchStatus))) { - qError("taosHashPut schedulerId[%"PRIx64"] to scheduleHash failed", schedulerId); - taosHashCleanup(newSchStatus.taskStatus); - return TSDB_CODE_QRY_APP_ERROR; - } - - return TSDB_CODE_SUCCESS; + + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); } - - schStatus->lastAccessTs = taosGetTimestampSec(); - - if (0 != taosHashPut(schStatus->taskStatus, id, sizeof(id), &tStatus, sizeof(tStatus))) { - qError("taosHashPut schedulerId[%"PRIx64"]queryId[%"PRIx64"] taskId[%"PRIx64"] to scheduleHash failed", schedulerId, queryId, taskId); - return TSDB_CODE_QRY_APP_ERROR; + + switch (oriStatus) { + case JOB_TASK_STATUS_NULL: + if (newStatus != JOB_TASK_STATUS_EXECUTING && newStatus != JOB_TASK_STATUS_FAILED ) { + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_NOT_START: + if (newStatus != JOB_TASK_STATUS_EXECUTING && newStatus != JOB_TASK_STATUS_FAILED) { + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_EXECUTING: + if (newStatus != JOB_TASK_STATUS_SUCCEED && newStatus != JOB_TASK_STATUS_FAILED && newStatus != JOB_TASK_STATUS_CANCELLING) { + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_PARTIAL_SUCCEED: + if (newStatus != JOB_TASK_STATUS_EXECUTING && newStatus != JOB_TASK_STATUS_CANCELLING) { + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_SUCCEED: + case JOB_TASK_STATUS_FAILED: + case JOB_TASK_STATUS_CANCELLING: + if (newStatus != JOB_TASK_STATUS_CANCELLED) { + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + break; + case JOB_TASK_STATUS_CANCELLED: + default: + qError("invalid task status:%d", oriStatus); + return TSDB_CODE_QRY_APP_ERROR; } return TSDB_CODE_SUCCESS; + +_return: + + qError("invalid task status:%d", oriStatus); + QW_ERR_RET(code); } -int32_t qwGetTaskStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, SQWorkerTaskStatus **taskStatus) { - SQWorkerSchTaskStatus *schStatus = taosHashGet(mgmt->scheduleHash, &schedulerId, sizeof(schedulerId)); - if (NULL == schStatus) { - qError("no scheduler for schedulerId[%"PRIx64"]", schedulerId); - return TSDB_CODE_QRY_APP_ERROR; - } - - schStatus->lastAccessTs = taosGetTimestampSec(); +int32_t qwUpdateTaskInfo(SQWorkerTaskStatus *task, int8_t type, void *data) { + int32_t code = 0; - char id[sizeof(queryId) + sizeof(taskId)] = {0}; - QW_SET_QTID(id, queryId, taskId); - - SQWorkerTaskStatus *tStatus = taosHashGet(schStatus->taskStatus, id, sizeof(id)); - if (NULL == tStatus) { - qError("no task status for schedulerId[%"PRIx64"] queryId[%"PRIx64"] taskId[%"PRIx64"]", schedulerId, queryId, taskId); - return TSDB_CODE_QRY_APP_ERROR; + switch (type) { + case QW_TASK_INFO_STATUS: { + int8_t newStatus = *(int8_t *)data; + QW_ERR_RET(qwCheckStatusSwitch(task->status, newStatus)); + task->status = newStatus; + break; + } + default: + qError("uknown task info type:%d", type); + return TSDB_CODE_QRY_APP_ERROR; } - - *taskStatus = tStatus; - + return TSDB_CODE_SUCCESS; } @@ -76,12 +86,16 @@ int32_t qwAddTaskResult(SQWorkerMgmt *mgmt, uint64_t queryId, uint64_t taskId, v SQWorkerResCache resCache = {0}; resCache.data = data; - + + QW_LOCK(QW_WRITE, &mgmt->resLock); if (0 != taosHashPut(mgmt->resHash, id, sizeof(id), &resCache, sizeof(SQWorkerResCache))) { + QW_UNLOCK(QW_WRITE, &mgmt->resLock); qError("taosHashPut queryId[%"PRIx64"] taskId[%"PRIx64"] to resHash failed", queryId, taskId); return TSDB_CODE_QRY_APP_ERROR; } + QW_UNLOCK(QW_WRITE, &mgmt->resLock); + return TSDB_CODE_SUCCESS; } @@ -101,62 +115,693 @@ int32_t qwGetTaskResult(SQWorkerMgmt *mgmt, uint64_t queryId, uint64_t taskId, v return TSDB_CODE_SUCCESS; } -int32_t qwUpdateSchLastAccess(SQWorkerMgmt *mgmt, uint64_t schedulerId) { - SQWorkerSchTaskStatus *schStatus = taosHashGet(mgmt->scheduleHash, &schedulerId, sizeof(schedulerId)); - if (NULL == schStatus) { - qError("no scheduler for schedulerId[%"PRIx64"]", schedulerId); - return TSDB_CODE_QRY_APP_ERROR; - } - schStatus->lastAccessTs = taosGetTimestampSec(); +static FORCE_INLINE int32_t qwAcquireScheduler(int32_t rwType, SQWorkerMgmt *mgmt, uint64_t schedulerId, SQWorkerSchStatus **sch) { + QW_LOCK(rwType, &mgmt->schLock); + *sch = taosHashGet(mgmt->schHash, &schedulerId, sizeof(schedulerId)); + if (NULL == (*sch)) { + QW_LOCK(rwType, &mgmt->schLock); + return TSDB_CODE_QRY_SCH_NOT_EXIST; + } return TSDB_CODE_SUCCESS; } -int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, SSchedulerStatusRsp **rsp) { - SQWorkerSchTaskStatus *schStatus = taosHashGet(mgmt->scheduleHash, &schedulerId, sizeof(schedulerId)); - if (NULL == schStatus) { - qError("no scheduler for schedulerId[%"PRIx64"]", schedulerId); - return TSDB_CODE_QRY_APP_ERROR; + +static FORCE_INLINE int32_t qwInsertAndAcquireScheduler(int32_t rwType, SQWorkerMgmt *mgmt, uint64_t schedulerId, SQWorkerSchStatus **sch) { + SQWorkerSchStatus newSch = {0}; + newSch.tasksHash = taosHashInit(mgmt->cfg.maxSchTaskNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); + if (NULL == newSch.tasksHash) { + qError("taosHashInit %d failed", mgmt->cfg.maxSchTaskNum); + return TSDB_CODE_QRY_OUT_OF_MEMORY; } - schStatus->lastAccessTs = taosGetTimestampSec(); + while (true) { + QW_LOCK(QW_WRITE, &mgmt->schLock); + int32_t code = taosHashPut(mgmt->schHash, &schedulerId, sizeof(schedulerId), &newSch, sizeof(newSch)); + if (0 != code) { + if (!HASH_NODE_EXIST(code)) { + QW_UNLOCK(QW_WRITE, &mgmt->schLock); + qError("taosHashPut schedulerId[%"PRIx64"] to scheduleHash failed", schedulerId); + taosHashCleanup(newSch.tasksHash); + return TSDB_CODE_QRY_APP_ERROR; + } + } + + QW_UNLOCK(QW_WRITE, &mgmt->schLock); + if (TSDB_CODE_SUCCESS == qwAcquireScheduler(rwType, mgmt, schedulerId, sch)) { + taosHashCleanup(newSch.tasksHash); + return TSDB_CODE_SUCCESS; + } + } - int32_t i = 0; - int32_t taskNum = taosHashGetSize(schStatus->taskStatus); + return TSDB_CODE_SUCCESS; +} + + +static FORCE_INLINE void qwReleaseScheduler(int32_t rwType, SQWorkerMgmt *mgmt) { + QW_UNLOCK(rwType, &mgmt->schLock); +} + +static FORCE_INLINE int32_t qwAcquireTask(int32_t rwType, SQWorkerSchStatus *sch, uint64_t queryId, uint64_t taskId, SQWorkerTaskStatus **task) { + char id[sizeof(queryId) + sizeof(taskId)] = {0}; + QW_SET_QTID(id, queryId, taskId); + + QW_LOCK(rwType, &sch->tasksLock); + *task = taosHashGet(sch->tasksHash, id, sizeof(id)); + if (NULL == (*task)) { + QW_UNLOCK(rwType, &sch->tasksLock); + return TSDB_CODE_QRY_TASK_NOT_EXIST; + } + + return TSDB_CODE_SUCCESS; +} + +static FORCE_INLINE int32_t qwInsertAndAcquireTask(int32_t rwType, SQWorkerSchStatus *sch, uint64_t queryId, uint64_t taskId, int8_t status, bool *inserted, SQWorkerTaskStatus **task) { + char id[sizeof(queryId) + sizeof(taskId)] = {0}; + QW_SET_QTID(id, queryId, taskId); + + while (true) { + *inserted = false; + + QW_LOCK(QW_WRITE, &sch->tasksLock); + int32_t code = taosHashPut(sch->tasksHash, id, sizeof(id), &status, sizeof(status)); + if (0 != code) { + QW_UNLOCK(QW_WRITE, &sch->tasksLock); + if (HASH_NODE_EXIST(code)) { + if (qwAcquireTask(rwType, sch, queryId, taskId, task)) { + continue; + } + + break; + } else { + qError("taosHashPut queryId[%"PRIx64"] taskId[%"PRIx64"] to scheduleHash failed", queryId, taskId); + return TSDB_CODE_QRY_APP_ERROR; + } + } + QW_UNLOCK(QW_WRITE, &sch->tasksLock); + + *inserted = true; + + if (TSDB_CODE_SUCCESS == qwAcquireTask(rwType, sch, queryId, taskId, task)) { + return TSDB_CODE_SUCCESS; + } + } + + return TSDB_CODE_SUCCESS; +} + + +static FORCE_INLINE void qwReleaseTask(int32_t rwType, SQWorkerSchStatus *sch) { + QW_UNLOCK(rwType, &sch->tasksLock); +} + +static FORCE_INLINE int32_t qwAcquireTaskResCache(int32_t rwType, SQWorkerMgmt *mgmt, uint64_t queryId, uint64_t taskId, SQWorkerResCache **res) { + char id[sizeof(queryId) + sizeof(taskId)] = {0}; + QW_SET_QTID(id, queryId, taskId); + + QW_LOCK(rwType, &mgmt->resLock); + *res = taosHashGet(mgmt->resHash, id, sizeof(id)); + if (NULL == (*res)) { + QW_UNLOCK(rwType, &mgmt->resLock); + return TSDB_CODE_QRY_RES_CACHE_NOT_EXIST; + } + + return TSDB_CODE_SUCCESS; +} + +static FORCE_INLINE void qwReleaseTaskResCache(int32_t rwType, SQWorkerMgmt *mgmt) { + QW_UNLOCK(rwType, &mgmt->resLock); +} + + +int32_t qwGetSchTasksStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, SSchedulerStatusRsp **rsp) { + SQWorkerSchStatus *schStatus = NULL; + int32_t taskNum = 0; + + if (qwAcquireScheduler(QW_READ, mgmt, schedulerId, &schStatus)) { + qWarn("no scheduler for schedulerId[%"PRIx64"]", schedulerId); + } else { + schStatus->lastAccessTs = taosGetTimestampSec(); + + QW_LOCK(QW_READ, &schStatus->tasksLock); + taskNum = taosHashGetSize(schStatus->tasksHash); + } + int32_t size = sizeof(SSchedulerStatusRsp) + sizeof((*rsp)->status[0]) * taskNum; *rsp = calloc(1, size); if (NULL == *rsp) { qError("calloc %d failed", size); + if (schStatus) { + QW_UNLOCK(QW_READ, &schStatus->tasksLock); + qwReleaseScheduler(QW_READ, mgmt); + } + return TSDB_CODE_QRY_OUT_OF_MEMORY; } void *key = NULL; size_t keyLen = 0; - void *pIter = taosHashIterate(schStatus->taskStatus, NULL); - while (pIter) { - SQWorkerTaskStatus *taskStatus = (SQWorkerTaskStatus *)pIter; - taosHashGetKey(pIter, &key, &keyLen); + int32_t i = 0; - QW_GET_QTID(key, (*rsp)->status[i].queryId, (*rsp)->status[i].taskId); - (*rsp)->status[i].status = taskStatus->status; - - pIter = taosHashIterate(schStatus->taskStatus, pIter); - } + if (schStatus) { + void *pIter = taosHashIterate(schStatus->tasksHash, NULL); + while (pIter) { + SQWorkerTaskStatus *taskStatus = (SQWorkerTaskStatus *)pIter; + taosHashGetKey(pIter, &key, &keyLen); + + QW_GET_QTID(key, (*rsp)->status[i].queryId, (*rsp)->status[i].taskId); + (*rsp)->status[i].status = taskStatus->status; + + pIter = taosHashIterate(schStatus->tasksHash, pIter); + } + } + + if (schStatus) { + QW_UNLOCK(QW_READ, &schStatus->tasksLock); + qwReleaseScheduler(QW_READ, mgmt); + } (*rsp)->num = taskNum; return TSDB_CODE_SUCCESS; } -int32_t qwBuildRspMsg(void *data, int32_t msgType); + + +int32_t qwUpdateSchLastAccess(SQWorkerMgmt *mgmt, uint64_t schedulerId) { + SQWorkerSchStatus *schStatus = NULL; + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &schStatus)); + + schStatus->lastAccessTs = taosGetTimestampSec(); + + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; +} + + +int32_t qwGetTaskStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, int8_t *taskStatus) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + + QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); + + *taskStatus = task->status; + +_return: + if (task) { + qwReleaseTask(QW_READ, sch); + } + + if (sch) { + qwReleaseScheduler(QW_READ, mgmt); + } + + QW_RET(code); +} + + +int32_t qwSwitchTaskStatus(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, int8_t taskStatus) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + bool inserted = false; + + if (qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)) { + if (qwCheckStatusSwitch(JOB_TASK_STATUS_NULL, taskStatus)) { + qError("switch status error, not start to %d", taskStatus); + QW_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + QW_ERR_RET(qwInsertAndAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + } + + if (qwAcquireTask(QW_READ, sch, queryId, taskId, &task)) { + if (qwCheckStatusSwitch(JOB_TASK_STATUS_NOT_START, taskStatus)) { + qwReleaseScheduler(QW_READ, mgmt); + qError("switch status error, not start to %d", taskStatus); + QW_ERR_RET(TSDB_CODE_QRY_APP_ERROR); + } + + QW_ERR_JRET(qwInsertAndAcquireTask(QW_READ, sch, queryId, taskId, taskStatus, &inserted, &task)); + + if (inserted) { + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + return TSDB_CODE_SUCCESS; + } + + QW_LOCK(QW_WRITE, &task->lock); + code = qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &taskStatus); + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + QW_RET(code); + } + + QW_LOCK(QW_WRITE, &task->lock); + code = qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &taskStatus); + QW_UNLOCK(QW_WRITE, &task->lock); + +_return: + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + QW_RET(code); +} + + +int32_t qwCancelTask(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + if (TSDB_CODE_SUCCESS != qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)) { + QW_ERR_RET(qwSwitchTaskStatus(mgmt, schedulerId, queryId, taskId, JOB_TASK_STATUS_NOT_START)); + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + } + + if (qwAcquireTask(QW_READ, sch, queryId, taskId, &task)) { + code = qwSwitchTaskStatus(mgmt, schedulerId, queryId, taskId, JOB_TASK_STATUS_NOT_START); + if (code) { + qwReleaseScheduler(QW_READ, mgmt); + QW_ERR_RET(code); + } + + QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); + } + + QW_LOCK(QW_WRITE, &task->lock); + + task->cancel = true; + + int8_t oriStatus = task->status; + int8_t newStatus = 0; + + if (task->status == JOB_TASK_STATUS_CANCELLED || task->status == JOB_TASK_STATUS_NOT_START || task->status == JOB_TASK_STATUS_CANCELLING || task->status == JOB_TASK_STATUS_DROPPING) { + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; + } else if (task->status == JOB_TASK_STATUS_FAILED || task->status == JOB_TASK_STATUS_SUCCEED || task->status == JOB_TASK_STATUS_PARTIAL_SUCCEED) { + newStatus = JOB_TASK_STATUS_CANCELLED; + QW_ERR_JRET(qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &newStatus)); + } else { + newStatus = JOB_TASK_STATUS_CANCELLING; + QW_ERR_JRET(qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &newStatus)); + } + + QW_UNLOCK(QW_WRITE, &task->lock); + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + if (oriStatus == JOB_TASK_STATUS_EXECUTING) { + //TODO call executer to cancel subquery async + } + + return TSDB_CODE_SUCCESS; + +_return: + + if (task) { + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + } + + if (sch) { + qwReleaseScheduler(QW_READ, mgmt); + } + + QW_RET(code); +} + + + +int32_t qwDropTask(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + char id[sizeof(queryId) + sizeof(taskId)] = {0}; + QW_SET_QTID(id, queryId, taskId); + + QW_LOCK(QW_WRITE, &mgmt->resLock); + if (mgmt->resHash) { + taosHashRemove(mgmt->resHash, id, sizeof(id)); + } + QW_UNLOCK(QW_WRITE, &mgmt->resLock); + + if (TSDB_CODE_SUCCESS != qwAcquireScheduler(QW_WRITE, mgmt, schedulerId, &sch)) { + qWarn("scheduler %"PRIx64" doesn't exist", schedulerId); + return TSDB_CODE_SUCCESS; + } + + if (qwAcquireTask(QW_WRITE, sch, queryId, taskId, &task)) { + qwReleaseScheduler(QW_WRITE, mgmt); + + qWarn("scheduler %"PRIx64" queryId %"PRIx64" taskId:%"PRIx64" doesn't exist", schedulerId, queryId, taskId); + return TSDB_CODE_SUCCESS; + } + + taosHashRemove(sch->tasksHash, id, sizeof(id)); + + qwReleaseTask(QW_WRITE, sch); + qwReleaseScheduler(QW_WRITE, mgmt); + + return TSDB_CODE_SUCCESS; +} + + +int32_t qwCancelDropTask(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + if (TSDB_CODE_SUCCESS != qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)) { + qWarn("scheduler %"PRIx64" doesn't exist", schedulerId); + return TSDB_CODE_SUCCESS; + } + + if (qwAcquireTask(QW_READ, sch, queryId, taskId, &task)) { + qwReleaseScheduler(QW_READ, mgmt); + + qWarn("scheduler %"PRIx64" queryId %"PRIx64" taskId:%"PRIx64" doesn't exist", schedulerId, queryId, taskId); + return TSDB_CODE_SUCCESS; + } + + QW_LOCK(QW_WRITE, &task->lock); + + task->drop = true; + + int8_t oriStatus = task->status; + int8_t newStatus = 0; + + if (task->status == JOB_TASK_STATUS_EXECUTING) { + newStatus = JOB_TASK_STATUS_CANCELLING; + QW_ERR_JRET(qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &newStatus)); + } else if (task->status == JOB_TASK_STATUS_CANCELLING || task->status == JOB_TASK_STATUS_DROPPING || task->status == JOB_TASK_STATUS_NOT_START) { + QW_UNLOCK(QW_WRITE, &task->lock); + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; + } else { + QW_UNLOCK(QW_WRITE, &task->lock); + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + QW_ERR_RET(qwDropTask(mgmt, schedulerId, queryId, taskId)); + return TSDB_CODE_SUCCESS; + } + + QW_UNLOCK(QW_WRITE, &task->lock); + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + if (oriStatus == JOB_TASK_STATUS_EXECUTING) { + //TODO call executer to cancel subquery async + } + + return TSDB_CODE_SUCCESS; + +_return: + + if (task) { + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + } + + if (sch) { + qwReleaseScheduler(QW_READ, mgmt); + } + + QW_RET(code); +} + + + +int32_t qwBuildAndSendQueryRsp(SRpcMsg *pMsg, int32_t code) { + +} + +int32_t qwBuildAndSendReadyRsp(SRpcMsg *pMsg, int32_t code) { + +} + +int32_t qwBuildAndSendStatusRsp(SRpcMsg *pMsg, SSchedulerStatusRsp *sStatus) { + +} + +int32_t qwBuildAndSendFetchRsp(SRpcMsg *pMsg, void *data) { + +} + + +int32_t qwBuildAndSendCancelRsp(SRpcMsg *pMsg) { + +} + +int32_t qwBuildAndSendDropRsp(SRpcMsg *pMsg) { + +} + + + +int32_t qwCheckAndSendReadyRsp(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, SRpcMsg *pMsg, int32_t rspCode) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + + QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); + + QW_LOCK(QW_WRITE, &task->lock); + + if (QW_READY_NOT_RECEIVED == task->ready) { + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; + } else if (QW_READY_RECEIVED == task->ready) { + QW_ERR_JRET(qwBuildAndSendReadyRsp(pMsg, rspCode)); + + task->ready = QW_READY_RESPONSED; + } else if (QW_READY_RESPONSED == task->ready) { + qError("query response already send"); + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } else { + assert(0); + } + +_return: + + if (task) { + QW_UNLOCK(QW_WRITE, &task->lock); + } + + if (sch) { + qwReleaseTask(QW_READ, sch); + } + + qwReleaseScheduler(QW_READ, mgmt); + + QW_RET(code); +} + +int32_t qwSetAndSendReadyRsp(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, SRpcMsg *pMsg) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + + QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); + + QW_LOCK(QW_WRITE, &task->lock); + if (QW_TASK_READY_RESP(task->status)) { + QW_ERR_JRET(qwBuildAndSendReadyRsp(pMsg, task->code)); + + task->ready = QW_READY_RESPONSED; + } else { + task->ready = QW_READY_RECEIVED; + QW_UNLOCK(QW_WRITE, &task->lock); + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; + } + +_return: + + if (task) { + QW_UNLOCK(QW_WRITE, &task->lock); + } + + if (sch) { + qwReleaseTask(QW_READ, sch); + } + + qwReleaseScheduler(QW_READ, mgmt); + + QW_RET(code); +} + +int32_t qwCheckTaskCancelDrop( SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, bool *needStop) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + int8_t status = JOB_TASK_STATUS_CANCELLED; + + *needStop = false; + + if (qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)) { + return TSDB_CODE_SUCCESS; + } + + if (qwAcquireTask(QW_READ, sch, queryId, taskId, &task)) { + qwReleaseScheduler(QW_READ, mgmt); + return TSDB_CODE_SUCCESS; + } + + QW_LOCK(QW_READ, &task->lock); + + if ((!task->cancel) && (!task->drop)) { + QW_UNLOCK(QW_READ, &task->lock); + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; + } + + QW_UNLOCK(QW_READ, &task->lock); + + *needStop = true; + + if (task->cancel) { + QW_LOCK(QW_WRITE, &task->lock); + qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &status); + QW_UNLOCK(QW_WRITE, &task->lock); + } else if (task->drop) { + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + qwDropTask(mgmt, schedulerId, queryId, taskId); + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t qwHandleFetch(SQWorkerResCache *res, SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, SRpcMsg *pMsg) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + + QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); + + QW_LOCK(QW_READ, &task->lock); + + if (task->status != JOB_TASK_STATUS_EXECUTING && task->status != JOB_TASK_STATUS_PARTIAL_SUCCEED && task->status != JOB_TASK_STATUS_SUCCEED) { + qError("invalid status %d for fetch", task->status); + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + if (QW_GOT_RES_DATA(res->data)) { + QW_ERR_JRET(qwBuildAndSendFetchRsp(pMsg, res->data)); + if (QW_LOW_RES_DATA(res->data)) { + if (task->status == JOB_TASK_STATUS_PARTIAL_SUCCEED) { + //TODO add query back to queue + } + } + } else { + if (task->status != JOB_TASK_STATUS_EXECUTING) { + qError("invalid status %d for fetch without res", task->status); + QW_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + //TODO SET FLAG FOR QUERY TO SEND RSP WHEN RES READY + } + +_return: + if (task) { + QW_UNLOCK(QW_READ, &task->lock); + } + + if (sch) { + qwReleaseTask(QW_READ, sch); + } + + qwReleaseScheduler(QW_READ, mgmt); + + QW_RET(code); +} + +int32_t qwQueryPostProcess(SQWorkerMgmt *mgmt, uint64_t schedulerId, uint64_t queryId, uint64_t taskId, int8_t status, int32_t errCode) { + SQWorkerSchStatus *sch = NULL; + SQWorkerTaskStatus *task = NULL; + int32_t code = 0; + int8_t newStatus = JOB_TASK_STATUS_CANCELLED; + + code = qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch); + if (code) { + qError("schedulerId:%"PRIx64" not in cache", schedulerId); + QW_ERR_RET(code); + } + + code = qwAcquireTask(QW_READ, sch, queryId, taskId, &task); + if (code) { + qwReleaseScheduler(QW_READ, mgmt); + qError("schedulerId:%"PRIx64" queryId:%"PRIx64" taskId:%"PRIx64" not in cache", schedulerId, queryId, taskId); + QW_ERR_RET(code); + } + + if (task->cancel) { + QW_LOCK(QW_WRITE, &task->lock); + qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &newStatus); + QW_UNLOCK(QW_WRITE, &task->lock); + } else if (task->drop) { + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + qwDropTask(mgmt, schedulerId, queryId, taskId); + + return TSDB_CODE_SUCCESS; + } else { + QW_LOCK(QW_WRITE, &task->lock); + qwUpdateTaskInfo(task, QW_TASK_INFO_STATUS, &status); + task->code = errCode; + QW_UNLOCK(QW_WRITE, &task->lock); + } + + qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); + + return TSDB_CODE_SUCCESS; +} int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt) { SQWorkerMgmt *mgmt = calloc(1, sizeof(SQWorkerMgmt)); if (NULL == mgmt) { qError("calloc %d failed", (int32_t)sizeof(SQWorkerMgmt)); - return TSDB_CODE_QRY_OUT_OF_MEMORY; + QW_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } if (cfg) { @@ -167,16 +812,16 @@ int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt) { mgmt->cfg.maxSchTaskNum = QWORKER_DEFAULT_SCH_TASK_NUMBER; } - mgmt->scheduleHash = taosHashInit(mgmt->cfg.maxSchedulerNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == mgmt->scheduleHash) { + mgmt->schHash = taosHashInit(mgmt->cfg.maxSchedulerNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_NO_LOCK); + if (NULL == mgmt->schHash) { tfree(mgmt); QW_ERR_LRET(TSDB_CODE_QRY_OUT_OF_MEMORY, "init %d schduler hash failed", mgmt->cfg.maxSchedulerNum); } - mgmt->resHash = taosHashInit(mgmt->cfg.maxResCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK); + mgmt->resHash = taosHashInit(mgmt->cfg.maxResCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK); if (NULL == mgmt->resHash) { - taosHashCleanup(mgmt->scheduleHash); - mgmt->scheduleHash = NULL; + taosHashCleanup(mgmt->schHash); + mgmt->schHash = NULL; tfree(mgmt); QW_ERR_LRET(TSDB_CODE_QRY_OUT_OF_MEMORY, "init %d res cache hash failed", mgmt->cfg.maxResCacheNum); @@ -187,99 +832,179 @@ int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt) { return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessQueryMsg(void *qWorkerMgmt, SSchedulerQueryMsg *msg, SRpcMsg *rsp) { - if (NULL == qWorkerMgmt || NULL == msg || NULL == rsp) { - return TSDB_CODE_QRY_INVALID_INPUT; +int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg **rsp) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - SSubplan *plan = NULL; - SQWorkerTaskStatus *tStatus = NULL; - - int32_t code = qStringToSubplan(msg->msg, &plan); - if (TSDB_CODE_SUCCESS != code) { - qError("schId:%"PRIx64",qId:%"PRIx64",taskId:%"PRIx64" string to subplan failed, code:%d", msg->schedulerId, msg->queryId, msg->taskId, code); - return code; + SSubQueryMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } + bool queryDone = false; + bool queryRsp = false; + bool needStop = false; + SSubplan *plan = NULL; + int32_t code = 0; + + QW_ERR_JRET(qwCheckTaskCancelDrop(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, &needStop)); + if (needStop) { + qWarn("task need stop"); + QW_ERR_RET(TSDB_CODE_QRY_TASK_CANCELLED); + } + + code = qStringToSubplan(msg->msg, &plan); + if (TSDB_CODE_SUCCESS != code) { + qError("schId:%"PRIx64",qId:%"PRIx64",taskId:%"PRIx64" string to subplan failed, code:%d", msg->schedulerId, msg->queryId, msg->taskId, code); + QW_ERR_JRET(code); + } + //TODO call executer to init subquery + code = 0; // return error directly + //TODO call executer to init subquery + + if (code) { + QW_ERR_JRET(code); + } else { + QW_ERR_JRET(qwSwitchTaskStatus(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, JOB_TASK_STATUS_EXECUTING)); + } - QW_ERR_JRET(qwAddTaskStatus(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, JOB_TASK_STATUS_EXECUTING)); - - QW_ERR_JRET(qwBuildRspMsg(NULL, TSDB_MSG_TYPE_QUERY_RSP)); + QW_ERR_JRET(qwBuildAndSendQueryRsp(pMsg, TSDB_CODE_SUCCESS)); + queryRsp = true; + //TODO call executer to execute subquery - code = 0; + code = 0; void *data = NULL; + queryDone = false; //TODO call executer to execute subquery - QW_ERR_JRET(qwGetTaskStatus(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, &tStatus)); + if (code) { + QW_ERR_JRET(code); + } else { + QW_ERR_JRET(qwAddTaskResult(qWorkerMgmt, msg->queryId, msg->taskId, data)); - tStatus->status = (code) ? JOB_TASK_STATUS_FAILED : JOB_TASK_STATUS_SUCCEED; - - QW_ERR_JRET(qwAddTaskResult(qWorkerMgmt, msg->queryId, msg->taskId, data)); + QW_ERR_JRET(qwSwitchTaskStatus(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, JOB_TASK_STATUS_PARTIAL_SUCCEED)); + } _return: - if (tStatus && QW_TASK_DONE(tStatus->status) && QW_READY_RECEIVED == tStatus->ready) { - QW_ERR_RET(qwBuildRspMsg(NULL, TSDB_MSG_TYPE_RES_READY_RSP)); + if (queryRsp) { + code = qwCheckAndSendReadyRsp(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, pMsg, code); + } else { + code = qwBuildAndSendQueryRsp(pMsg, code); } - - qDestroySubplan(plan); - return code; + int8_t status = 0; + if (TSDB_CODE_SUCCESS != code || queryDone) { + if (code) { + status = JOB_TASK_STATUS_FAILED; //TODO set CANCELLED from code + } else { + status = JOB_TASK_STATUS_SUCCEED; + } + + qwQueryPostProcess(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, status, code); + } + + QW_RET(code); } -int32_t qWorkerProcessReadyMsg(void *qWorkerMgmt, SSchedulerReadyMsg *msg, SRpcMsg *rsp){ - if (NULL == qWorkerMgmt || NULL == msg || NULL == rsp) { +int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp){ + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { return TSDB_CODE_QRY_INVALID_INPUT; } - SQWorkerTaskStatus *tStatus = NULL; - - QW_ERR_RET(qwGetTaskStatus(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, &tStatus)); - - if (QW_TASK_DONE(tStatus->status)) { - QW_ERR_RET(qwBuildRspMsg(tStatus, TSDB_MSG_TYPE_RES_READY_RSP)); - } else { - tStatus->ready = QW_READY_RECEIVED; - - return TSDB_CODE_SUCCESS; - } + SResReadyMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } - tStatus->ready = QW_READY_RESPONSED; + QW_ERR_RET(qwSetAndSendReadyRsp(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, pMsg)); return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessStatusMsg(void *qWorkerMgmt, SSchedulerStatusMsg *msg, SRpcMsg *rsp) { - if (NULL == qWorkerMgmt || NULL == msg || NULL == rsp) { +int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { return TSDB_CODE_QRY_INVALID_INPUT; } + SSchTasksStatusMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + SSchedulerStatusRsp *sStatus = NULL; QW_ERR_RET(qwGetSchTasksStatus(qWorkerMgmt, msg->schedulerId, &sStatus)); + QW_ERR_RET(qwBuildAndSendStatusRsp(pMsg, sStatus)); + return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessFetchMsg(void *qWorkerMgmt, SSchedulerFetchMsg *msg, SRpcMsg *rsp) { - if (NULL == qWorkerMgmt || NULL == msg || NULL == rsp) { +int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { return TSDB_CODE_QRY_INVALID_INPUT; } + SResFetchMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + QW_ERR_RET(qwUpdateSchLastAccess(qWorkerMgmt, msg->schedulerId)); void *data = NULL; + SQWorkerResCache *res = NULL; + int32_t code = 0; - QW_ERR_RET(qwGetTaskResult(qWorkerMgmt, msg->queryId, msg->taskId, &data)); + QW_ERR_RET(qwAcquireTaskResCache(QW_READ, qWorkerMgmt, msg->queryId, msg->taskId, &res)); - QW_ERR_RET(qwBuildRspMsg(data, TSDB_MSG_TYPE_FETCH_RSP)); + QW_ERR_JRET(qwHandleFetch(res, qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, pMsg)); + +_return: + + qwReleaseTaskResCache(QW_READ, qWorkerMgmt); + + QW_RET(code); +} + +int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { + return TSDB_CODE_QRY_INVALID_INPUT; + } + + STaskCancelMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + + QW_ERR_RET(qwCancelTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); + + QW_ERR_RET(qwBuildAndSendCancelRsp(pMsg)); + + return TSDB_CODE_SUCCESS; +} + +int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { + return TSDB_CODE_QRY_INVALID_INPUT; + } + + STaskDropMsg *msg = pMsg->pCont; + if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + + QW_ERR_RET(qwCancelDropTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); + + QW_ERR_RET(qwBuildAndSendDropRsp(pMsg)); return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessCancelMsg(void *qWorkerMgmt, SSchedulerCancelMsg *msg, SRpcMsg *rsp); void qWorkerDestroy(void **qWorkerMgmt) { if (NULL == qWorkerMgmt || NULL == *qWorkerMgmt) { diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 99a9b06fe4..6020fbaa4d 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -296,44 +296,45 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { } int32_t len = strlen(task->msg); - msgSize = sizeof(SSchedulerQueryMsg) + len; + msgSize = sizeof(SSubQueryMsg) + len + 1; msg = calloc(1, msgSize); if (NULL == msg) { qError("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SSchedulerQueryMsg *pMsg = msg; + SSubQueryMsg *pMsg = msg; pMsg->schedulerId = htobe64(schMgmt.schedulerId); pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); pMsg->contentLen = htonl(len); memcpy(pMsg->msg, task->msg, len); + pMsg->msg[len] = 0; break; } case TSDB_MSG_TYPE_RES_READY: { - msgSize = sizeof(SSchedulerReadyMsg); + msgSize = sizeof(SResReadyMsg); msg = calloc(1, msgSize); if (NULL == msg) { qError("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SSchedulerReadyMsg *pMsg = msg; + SResReadyMsg *pMsg = msg; pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); break; } case TSDB_MSG_TYPE_FETCH: { - msgSize = sizeof(SSchedulerFetchMsg); + msgSize = sizeof(SResFetchMsg); msg = calloc(1, msgSize); if (NULL == msg) { qError("calloc %d failed", msgSize); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - SSchedulerFetchMsg *pMsg = msg; + SResFetchMsg *pMsg = msg; pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); break; diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 43ac760643..65057501b9 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -323,7 +323,10 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INCONSISTAN, "File inconsistance in TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_TIME_CONDITION, "One valid time range condition expected") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_SYS_ERROR, "System error") TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_INPUT, "invalid input") - +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_SCH_NOT_EXIST, "Scheduler not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_NOT_EXIST, "Task not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_TASK_ALREADY_EXIST, "Task already exist") +TAOS_DEFINE_ERROR(TSDB_CODE_QRY_RES_CACHE_NOT_EXIST, "Task result cache not exist") // grant TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, "License expired") diff --git a/source/util/src/thash.c b/source/util/src/thash.c index c4f6f78106..cfe14f00e1 100644 --- a/source/util/src/thash.c +++ b/source/util/src/thash.c @@ -291,7 +291,7 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da // enable resize __rd_unlock(&pHashObj->lock, pHashObj->type); - return pHashObj->enableUpdate ? 0 : -1; + return pHashObj->enableUpdate ? 0 : -2; } } From 34619844bf668f3af7f77d069f43973ef707a2d9 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 01:47:21 -0800 Subject: [PATCH 14/22] fix bug while exec trans --- .clang-format | 1 + include/common/taosmsg.h | 7 - source/dnode/mgmt/impl/src/dndMnode.c | 41 ++- source/dnode/mgmt/impl/test/mnode/mnode.cpp | 342 +++++++++++--------- source/dnode/mnode/impl/src/mndMnode.c | 21 +- source/dnode/mnode/impl/src/mndTrans.c | 2 +- source/dnode/mnode/impl/src/mnode.c | 2 + source/dnode/mnode/sdb/src/sdb.c | 35 +- source/dnode/mnode/sdb/src/sdbFile.c | 28 +- 9 files changed, 263 insertions(+), 216 deletions(-) diff --git a/.clang-format b/.clang-format index 3ddd8b43f6..f60fd3cb26 100644 --- a/.clang-format +++ b/.clang-format @@ -86,5 +86,6 @@ SpacesInSquareBrackets: false Standard: Auto TabWidth: 8 UseTab: Never +AlignConsecutiveDeclarations: true ... diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index c7a521413f..b3f997ecd9 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -909,36 +909,29 @@ typedef struct SShowRsp { typedef struct { char ep[TSDB_EP_LEN]; // end point, hostname:port - int32_t reserve[8]; } SCreateDnodeMsg; typedef struct { int32_t dnodeId; - int32_t reserve[8]; } SDropDnodeMsg; typedef struct { int32_t dnodeId; char config[TSDB_DNODE_CONFIG_LEN]; - int32_t reserve[8]; } SCfgDnodeMsg; typedef struct { int32_t dnodeId; - int32_t reserve[8]; } SCreateMnodeMsg, SDropMnodeMsg; typedef struct { int32_t dnodeId; - int8_t align[3]; int8_t replica; SReplica replicas[TSDB_MAX_REPLICA]; - int32_t reserve[8]; } SCreateMnodeInMsg, SAlterMnodeInMsg; typedef struct { int32_t dnodeId; - int32_t reserve[8]; } SDropMnodeInMsg; typedef struct { diff --git a/source/dnode/mgmt/impl/src/dndMnode.c b/source/dnode/mgmt/impl/src/dndMnode.c index 3cf08e619e..4fd6b021c8 100644 --- a/source/dnode/mgmt/impl/src/dndMnode.c +++ b/source/dnode/mgmt/impl/src/dndMnode.c @@ -349,7 +349,7 @@ static void dndBuildMnodeDeployOption(SDnode *pDnode, SMnodeOpt *pOption) { SReplica *pReplica = &pOption->replicas[0]; pReplica->id = 1; pReplica->port = pDnode->opt.serverPort; - tstrncpy(pReplica->fqdn, pDnode->opt.localFqdn, TSDB_FQDN_LEN); + memcpy(pReplica->fqdn, pDnode->opt.localFqdn, TSDB_FQDN_LEN); SMnodeMgmt *pMgmt = &pDnode->mmgmt; pMgmt->selfIndex = pOption->selfIndex; @@ -376,7 +376,7 @@ static int32_t dndBuildMnodeOptionFromMsg(SDnode *pDnode, SMnodeOpt *pOption, SC SReplica *pReplica = &pOption->replicas[i]; pReplica->id = pMsg->replicas[i].id; pReplica->port = pMsg->replicas[i].port; - tstrncpy(pReplica->fqdn, pMsg->replicas[i].fqdn, TSDB_FQDN_LEN); + memcpy(pReplica->fqdn, pMsg->replicas[i].fqdn, TSDB_FQDN_LEN); if (pReplica->id == pOption->dnodeId) { pOption->selfIndex = i; } @@ -499,7 +499,7 @@ static SCreateMnodeInMsg *dndParseCreateMnodeMsg(SRpcMsg *pRpcMsg) { } static int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SCreateMnodeInMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg->pCont); + SCreateMnodeInMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { terrno = TSDB_CODE_DND_MNODE_ID_INVALID; @@ -515,18 +515,23 @@ static int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { } static int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { - SAlterMnodeInMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg->pCont); + SAlterMnodeInMsg *pMsg = dndParseCreateMnodeMsg(pRpcMsg); if (pMsg->dnodeId != dndGetDnodeId(pDnode)) { terrno = TSDB_CODE_DND_MNODE_ID_INVALID; return -1; - } else { - SMnodeOpt option = {0}; - if (dndBuildMnodeOptionFromMsg(pDnode, &option, pMsg) != 0) { - return -1; - } - return dndAlterMnode(pDnode, &option); } + + SMnodeOpt option = {0}; + if (dndBuildMnodeOptionFromMsg(pDnode, &option, pMsg) != 0) { + return -1; + } + + if (dndAlterMnode(pDnode, &option) != 0) { + return -1; + } + + return dndWriteMnodeFile(pDnode); } static int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg) { @@ -555,16 +560,17 @@ static void dndProcessMnodeMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg) { code = dndProcessDropMnodeReq(pDnode, pMsg); break; default: - code = TSDB_CODE_MSG_NOT_PROCESSED; + terrno = TSDB_CODE_MSG_NOT_PROCESSED; + code = -1; break; } if (pMsg->msgType & 1u) { + if (code != 0) code = terrno; SRpcMsg rsp = {.code = code, .handle = pMsg->handle}; rpcSendResponse(&rsp); } rpcFreeCont(pMsg->pCont); - pMsg->pCont = NULL; taosFreeQitem(pMsg); } @@ -625,8 +631,6 @@ static void dndProcessMnodeSyncQueue(SDnode *pDnode, SMnodeMsg *pMsg) { } static int32_t dndWriteMnodeMsgToQueue(SMnode *pMnode, taos_queue pQueue, SRpcMsg *pRpcMsg) { - assert(pQueue); - SMnodeMsg *pMsg = mndInitMsg(pMnode, pRpcMsg); if (pMsg == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -647,13 +651,14 @@ void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet) { SMnode *pMnode = dndAcquireMnode(pDnode); SRpcMsg *pMsg = taosAllocateQitem(sizeof(SRpcMsg)); + if (pMsg != NULL) *pMsg = *pRpcMsg; + if (pMsg == NULL || taosWriteQitem(pMgmt->pMgmtQ, pMsg) != 0) { if (pRpcMsg->msgType & 1u) { SRpcMsg rsp = {.handle = pRpcMsg->handle, .code = TSDB_CODE_OUT_OF_MEMORY}; rpcSendResponse(&rsp); } rpcFreeCont(pRpcMsg->pCont); - pRpcMsg->pCont = NULL; taosFreeQitem(pMsg); } } @@ -894,6 +899,11 @@ int32_t dndInitMnode(SDnode *pDnode) { return -1; } + if (dndAllocMnodeMgmtQueue(pDnode) != 0) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/mnode.json", pDnode->dir.dnode); pMgmt->file = strdup(path); @@ -937,6 +947,7 @@ void dndCleanupMnode(SDnode *pDnode) { dInfo("dnode-mnode start to clean up"); dndStopMnodeWorker(pDnode); dndCleanupMnodeMgmtWorker(pDnode); + dndFreeMnodeMgmtQueue(pDnode); tfree(pMgmt->file); mndClose(pMgmt->pMnode); dInfo("dnode-mnode is cleaned up"); diff --git a/source/dnode/mgmt/impl/test/mnode/mnode.cpp b/source/dnode/mgmt/impl/test/mnode/mnode.cpp index cc0d25edea..6f66a0b12f 100644 --- a/source/dnode/mgmt/impl/test/mnode/mnode.cpp +++ b/source/dnode/mgmt/impl/test/mnode/mnode.cpp @@ -70,21 +70,35 @@ TEST_F(DndTestMnode, 01_ShowDnode) { CheckTimestamp(); } -#if 0 -TEST_F(DndTestMnode, 02_ConfigDnode) { - int32_t contLen = sizeof(SCfgDnodeMsg); +TEST_F(DndTestMnode, 02_Create_Mnode_Invalid_Id) { + { + int32_t contLen = sizeof(SCreateMnodeMsg); - SCfgDnodeMsg* pReq = (SCfgDnodeMsg*)rpcMallocCont(contLen); - pReq->dnodeId = htonl(1); - strcpy(pReq->config, "ddebugflag 131"); + SCreateMnodeMsg* pReq = (SCreateMnodeMsg*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(1); - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CONFIG_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, TSDB_CODE_MND_MNODE_ALREADY_EXIST); + } } -TEST_F(DndTestMnode, 03_Create_Drop_Restart_Dnode) { +TEST_F(DndTestMnode, 03_Create_Mnode_Invalid_Id) { { + int32_t contLen = sizeof(SCreateMnodeMsg); + + SCreateMnodeMsg* pReq = (SCreateMnodeMsg*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_MNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, TSDB_CODE_MND_DNODE_NOT_EXIST); + } +} + +TEST_F(DndTestMnode, 04_Create_Mnode) { + { + // create dnode int32_t contLen = sizeof(SCreateDnodeMsg); SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); @@ -93,164 +107,172 @@ TEST_F(DndTestMnode, 03_Create_Drop_Restart_Dnode) { SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); + + taosMsleep(1300); + test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 2); } - taosMsleep(1300); - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 2); - - CheckInt16(1); - CheckInt16(2); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("localhost:9062", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(1); - CheckInt16(1); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - { - int32_t contLen = sizeof(SDropDnodeMsg); + // create mnode + int32_t contLen = sizeof(SCreateMnodeMsg); - SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(contLen); + SCreateMnodeMsg* pReq = (SCreateMnodeMsg*)rpcMallocCont(contLen); pReq->dnodeId = htonl(2); - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_DNODE, pReq, contLen); + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_MNODE, pReq, contLen); ASSERT_NE(pMsg, nullptr); ASSERT_EQ(pMsg->code, 0); + + test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 2); + + CheckInt16(1); + CheckInt16(2); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckBinary("localhost:9062", TSDB_EP_LEN); + CheckBinary("master", 12); + CheckBinary("slave", 12); + CheckInt64(0); + CheckInt64(0); + CheckTimestamp(); + CheckTimestamp(); } - - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); - - CheckInt16(1); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(1); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckBinary("", 24); - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->ep, "localhost:9063"); - - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->ep, "localhost:9064"); - - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - { - int32_t contLen = sizeof(SCreateDnodeMsg); - - SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); - strcpy(pReq->ep, "localhost:9065"); - - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 4); - - CheckInt16(1); - CheckInt16(3); - CheckInt16(4); - CheckInt16(5); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("localhost:9063", TSDB_EP_LEN); - CheckBinary("localhost:9064", TSDB_EP_LEN); - CheckBinary("localhost:9065", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(1); - CheckInt16(1); - CheckInt16(1); - CheckInt16(1); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - - // restart - uInfo("stop all server"); - test.Restart(); - server2.Restart(); - server3.Restart(); - server4.Restart(); - server5.Restart(); - - taosMsleep(1300); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); - CHECK_META("show dnodes", 7); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 4); - - CheckInt16(1); - CheckInt16(3); - CheckInt16(4); - CheckInt16(5); - CheckBinary("localhost:9061", TSDB_EP_LEN); - CheckBinary("localhost:9063", TSDB_EP_LEN); - CheckBinary("localhost:9064", TSDB_EP_LEN); - CheckBinary("localhost:9065", TSDB_EP_LEN); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(0); - CheckInt16(1); - CheckInt16(1); - CheckInt16(1); - CheckInt16(1); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckBinary("ready", 10); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckTimestamp(); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); - CheckBinary("", 24); } +// { +// int32_t contLen = sizeof(SDropDnodeMsg); -#endif \ No newline at end of file +// SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(contLen); +// pReq->dnodeId = htonl(2); + +// SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_DNODE, pReq, contLen); +// ASSERT_NE(pMsg, nullptr); +// ASSERT_EQ(pMsg->code, 0); +// } + +// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); +// CHECK_META("show dnodes", 7); +// test.SendShowRetrieveMsg(); +// EXPECT_EQ(test.GetShowRows(), 1); + +// CheckInt16(1); +// CheckBinary("localhost:9061", TSDB_EP_LEN); +// CheckInt16(0); +// CheckInt16(1); +// CheckBinary("ready", 10); +// CheckTimestamp(); +// CheckBinary("", 24); + +// { +// int32_t contLen = sizeof(SCreateDnodeMsg); + +// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); +// strcpy(pReq->ep, "localhost:9063"); + +// SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); +// ASSERT_NE(pMsg, nullptr); +// ASSERT_EQ(pMsg->code, 0); +// } + +// { +// int32_t contLen = sizeof(SCreateDnodeMsg); + +// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); +// strcpy(pReq->ep, "localhost:9064"); + +// SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); +// ASSERT_NE(pMsg, nullptr); +// ASSERT_EQ(pMsg->code, 0); +// } + +// { +// int32_t contLen = sizeof(SCreateDnodeMsg); + +// SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(contLen); +// strcpy(pReq->ep, "localhost:9065"); + +// SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_CREATE_DNODE, pReq, contLen); +// ASSERT_NE(pMsg, nullptr); +// ASSERT_EQ(pMsg->code, 0); +// } + +// taosMsleep(1300); +// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); +// CHECK_META("show dnodes", 7); +// test.SendShowRetrieveMsg(); +// EXPECT_EQ(test.GetShowRows(), 4); + +// CheckInt16(1); +// CheckInt16(3); +// CheckInt16(4); +// CheckInt16(5); +// CheckBinary("localhost:9061", TSDB_EP_LEN); +// CheckBinary("localhost:9063", TSDB_EP_LEN); +// CheckBinary("localhost:9064", TSDB_EP_LEN); +// CheckBinary("localhost:9065", TSDB_EP_LEN); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(1); +// CheckInt16(1); +// CheckInt16(1); +// CheckInt16(1); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckBinary("", 24); +// CheckBinary("", 24); +// CheckBinary("", 24); +// CheckBinary("", 24); + +// // restart +// uInfo("stop all server"); +// test.Restart(); +// server2.Restart(); +// server3.Restart(); +// server4.Restart(); +// server5.Restart(); + +// taosMsleep(1300); +// test.SendShowMetaMsg(TSDB_MGMT_TABLE_DNODE, ""); +// CHECK_META("show dnodes", 7); +// test.SendShowRetrieveMsg(); +// EXPECT_EQ(test.GetShowRows(), 4); + +// CheckInt16(1); +// CheckInt16(3); +// CheckInt16(4); +// CheckInt16(5); +// CheckBinary("localhost:9061", TSDB_EP_LEN); +// CheckBinary("localhost:9063", TSDB_EP_LEN); +// CheckBinary("localhost:9064", TSDB_EP_LEN); +// CheckBinary("localhost:9065", TSDB_EP_LEN); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(0); +// CheckInt16(1); +// CheckInt16(1); +// CheckInt16(1); +// CheckInt16(1); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckBinary("ready", 10); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckTimestamp(); +// CheckBinary("", 24); +// CheckBinary("", 24); +// CheckBinary("", 24); +// CheckBinary("", 24); +// } diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 80b4fabca9..37c9ac513a 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -31,6 +31,7 @@ static int32_t mndMnodeActionUpdate(SSdb *pSdb, SMnodeObj *pOldMnode, SMnodeObj static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg); static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg); static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg); +static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pMsg); static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg); static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta); static int32_t mndRetrieveMnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); @@ -49,6 +50,7 @@ int32_t mndInitMnode(SMnode *pMnode) { mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_MNODE, mndProcessCreateMnodeReq); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_MNODE, mndProcessDropMnodeReq); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_MNODE_IN_RSP, mndProcessCreateMnodeRsp); + mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_MNODE_IN_RSP, mndProcessAlterMnodeRsp); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_DROP_MNODE_IN_RSP, mndProcessDropMnodeRsp); mndAddShowMetaHandle(pMnode, TSDB_MGMT_TABLE_MNODE, mndGetMnodeMeta); @@ -270,6 +272,8 @@ static int32_t mndSetCreateMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDno memcpy(pReplica->fqdn, pDnode->fqdn, TSDB_FQDN_LEN); numOfReplicas++; + createMsg.replica = numOfReplicas; + while (1) { SMnodeObj *pMObj = NULL; pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); @@ -382,7 +386,7 @@ static int32_t mndProcessCreateMnodeReq(SMnodeMsg *pMsg) { SDnodeObj *pDnode = mndAcquireDnode(pMnode, pCreate->dnodeId); if (pDnode == NULL) { - mError("mnode:%d, dnode not exist", pDnode->id); + mError("mnode:%d, dnode not exist", pCreate->dnodeId); terrno = TSDB_CODE_MND_DNODE_NOT_EXIST; return -1; } @@ -560,9 +564,20 @@ static int32_t mndProcessDropMnodeReq(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg) { return 0; } +static int32_t mndProcessCreateMnodeRsp(SMnodeMsg *pMsg) { + mndTransHandleActionRsp(pMsg); + return 0; +} -static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg) { return 0; } +static int32_t mndProcessAlterMnodeRsp(SMnodeMsg *pMsg) { + mndTransHandleActionRsp(pMsg); + return 0; +} + +static int32_t mndProcessDropMnodeRsp(SMnodeMsg *pMsg) { + mndTransHandleActionRsp(pMsg); + return 0; +} static int32_t mndGetMnodeMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMeta) { SMnode *pMnode = pMsg->pMnode; diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 54cd6ab501..504717117b 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -622,7 +622,7 @@ void mndTransHandleActionRsp(SMnodeMsg *pMsg) { STransAction *pAction = taosArrayGet(pArray, action); if (pAction != NULL) { pAction->msgReceived = 1; - pAction->errCode = pMsg->code; + pAction->errCode = pMsg->rpcMsg.code; } mDebug("trans:%d, action:%d response is received, code:0x%x", transId, action, pMsg->code); diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index fb0b95dc4a..a62a0a9296 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -178,8 +178,10 @@ static int32_t mndExecSteps(SMnode *pMnode) { // (*pMnode->reportProgress)(pStep->name, "start initialize"); if ((*pStep->initFp)(pMnode) != 0) { + int32_t code = terrno; mError("step:%s exec failed since %s, start to cleanup", pStep->name, terrstr()); mndCleanupSteps(pMnode, pos); + terrno = code; return -1; } else { mDebug("step:%s is initialized", pStep->name); diff --git a/source/dnode/mnode/sdb/src/sdb.c b/source/dnode/mnode/sdb/src/sdb.c index 77614e399e..bb0e606463 100644 --- a/source/dnode/mnode/sdb/src/sdb.c +++ b/source/dnode/mnode/sdb/src/sdb.c @@ -16,6 +16,8 @@ #define _DEFAULT_SOURCE #include "sdbInt.h" +static int32_t sdbCreateDir(SSdb *pSdb); + SSdb *sdbInit(SSdbOpt *pOption) { mDebug("start to init sdb in %s", pOption->path); @@ -40,6 +42,11 @@ SSdb *sdbInit(SSdbOpt *pOption) { return NULL; } + if (sdbCreateDir(pSdb) != 0) { + sdbCleanup(pSdb); + return NULL; + } + for (ESdbType i = 0; i < SDB_MAX; ++i) { taosInitRWLatch(&pSdb->locks[i]); } @@ -53,8 +60,8 @@ void sdbCleanup(SSdb *pSdb) { mDebug("start to cleanup sdb"); // if (pSdb->curVer != pSdb->lastCommitVer) { - mDebug("write sdb file for curVer:% " PRId64 " and lastVer:%" PRId64, pSdb->curVer, pSdb->lastCommitVer); - sdbWriteFile(pSdb); + mDebug("write sdb file for curVer:% " PRId64 " and lastVer:%" PRId64, pSdb->curVer, pSdb->lastCommitVer); + sdbWriteFile(pSdb); // } if (pSdb->currDir != NULL) { @@ -133,4 +140,26 @@ int32_t sdbSetTable(SSdb *pSdb, SSdbTable table) { mDebug("sdb table:%d is initialized", sdbType); return 0; -} \ No newline at end of file +} + +static int32_t sdbCreateDir(SSdb *pSdb) { + if (taosMkDir(pSdb->currDir) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + mError("failed to create dir:%s since %s", pSdb->currDir, terrstr()); + return -1; + } + + if (taosMkDir(pSdb->syncDir) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + mError("failed to create dir:%s since %s", pSdb->syncDir, terrstr()); + return -1; + } + + if (taosMkDir(pSdb->tmpDir) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + mError("failed to create dir:%s since %s", pSdb->tmpDir, terrstr()); + return -1; + } + + return 0; +} diff --git a/source/dnode/mnode/sdb/src/sdbFile.c b/source/dnode/mnode/sdb/src/sdbFile.c index af37e9e1d5..7828e39e56 100644 --- a/source/dnode/mnode/sdb/src/sdbFile.c +++ b/source/dnode/mnode/sdb/src/sdbFile.c @@ -17,28 +17,6 @@ #include "sdbInt.h" #include "tchecksum.h" -static int32_t sdbCreateDir(SSdb *pSdb) { - if (taosMkDir(pSdb->currDir) != 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - mError("failed to create dir:%s since %s", pSdb->currDir, terrstr()); - return -1; - } - - if (taosMkDir(pSdb->syncDir) != 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - mError("failed to create dir:%s since %s", pSdb->syncDir, terrstr()); - return -1; - } - - if (taosMkDir(pSdb->tmpDir) != 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - mError("failed to create dir:%s since %s", pSdb->tmpDir, terrstr()); - return -1; - } - - return 0; -} - static int32_t sdbRunDeployFp(SSdb *pSdb) { mDebug("start to deploy sdb"); @@ -77,7 +55,7 @@ int32_t sdbReadFile(SSdb *pSdb) { free(pRaw); terrno = TAOS_SYSTEM_ERROR(errno); mError("failed to read file:%s since %s", file, terrstr()); - return -1; + return 0; } while (1) { @@ -225,10 +203,6 @@ int32_t sdbWriteFile(SSdb *pSdb) { } int32_t sdbDeploy(SSdb *pSdb) { - if (sdbCreateDir(pSdb) != 0) { - return -1; - } - if (sdbRunDeployFp(pSdb) != 0) { return -1; } From aedd147359948fd57b784c96b3da12f211e4b3f4 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 23 Dec 2021 18:18:51 +0800 Subject: [PATCH 15/22] fix tfile bug and add unit test --- source/libs/index/inc/index_tfile.h | 7 +- source/libs/index/src/index.c | 30 +- source/libs/index/src/index_cache.c | 3 +- .../index/src/index_fst_counting_writer.c | 5 +- source/libs/index/src/index_tfile.c | 37 +- source/libs/index/test/indexTests.cc | 509 ++++++++++-------- 6 files changed, 333 insertions(+), 258 deletions(-) diff --git a/source/libs/index/inc/index_tfile.h b/source/libs/index/inc/index_tfile.h index b19b887e9f..416b10bd14 100644 --- a/source/libs/index/inc/index_tfile.h +++ b/source/libs/index/inc/index_tfile.h @@ -42,7 +42,12 @@ typedef struct TFileHeader { #define TFILE_HEADER_SIZE (sizeof(TFileHeader)) #define TFILE_HEADER_NO_FST (TFILE_HEADER_SIZE - sizeof(int32_t)) -//#define TFILE_HADER_PRE_SIZE (sizeof(uint64_t) + sizeof(int32_t) + sizeof(int32_t)) + +typedef struct TFileValue { + char* colVal; // null terminated + SArray* tableId; + int32_t offset; +} TFileValue; typedef struct TFileCacheKey { uint64_t suid; diff --git a/source/libs/index/src/index.c b/source/libs/index/src/index.c index e88cecfd62..f0546afaf5 100644 --- a/source/libs/index/src/index.c +++ b/source/libs/index/src/index.c @@ -41,7 +41,7 @@ static pthread_once_t isInit = PTHREAD_ONCE_INIT; static void indexInit(); static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* term, SArray** result); -static int indexMergeCacheIntoTindex(SIndex* sIdx); +static int indexFlushCacheToTindex(SIndex* sIdx); static void indexInterResultsDestroy(SArray* results); static int indexMergeFinalResults(SArray* interResults, EIndexOperatorType oType, SArray* finalResult); @@ -49,9 +49,7 @@ static int indexMergeFinalResults(SArray* interResults, EIndexOperatorType oTyp int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) { pthread_once(&isInit, indexInit); SIndex* sIdx = calloc(1, sizeof(SIndex)); - if (sIdx == NULL) { - return -1; - } + if (sIdx == NULL) { return -1; } #ifdef USE_LUCENE index_t* index = index_open(path); @@ -131,9 +129,7 @@ int indexPut(SIndex* index, SIndexMultiTerm* fVals, uint64_t uid) { int32_t colId = fi->colId; int32_t version = index->cVersion; int ret = indexCachePut(index->cache, p, colId, version, uid); - if (ret != 0) { - return ret; - } + if (ret != 0) { return ret; } } #endif @@ -221,9 +217,7 @@ void indexOptsDestroy(SIndexOpts* opts){ SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) { SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)malloc(sizeof(SIndexMultiTermQuery)); - if (p == NULL) { - return NULL; - } + if (p == NULL) { return NULL; } p->opera = opera; p->query = taosArrayInit(4, sizeof(SIndexTermQuery)); return p; @@ -250,9 +244,7 @@ SIndexTerm* indexTermCreate(int64_t suid, const char* colVal, int32_t nColVal) { SIndexTerm* t = (SIndexTerm*)calloc(1, (sizeof(SIndexTerm))); - if (t == NULL) { - return NULL; - } + if (t == NULL) { return NULL; } t->suid = suid; t->operType = oper; @@ -332,9 +324,7 @@ static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result return 0; } static void indexInterResultsDestroy(SArray* results) { - if (results == NULL) { - return; - } + if (results == NULL) { return; } size_t sz = taosArrayGetSize(results); for (size_t i = 0; i < sz; i++) { @@ -363,10 +353,10 @@ static int indexMergeFinalResults(SArray* interResults, EIndexOperatorType oType } return 0; } -static int indexMergeCacheIntoTindex(SIndex* sIdx) { - if (sIdx == NULL) { - return -1; - } +static int indexFlushCacheToTindex(SIndex* sIdx) { + if (sIdx == NULL) { return -1; } + indexWarn("suid %" PRIu64 " merge cache into tindex", sIdx->suid); + return 0; } diff --git a/source/libs/index/src/index_cache.c b/source/libs/index/src/index_cache.c index 6170642707..bb6a5e048a 100644 --- a/source/libs/index/src/index_cache.c +++ b/source/libs/index/src/index_cache.c @@ -151,8 +151,7 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, int16_t colId, int32_t EIndexQueryType qtype = query->qType; int32_t keyLen = CACHE_KEY_LEN(term); - - char* buf = calloc(1, keyLen); + char* buf = calloc(1, keyLen); if (qtype == QUERY_TERM) { // } else if (qtype == QUERY_PREFIX) { diff --git a/source/libs/index/src/index_fst_counting_writer.c b/source/libs/index/src/index_fst_counting_writer.c index 962973bb5c..c8fbdd7690 100644 --- a/source/libs/index/src/index_fst_counting_writer.c +++ b/source/libs/index/src/index_fst_counting_writer.c @@ -69,9 +69,9 @@ WriterCtx* writerCtxCreate(WriterType type, const char* path, bool readOnly, int // ugly code, refactor later ctx->file.readOnly = readOnly; if (readOnly == false) { - ctx->file.fd = tfOpenCreateWriteAppend(tmpFile); + ctx->file.fd = tfOpenCreateWriteAppend(path); } else { - ctx->file.fd = tfOpenReadWrite(tmpFile); + ctx->file.fd = tfOpenReadWrite(path); } if (ctx->file.fd < 0) { indexError("open file error %d", errno); @@ -93,6 +93,7 @@ WriterCtx* writerCtxCreate(WriterType type, const char* path, bool readOnly, int END: if (ctx->type == TMemory) { free(ctx->mem.buf); } free(ctx); + return NULL; } void writerCtxDestroy(WriterCtx* ctx) { if (ctx->type == TMemory) { diff --git a/source/libs/index/src/index_tfile.c b/source/libs/index/src/index_tfile.c index ecacdcd13c..e02a3e0327 100644 --- a/source/libs/index/src/index_tfile.c +++ b/source/libs/index/src/index_tfile.c @@ -25,12 +25,7 @@ #define TF_TABLE_TATOAL_SIZE(sz) (sizeof(sz) + sz * sizeof(uint64_t)) -typedef struct TFileValue { - char* colVal; // null terminated - SArray* tableId; - int32_t offset; -} TFileValue; - +static int tfileStrCompare(const void* a, const void* b); static int tfileValueCompare(const void* a, const void* b, const void* param); static void tfileSerialTableIdsToBuf(char* buf, SArray* tableIds); @@ -49,6 +44,7 @@ static int tfileRmExpireFile(SArray* result); static void tfileDestroyFileName(void* elem); static int tfileCompare(const void* a, const void* b); static int tfileParseFileName(const char* filename, uint64_t* suid, int* colId, int* version); +static void tfileGenFileName(char* filename, uint64_t suid, int colId, int version); static void tfileSerialCacheKey(TFileCacheKey* key, char* buf); TFileCache* tfileCacheCreate(const char* path) { @@ -209,16 +205,28 @@ TFileWriter* tfileWriterCreate(WriterCtx* ctx, TFileHeader* header) { tw->ctx = ctx; tw->header = *header; tfileWriteHeader(tw); + tw->fb = fstBuilderCreate(ctx, 0); + if (tw->fb == NULL) { + tfileWriterDestroy(tw); + return NULL; + } return tw; } int tfileWriterPut(TFileWriter* tw, void* data) { // sort by coltype and write to tindex - __compar_fn_t fn = getComparFunc(tw->header.colType, 0); + __compar_fn_t fn; + + int8_t colType = tw->header.colType; + if (colType == TSDB_DATA_TYPE_BINARY || colType == TSDB_DATA_TYPE_NCHAR) { + fn = tfileStrCompare; + } else { + fn = getComparFunc(colType, 0); + } taosArraySortPWithExt((SArray*)(data), tfileValueCompare, &fn); int32_t bufLimit = 4096, offset = 0; - char* buf = calloc(1, sizeof(bufLimit)); + char* buf = calloc(1, sizeof(char) * bufLimit); char* p = buf; int32_t sz = taosArrayGetSize((SArray*)data); int32_t fstOffset = tw->offset; @@ -267,6 +275,9 @@ int tfileWriterPut(TFileWriter* tw, void* data) { // } } + fstBuilderFinish(tw->fb); + fstBuilderDestroy(tw->fb); + tw->fb = NULL; return 0; } void tfileWriterDestroy(TFileWriter* tw) { @@ -305,6 +316,12 @@ int indexTFilePut(void* tfile, SIndexTerm* term, uint64_t uid) { return 0; } +static int tfileStrCompare(const void* a, const void* b) { + int ret = strcmp((char*)a, (char*)b); + if (ret == 0) { return ret; } + return ret < 0 ? -1 : 1; +} + static int tfileValueCompare(const void* a, const void* b, const void* param) { __compar_fn_t fn = *(__compar_fn_t*)param; @@ -445,6 +462,10 @@ static int tfileCompare(const void* a, const void* b) { return strncmp(aName, bName, aLen > bLen ? aLen : bLen); } // tfile name suid-colId-version.tindex +static void tfileGenFileName(char* filename, uint64_t suid, int colId, int version) { + sprintf(filename, "%" PRIu64 "-%d-%d.tindex", suid, colId, version); + return; +} static int tfileParseFileName(const char* filename, uint64_t* suid, int* colId, int* version) { if (3 == sscanf(filename, "%" PRIu64 "-%d-%d.tindex", suid, colId, version)) { // read suid & colid & version success diff --git a/source/libs/index/test/indexTests.cc b/source/libs/index/test/indexTests.cc index 85d76bb716..f8dae787b8 100644 --- a/source/libs/index/test/indexTests.cc +++ b/source/libs/index/test/indexTests.cc @@ -2,8 +2,7 @@ * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. + * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -13,141 +12,141 @@ * along with this program. If not, see . */ #include -#include #include +#include #include "index.h" -#include "tutil.h" #include "indexInt.h" #include "index_fst.h" -#include "index_fst_util.h" #include "index_fst_counting_writer.h" - +#include "index_fst_util.h" +#include "index_tfile.h" +#include "tutil.h" class FstWriter { - public: - FstWriter() { - _wc = writerCtxCreate(TFile, "/tmp/tindex", false, 0); - _b = fstBuilderCreate(NULL, 0); - } - bool Put(const std::string &key, uint64_t val) { - FstSlice skey = fstSliceCreate((uint8_t *)key.c_str(), key.size()); - bool ok = fstBuilderInsert(_b, skey, val); - fstSliceDestroy(&skey); - return ok; - } - ~FstWriter() { - fstBuilderFinish(_b); - fstBuilderDestroy(_b); + public: + FstWriter() { + _wc = writerCtxCreate(TFile, "/tmp/tindex", false, 64 * 1024 * 1024); + _b = fstBuilderCreate(NULL, 0); + } + bool Put(const std::string& key, uint64_t val) { + FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size()); + bool ok = fstBuilderInsert(_b, skey, val); + fstSliceDestroy(&skey); + return ok; + } + ~FstWriter() { + fstBuilderFinish(_b); + fstBuilderDestroy(_b); - writerCtxDestroy(_wc); - } - private: - FstBuilder *_b; - WriterCtx *_wc; + writerCtxDestroy(_wc); + } + + private: + FstBuilder* _b; + WriterCtx* _wc; }; class FstReadMemory { - public: - FstReadMemory(size_t size) { - _wc = writerCtxCreate(TFile, "/tmp/tindex", true, 0); - _w = fstCountingWriterCreate(_wc); - _size = size; - memset((void *)&_s, 0, sizeof(_s)); - } - bool init() { - char *buf = (char *)calloc(1, sizeof(char) * _size); - int nRead = fstCountingWriterRead(_w, (uint8_t *)buf, _size); - if (nRead <= 0) { return false; } - _size = nRead; - _s = fstSliceCreate((uint8_t *)buf, _size); - _fst = fstCreate(&_s); - free(buf); - return _fst != NULL; - } - bool Get(const std::string &key, uint64_t *val) { - FstSlice skey = fstSliceCreate((uint8_t *)key.c_str(), key.size()); - bool ok = fstGet(_fst, &skey, val); - fstSliceDestroy(&skey); - return ok; - } - bool GetWithTimeCostUs(const std::string &key, uint64_t *val, uint64_t *elapse) { - int64_t s = taosGetTimestampUs(); - bool ok = this->Get(key, val); - int64_t e = taosGetTimestampUs(); - *elapse = e - s; - return ok; - } - // add later - bool Search(AutomationCtx *ctx, std::vector &result) { - FstStreamBuilder *sb = fstSearch(_fst, ctx); - StreamWithState *st = streamBuilderIntoStream(sb); - StreamWithStateResult *rt = NULL; - - while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { - result.push_back((uint64_t)(rt->out.out)); - } - return true; - } - bool SearchWithTimeCostUs(AutomationCtx *ctx, std::vector &result) { - int64_t s = taosGetTimestampUs(); - bool ok = this->Search(ctx, result); - int64_t e = taosGetTimestampUs(); - return ok; - } - - ~FstReadMemory() { + public: + FstReadMemory(size_t size) { + _wc = writerCtxCreate(TFile, "/tmp/tindex", true, 64 * 1024); + _w = fstCountingWriterCreate(_wc); + _size = size; + memset((void*)&_s, 0, sizeof(_s)); + } + bool init() { + char* buf = (char*)calloc(1, sizeof(char) * _size); + int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size); + if (nRead <= 0) { return false; } + _size = nRead; + _s = fstSliceCreate((uint8_t*)buf, _size); + _fst = fstCreate(&_s); + free(buf); + return _fst != NULL; + } + bool Get(const std::string& key, uint64_t* val) { + FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size()); + bool ok = fstGet(_fst, &skey, val); + fstSliceDestroy(&skey); + return ok; + } + bool GetWithTimeCostUs(const std::string& key, uint64_t* val, uint64_t* elapse) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Get(key, val); + int64_t e = taosGetTimestampUs(); + *elapse = e - s; + return ok; + } + // add later + bool Search(AutomationCtx* ctx, std::vector& result) { + FstStreamBuilder* sb = fstSearch(_fst, ctx); + StreamWithState* st = streamBuilderIntoStream(sb); + StreamWithStateResult* rt = NULL; + + while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { + result.push_back((uint64_t)(rt->out.out)); + } + return true; + } + bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector& result) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Search(ctx, result); + int64_t e = taosGetTimestampUs(); + return ok; + } + + ~FstReadMemory() { fstCountingWriterDestroy(_w); fstDestroy(_fst); fstSliceDestroy(&_s); writerCtxDestroy(_wc); - } - - private: - FstCountingWriter *_w; - Fst *_fst; - FstSlice _s; - WriterCtx *_wc; - size_t _size; - -}; + } -//TEST(IndexTest, index_create_test) { + private: + FstCountingWriter* _w; + Fst* _fst; + FstSlice _s; + WriterCtx* _wc; + size_t _size; +}; + +// TEST(IndexTest, index_create_test) { // SIndexOpts *opts = indexOptsCreate(); // SIndex *index = indexOpen(opts, "./test"); // if (index == NULL) { -// std::cout << "index open failed" << std::endl; +// std::cout << "index open failed" << std::endl; // } // -// -// // write +// +// // write // for (int i = 0; i < 100000; i++) { // SIndexMultiTerm* terms = indexMultiTermCreate(); -// std::string val = "field"; +// std::string val = "field"; // // indexMultiTermAdd(terms, "tag1", strlen("tag1"), val.c_str(), val.size()); // -// val.append(std::to_string(i)); +// val.append(std::to_string(i)); // indexMultiTermAdd(terms, "tag2", strlen("tag2"), val.c_str(), val.size()); // // val.insert(0, std::to_string(i)); // indexMultiTermAdd(terms, "tag3", strlen("tag3"), val.c_str(), val.size()); // -// val.append("const"); +// val.append("const"); // indexMultiTermAdd(terms, "tag4", strlen("tag4"), val.c_str(), val.size()); // -// +// // indexPut(index, terms, i); // indexMultiTermDestroy(terms); -// } -// +// } +// // // // query -// SIndexMultiTermQuery *multiQuery = indexMultiTermQueryCreate(MUST); -// +// SIndexMultiTermQuery *multiQuery = indexMultiTermQueryCreate(MUST); +// // indexMultiTermQueryAdd(multiQuery, "tag1", strlen("tag1"), "field", strlen("field"), QUERY_PREFIX); // indexMultiTermQueryAdd(multiQuery, "tag3", strlen("tag3"), "0field0", strlen("0field0"), QUERY_TERM); // -// SArray *result = (SArray *)taosArrayInit(10, sizeof(int)); +// SArray *result = (SArray *)taosArrayInit(10, sizeof(int)); // indexSearch(index, multiQuery, result); // // std::cout << "taos'size : " << taosArrayGetSize(result) << std::endl; @@ -155,25 +154,24 @@ class FstReadMemory { // int *v = (int *)taosArrayGet(result, i); // std::cout << "value --->" << *v << std::endl; // } -// // add more test case +// // add more test case // indexMultiTermQueryDestroy(multiQuery); // -// indexOptsDestroy(opts); -// indexClose(index); +// indexOptsDestroy(opts); +// indexClose(index); // // //} - #define L 100 #define M 100 #define N 100 -int Performance_fstWriteRecords(FstWriter *b) { - std::string str("aa"); +int Performance_fstWriteRecords(FstWriter* b) { + std::string str("aa"); for (int i = 0; i < L; i++) { str[0] = 'a' + i; - str.resize(2); - for(int j = 0; j < M; j++) { + str.resize(2); + for (int j = 0; j < M; j++) { str[1] = 'a' + j; str.resize(2); for (int k = 0; k < N; k++) { @@ -181,87 +179,86 @@ int Performance_fstWriteRecords(FstWriter *b) { b->Put(str, k); printf("(%d, %d, %d, %s)\n", i, j, k, str.c_str()); } - } + } } return L * M * N; } -void Performance_fstReadRecords(FstReadMemory *m) { +void Performance_fstReadRecords(FstReadMemory* m) { std::string str("aa"); for (int i = 0; i < M; i++) { str[0] = 'a' + i; - str.resize(2); - for(int j = 0; j < N; j++) { + str.resize(2); + for (int j = 0; j < N; j++) { str[1] = 'a' + j; str.resize(2); for (int k = 0; k < L; k++) { str.push_back('a'); - uint64_t val, cost; + uint64_t val, cost; if (m->GetWithTimeCostUs(str, &val, &cost)) { - printf("succes to get kv(%s, %" PRId64"), cost: %" PRId64"\n", str.c_str(), val, cost); + printf("succes to get kv(%s, %" PRId64 "), cost: %" PRId64 "\n", str.c_str(), val, cost); } else { printf("failed to get key: %s\n", str.c_str()); } } - } + } } } void checkFstPerf() { - FstWriter *fw = new FstWriter; - int64_t s = taosGetTimestampUs(); + FstWriter* fw = new FstWriter; + int64_t s = taosGetTimestampUs(); - int num = Performance_fstWriteRecords(fw); + int num = Performance_fstWriteRecords(fw); int64_t e = taosGetTimestampUs(); - printf("write %d record cost %" PRId64"us\n", num, e - s); + printf("write %d record cost %" PRId64 "us\n", num, e - s); delete fw; - FstReadMemory *m = new FstReadMemory(1024 * 64); - if (m->init()) { - printf("success to init fst read"); - } - Performance_fstReadRecords(m); + FstReadMemory* m = new FstReadMemory(1024 * 64); + if (m->init()) { printf("success to init fst read"); } + Performance_fstReadRecords(m); delete m; -} +} void checkFstPrefixSearch() { - FstWriter *fw = new FstWriter; - int64_t s = taosGetTimestampUs(); - int count = 2; + FstWriter* fw = new FstWriter; + int64_t s = taosGetTimestampUs(); + int count = 2; std::string key("ab"); - + for (int i = 0; i < count; i++) { - key[1] = key[1] + i; - fw->Put(key, i); + key[1] = key[1] + i; + fw->Put(key, i); } int64_t e = taosGetTimestampUs(); - + std::cout << "insert data count : " << count << "elapas time: " << e - s << std::endl; delete fw; - FstReadMemory *m = new FstReadMemory(1024 * 64); + FstReadMemory* m = new FstReadMemory(1024 * 64); if (m->init() == false) { - std::cout << "init readMemory failed" << std::endl; + std::cout << "init readMemory failed" << std::endl; delete m; return; } - - // prefix search + + // prefix search std::vector result; - AutomationCtx *ctx = automCtxCreate((void *)"ab", AUTOMATION_PREFIX); - m->Search(ctx, result); - assert(result.size() == count); + + AutomationCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_PREFIX); + m->Search(ctx, result); + assert(result.size() == count); for (int i = 0; i < result.size(); i++) { - assert(result[i] == i); // check result + assert(result[i] == i); // check result } free(ctx); delete m; -} +} void validateFst() { - int val = 100; - int count = 100; - FstWriter *fw = new FstWriter; - // write + int val = 100; + int count = 100; + FstWriter* fw = new FstWriter; + // write { std::string key("ab"); for (int i = 0; i < count; i++) { @@ -272,99 +269,161 @@ void validateFst() { delete fw; // read - FstReadMemory *m = new FstReadMemory(1024 * 64); - if (m->init() == false) { - std::cout << "init readMemory failed" << std::endl; + FstReadMemory* m = new FstReadMemory(1024 * 64); + if (m->init() == false) { + std::cout << "init readMemory failed" << std::endl; delete m; return; } { - std::string key("ab"); - uint64_t out; - if (m->Get(key, &out)) { - printf("success to get (%s, %" PRId64")\n", key.c_str(), out); - } else { - printf("failed to get(%s)\n", key.c_str()); - } - for (int i = 0; i < count; i++) { - key.push_back('a' + i); - if (m->Get(key, &out) ) { - assert(val - i == out); - printf("success to get (%s, %" PRId64")\n", key.c_str(), out); - } else { - printf("failed to get(%s)\n", key.c_str()); + std::string key("ab"); + uint64_t out; + if (m->Get(key, &out)) { + printf("success to get (%s, %" PRId64 ")\n", key.c_str(), out); + } else { + printf("failed to get(%s)\n", key.c_str()); } - } - } + for (int i = 0; i < count; i++) { + key.push_back('a' + i); + if (m->Get(key, &out)) { + assert(val - i == out); + printf("success to get (%s, %" PRId64 ")\n", key.c_str(), out); + } else { + printf("failed to get(%s)\n", key.c_str()); + } + } + } delete m; -} - -class IndexEnv : public ::testing::Test { - protected: - virtual void SetUp() { - taosRemoveDir(path); - opts = indexOptsCreate(); - int ret = indexOpen(opts, path, &index); - assert(ret == 0); - } - virtual void TearDown() { - indexClose(index); - indexOptsDestroy(opts); - } - - const char *path = "/tmp/tindex"; - SIndexOpts *opts; - SIndex *index; -}; - -TEST_F(IndexEnv, testPut) { - - // single index column - { - - std::string colName("tag1"), colVal("Hello world"); - SIndexTerm *term = indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); - SIndexMultiTerm *terms = indexMultiTermCreate(); - indexMultiTermAdd(terms, term); - - for (size_t i = 0; i < 100; i++) { - int tableId = i; - int ret = indexPut(index, terms, tableId); - assert(ret == 0); - } - indexMultiTermDestroy(terms); - } - // multi index column - { - - SIndexMultiTerm *terms = indexMultiTermCreate(); - { - std::string colName("tag1"), colVal("Hello world"); - SIndexTerm *term = indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); - indexMultiTermAdd(terms, term); - } - { - std::string colName("tag2"), colVal("Hello world"); - SIndexTerm *term = indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); - indexMultiTermAdd(terms, term); - } - - for (int i = 0; i < 100; i++) { - int tableId = i; - int ret = indexPut(index, terms, tableId); - assert(ret == 0); - } - indexMultiTermDestroy(terms); - } - // -} - -TEST_F(IndexEnv, testDel) { - } +class IndexEnv : public ::testing::Test { + protected: + virtual void SetUp() { + taosRemoveDir(path); + opts = indexOptsCreate(); + int ret = indexOpen(opts, path, &index); + assert(ret == 0); + } + virtual void TearDown() { + indexClose(index); + indexOptsDestroy(opts); + } + const char* path = "/tmp/tindex"; + SIndexOpts* opts; + SIndex* index; +}; +// TEST_F(IndexEnv, testPut) { +// // single index column +// { +// std::string colName("tag1"), colVal("Hello world"); +// SIndexTerm* term = indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), +// colVal.size()); SIndexMultiTerm* terms = indexMultiTermCreate(); indexMultiTermAdd(terms, term); +// +// for (size_t i = 0; i < 100; i++) { +// int tableId = i; +// int ret = indexPut(index, terms, tableId); +// assert(ret == 0); +// } +// indexMultiTermDestroy(terms); +// } +// // multi index column +// { +// SIndexMultiTerm* terms = indexMultiTermCreate(); +// { +// std::string colName("tag1"), colVal("Hello world"); +// SIndexTerm* term = +// indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); +// indexMultiTermAdd(terms, term); +// } +// { +// std::string colName("tag2"), colVal("Hello world"); +// SIndexTerm* term = +// indexTermCreate(0, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); +// indexMultiTermAdd(terms, term); +// } +// +// for (int i = 0; i < 100; i++) { +// int tableId = i; +// int ret = indexPut(index, terms, tableId); +// assert(ret == 0); +// } +// indexMultiTermDestroy(terms); +// } +// // +//} +class IndexTFileEnv : public ::testing::Test { + protected: + virtual void SetUp() { + taosRemoveDir(dir); + taosMkDir(dir); + tfInit(); + std::string colName("voltage"); + header.suid = 1; + header.version = 1; + memcpy(header.colName, colName.c_str(), colName.size()); + header.colType = TSDB_DATA_TYPE_BINARY; + std::string path(dir); + int colId = 2; + char buf[64] = {0}; + sprintf(buf, "%" PRIu64 "-%d-%d.tindex", header.suid, colId, header.version); + path.append("/").append(buf); + + ctx = writerCtxCreate(TFile, path.c_str(), false, 64 * 1024 * 1024); + + twrite = tfileWriterCreate(ctx, &header); + } + + virtual void TearDown() { + // indexClose(index); + // indexeptsDestroy(opts); + tfCleanup(); + tfileWriterDestroy(twrite); + } + const char* dir = "/tmp/tindex"; + WriterCtx* ctx = NULL; + TFileHeader header; + TFileWriter* twrite = NULL; +}; + +static TFileValue* genTFileValue(const char* val) { + TFileValue* tv = (TFileValue*)calloc(1, sizeof(TFileValue)); + int32_t vlen = strlen(val) + 1; + tv->colVal = (char*)calloc(1, vlen); + memcpy(tv->colVal, val, vlen); + + tv->tableId = (SArray*)taosArrayInit(1, sizeof(uint64_t)); + for (size_t i = 0; i < 10; i++) { + uint64_t v = i; + taosArrayPush(tv->tableId, &v); + } + return tv; +} +static void destroyTFileValue(void* val) { + TFileValue* tv = (TFileValue*)val; + free(tv->colVal); + taosArrayDestroy(tv->tableId); + free(tv); +} + +TEST_F(IndexTFileEnv, test_tfile_write) { + TFileValue* v1 = genTFileValue("c"); + TFileValue* v2 = genTFileValue("a"); + + SArray* data = (SArray*)taosArrayInit(4, sizeof(void*)); + + taosArrayPush(data, &v1); + taosArrayPush(data, &v2); + + tfileWriterPut(twrite, data); + // tfileWriterDestroy(twrite); + + for (size_t i = 0; i < taosArrayGetSize(data); i++) { + destroyTFileValue(taosArrayGetP(data, i)); + } + taosArrayDestroy(data); +} From 6307883ff50d467bf591ab80bb478a33a87a7823 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 23 Dec 2021 05:24:51 -0500 Subject: [PATCH 16/22] TD-12450 perfect parser interface --- include/libs/parser/parsenodes.h | 1 + source/client/src/clientImpl.c | 4 ++-- source/libs/parser/src/astValidate.c | 18 +++++++++--------- source/libs/parser/src/parser.c | 10 ++++++---- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/libs/parser/parsenodes.h b/include/libs/parser/parsenodes.h index 2ec2c0218f..250739c1e6 100644 --- a/include/libs/parser/parsenodes.h +++ b/include/libs/parser/parsenodes.h @@ -162,6 +162,7 @@ typedef struct SInsertStmtInfo { typedef struct SDclStmtInfo { int16_t nodeType; + int16_t msgType; char* pMsg; int32_t msgLen; } SDclStmtInfo; diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 5422250936..992d93f39b 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -155,13 +155,13 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { int32_t code = qParseQuerySql(&cxt, &pQuery); if (qIsDclQuery(pQuery)) { SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery; - pRequest->type = pDcl->nodeType; + pRequest->type = pDcl->msgType; pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = pDcl->pMsg, .len = pDcl->msgLen}; SRequestMsgBody body = buildRequestMsgImpl(pRequest); SEpSet* pEpSet = &pTscObj->pAppInfo->mgmtEp.epSet; - if (pDcl->nodeType == TSDB_MSG_TYPE_CREATE_TABLE) { + if (pDcl->msgType == TSDB_MSG_TYPE_CREATE_TABLE) { struct SCatalog* pCatalog = NULL; char buf[12] = {0}; diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index da1fe2e868..5d64323332 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -4358,7 +4358,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm } pDcl->pMsg = (char*)buildUserManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); - pDcl->nodeType = (pInfo->type == TSDB_SQL_CREATE_USER)? TSDB_MSG_TYPE_CREATE_USER:TSDB_MSG_TYPE_ALTER_USER; + pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_USER)? TSDB_MSG_TYPE_CREATE_USER:TSDB_MSG_TYPE_ALTER_USER; break; } @@ -4395,20 +4395,20 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm } pDcl->pMsg = (char*)buildAcctManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); - pDcl->nodeType = (pInfo->type == TSDB_SQL_CREATE_ACCT)? TSDB_MSG_TYPE_CREATE_ACCT:TSDB_MSG_TYPE_ALTER_ACCT; + pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_ACCT)? TSDB_MSG_TYPE_CREATE_ACCT:TSDB_MSG_TYPE_ALTER_ACCT; break; } case TSDB_SQL_DROP_ACCT: case TSDB_SQL_DROP_USER: { pDcl->pMsg = (char*)buildDropUserMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); - pDcl->nodeType = (pInfo->type == TSDB_SQL_DROP_ACCT)? TSDB_MSG_TYPE_DROP_ACCT:TSDB_MSG_TYPE_DROP_USER; + pDcl->msgType = (pInfo->type == TSDB_SQL_DROP_ACCT)? TSDB_MSG_TYPE_DROP_ACCT:TSDB_MSG_TYPE_DROP_USER; break; } case TSDB_SQL_SHOW: { code = setShowInfo(&pInfo->pMiscInfo->showOpt, pCtx, (void**)&pDcl->pMsg, &pDcl->msgLen, pMsgBuf); - pDcl->nodeType = TSDB_MSG_TYPE_SHOW; + pDcl->msgType = TSDB_MSG_TYPE_SHOW; break; } @@ -4431,7 +4431,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm pDcl->pMsg = (char*)pUseDbMsg; pDcl->msgLen = sizeof(SUseDbMsg); - pDcl->nodeType = TSDB_MSG_TYPE_USE_DB; + pDcl->msgType = TSDB_MSG_TYPE_USE_DB; break; } @@ -4461,7 +4461,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm pDcl->pMsg = (char*)pCreateMsg; pDcl->msgLen = sizeof(SCreateDbMsg); - pDcl->nodeType = (pInfo->type == TSDB_SQL_CREATE_DB)? TSDB_MSG_TYPE_CREATE_DB:TSDB_MSG_TYPE_ALTER_DB; + pDcl->msgType = (pInfo->type == TSDB_SQL_CREATE_DB)? TSDB_MSG_TYPE_CREATE_DB:TSDB_MSG_TYPE_ALTER_DB; break; } @@ -4483,7 +4483,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm pDropDbMsg->ignoreNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0; assert(code == TSDB_CODE_SUCCESS && name.type == TSDB_DB_NAME_T); - pDcl->nodeType = TSDB_MSG_TYPE_DROP_DB; + pDcl->msgType = TSDB_MSG_TYPE_DROP_DB; pDcl->msgLen = sizeof(SDropDbMsg); pDcl->pMsg = (char*)pDropDbMsg; return TSDB_CODE_SUCCESS; @@ -4497,7 +4497,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm return code; } pDcl->pMsg = (char*)buildCreateTableMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf); - pDcl->nodeType = (pCreateTable->type == TSQL_CREATE_TABLE)? TSDB_MSG_TYPE_CREATE_TABLE:TSDB_MSG_TYPE_CREATE_STB; + pDcl->msgType = (pCreateTable->type == TSQL_CREATE_TABLE)? TSDB_MSG_TYPE_CREATE_TABLE:TSDB_MSG_TYPE_CREATE_STB; } else if (pCreateTable->type == TSQL_CREATE_CTABLE) { // if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) { // return code; @@ -4517,7 +4517,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStm return terrno; } - pDcl->nodeType = TSDB_MSG_TYPE_DROP_STB; + pDcl->msgType = TSDB_MSG_TYPE_DROP_STB; return TSDB_CODE_SUCCESS; break; } diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 25f18ad6f2..9922642df3 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -32,10 +32,7 @@ bool isInsertSql(const char* pStr, size_t length) { } bool qIsDclQuery(const SQueryNode* pQuery) { - int16_t type = pQuery->type; - return type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER || - type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT || - type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB; + return TSDB_SQL_INSERT != pQuery->type && TSDB_SQL_SELECT != pQuery->type; } int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { @@ -48,6 +45,11 @@ int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { if (!isDqlSqlStatement(&info)) { SDclStmtInfo* pDcl = calloc(1, sizeof(SQueryStmtInfo)); + if (NULL == pDcl) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; // set correct error code. + return terrno; + } + pDcl->nodeType = info.type; int32_t code = qParserValidateDclSqlNode(&info, &pCxt->ctx, pDcl, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { *pQuery = (SQueryNode*)pDcl; From 829fd712f7ffeedef426fecde39c02f4bc773ed2 Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Thu, 23 Dec 2021 19:49:34 +0800 Subject: [PATCH 17/22] simulate a raft KVStore, for self testing --- contrib/test/craft/common.h | 23 ++- contrib/test/craft/raftMain.c | 297 +++++++++++++++++++++++++++++--- contrib/test/craft/raftServer.c | 97 +++++++++-- contrib/test/craft/raftServer.h | 25 ++- 4 files changed, 402 insertions(+), 40 deletions(-) diff --git a/contrib/test/craft/common.h b/contrib/test/craft/common.h index 670e5fb927..1e94ee8bca 100644 --- a/contrib/test/craft/common.h +++ b/contrib/test/craft/common.h @@ -5,11 +5,28 @@ extern "C" { #endif -#define COMMAND_LEN 256 -#define DIR_LEN 128 -#define HOST_LEN 128 +#include + +#define MAX_PEERS 10 +#define COMMAND_LEN 512 +#define TOKEN_LEN 128 +#define DIR_LEN 256 +#define HOST_LEN 64 #define ADDRESS_LEN (HOST_LEN + 16) +typedef struct { + char host[HOST_LEN]; + uint32_t port; +} Addr; + +typedef struct { + Addr me; + Addr peers[MAX_PEERS]; + int peersCount; + char dir[DIR_LEN]; + char dataDir[DIR_LEN + HOST_LEN * 2]; +} SRaftServerConfig; + #ifdef __cplusplus } #endif diff --git a/contrib/test/craft/raftMain.c b/contrib/test/craft/raftMain.c index 9d00cb4f70..52e0b694dc 100644 --- a/contrib/test/craft/raftMain.c +++ b/contrib/test/craft/raftMain.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,67 @@ const char *exe_name; +void parseAddr(const char *addr, char *host, int len, uint32_t *port) { + char* tmp = (char*)malloc(strlen(addr) + 1); + strcpy(tmp, addr); + + char* context; + char* separator = ":"; + char* token = strtok_r(tmp, separator, &context); + if (token) { + snprintf(host, len, "%s", token); + } + + token = strtok_r(NULL, separator, &context); + if (token) { + sscanf(token, "%u", port); + } + + free(tmp); +} + +// only parse 3 tokens +int parseCommand(const char* str, char* token1, char* token2, char* token3, int len) +{ + char* tmp = (char*)malloc(strlen(str) + 1); + strcpy(tmp, str); + + char* context; + char* separator = " "; + int n = 0; + + char* token = strtok_r(tmp, separator, &context); + if (!token) { + goto ret; + } + if (strcmp(token, "") != 0) { + strncpy(token1, token, len); + n++; + } + + token = strtok_r(NULL, separator, &context); + if (!token) { + goto ret; + } + if (strcmp(token, "") != 0) { + strncpy(token2, token, len); + n++; + } + + token = strtok_r(NULL, separator, &context); + if (!token) { + goto ret; + } + if (strcmp(token, "") != 0) { + strncpy(token3, token, len); + n++; + } + +ret: + return n; + free(tmp); +} + void *startServerFunc(void *param) { SRaftServer *pServer = (SRaftServer*)param; int32_t r = raftServerStart(pServer); @@ -22,6 +84,86 @@ void *startServerFunc(void *param) { } // Console --------------------------------- +const char* state2String(unsigned short state) { + if (state == RAFT_UNAVAILABLE) { + return "RAFT_UNAVAILABLE"; + + } else if (state == RAFT_FOLLOWER) { + return "RAFT_FOLLOWER"; + + } else if (state == RAFT_CANDIDATE) { + return "RAFT_CANDIDATE"; + + } else if (state == RAFT_LEADER) { + return "RAFT_LEADER"; + + } + return "UNKNOWN_RAFT_STATE"; +} + +void printRaftConfiguration(struct raft_configuration *c) { + printf("configuration: \n"); + for (int i = 0; i < c->n; ++i) { + printf("%llu -- %d -- %s\n", c->servers->id, c->servers->role, c->servers->address); + } +} + +void printRaftState(struct raft *r) { + printf("----Raft State: -----------\n"); + printf("my_id: %llu \n", r->id); + printf("address: %s \n", r->address); + printf("current_term: %llu \n", r->current_term); + printf("voted_for: %llu \n", r->voted_for); + printf("role: %s \n", state2String(r->state)); + printf("commit_index: %llu \n", r->commit_index); + printf("last_applied: %llu \n", r->last_applied); + printf("last_stored: %llu \n", r->last_stored); + + /* + printf("configuration_index: %llu \n", r->configuration_index); + printf("configuration_uncommitted_index: %llu \n", r->configuration_uncommitted_index); + printRaftConfiguration(&r->configuration); + */ + + printf("----------------------------\n"); +} + +void putValueCb(struct raft_apply *req, int status, void *result) { + raft_free(req); + struct raft *r = req->data; + if (status != 0) { + printf("putValueCb: %s \n", raft_errmsg(r)); + } else { + printf("putValueCb: %s \n", "ok"); + } +} + +void putValue(struct raft *r, const char *value) { + struct raft_buffer buf; + + buf.len = TOKEN_LEN;; + buf.base = raft_malloc(buf.len); + snprintf(buf.base, buf.len, "%s", value); + + struct raft_apply *req = raft_malloc(sizeof(struct raft_apply)); + req->data = r; + int ret = raft_apply(r, req, &buf, 1, putValueCb); + if (ret == 0) { + printf("put %s \n", (char*)buf.base); + } else { + printf("put error: %s \n", raft_errmsg(r)); + } +} + +void getValue(const char *key) { + char *ptr = getKV(key); + if (ptr) { + printf("get value: [%s] \n", ptr); + } else { + printf("value not found for key: [%s] \n", key); + } +} + void console(SRaftServer *pRaftServer) { while (1) { char cmd_buf[COMMAND_LEN]; @@ -40,7 +182,68 @@ void console(SRaftServer *pRaftServer) { continue; } - printf("cmd_buf: [%s] \n", cmd_buf); + char cmd[TOKEN_LEN]; + memset(cmd, 0, sizeof(cmd)); + + char param1[TOKEN_LEN]; + memset(param1, 0, sizeof(param1)); + + char param2[TOKEN_LEN]; + memset(param2, 0, sizeof(param2)); + + parseCommand(cmd_buf, cmd, param1, param2, TOKEN_LEN); + if (strcmp(cmd, "addnode") == 0) { + printf("not support \n"); + + /* + char host[HOST_LEN]; + uint32_t port; + parseAddr(param1, host, HOST_LEN, &port); + uint64_t rid = raftId(host, port); + + struct raft_change *req = raft_malloc(sizeof(*req)); + int r = raft_add(&pRaftServer->raft, req, rid, param1, NULL); + if (r != 0) { + printf("raft_add: %s \n", raft_errmsg(&pRaftServer->raft)); + } + printf("add node: %lu %s \n", rid, param1); + + struct raft_change *req2 = raft_malloc(sizeof(*req2)); + r = raft_assign(&pRaftServer->raft, req2, rid, RAFT_VOTER, NULL); + if (r != 0) { + printf("raft_assign: %s \n", raft_errmsg(&pRaftServer->raft)); + } + */ + + } else if (strcmp(cmd, "dropnode") == 0) { + printf("not support \n"); + + } else if (strcmp(cmd, "put") == 0) { + char buf[256]; + snprintf(buf, sizeof(buf), "%s--%s", param1, param2); + putValue(&pRaftServer->raft, buf); + + } else if (strcmp(cmd, "get") == 0) { + getValue(param1); + + } else if (strcmp(cmd, "state") == 0) { + printRaftState(&pRaftServer->raft); + + } else if (strcmp(cmd, "snapshot") == 0) { + printf("not support \n"); + + } else if (strcmp(cmd, "help") == 0) { + printf("addnode \"127.0.0.1:8888\" \n"); + printf("dropnode \"127.0.0.1:8888\" \n"); + printf("put key value \n"); + printf("get key \n"); + printf("state \n"); + + } else { + printf("unknown command: [%s], type \"help\" to see help \n", cmd); + } + + //printf("cmd_buf: [%s] \n", cmd_buf); } } @@ -51,38 +254,86 @@ void *startConsoleFunc(void *param) { } // Config --------------------------------- -typedef struct SRaftServerConfig { - char host[HOST_LEN]; - uint32_t port; - char dir[DIR_LEN]; -} SRaftServerConfig; +void usage() { + printf("\nusage: \n"); + printf("%s --me=127.0.0.1:10000 --dir=./data \n", exe_name); + printf("\n"); + printf("%s --me=127.0.0.1:10000 --peers=127.0.0.1:10001,127.0.0.1:10002 --dir=./data \n", exe_name); + printf("%s --me=127.0.0.1:10001 --peers=127.0.0.1:10000,127.0.0.1:10002 --dir=./data \n", exe_name); + printf("%s --me=127.0.0.1:10002 --peers=127.0.0.1:10000,127.0.0.1:10001 --dir=./data \n", exe_name); + printf("\n"); +} void parseConf(int argc, char **argv, SRaftServerConfig *pConf) { - snprintf(pConf->host, sizeof(pConf->host), "%s", argv[1]); - sscanf(argv[2], "%u", &pConf->port); - snprintf(pConf->dir, sizeof(pConf->dir), "%s", argv[3]); + memset(pConf, 0, sizeof(*pConf)); + + int option_index, option_value; + option_index = 0; + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"peers", required_argument, NULL, 'p'}, + {"me", required_argument, NULL, 'm'}, + {"dir", required_argument, NULL, 'd'}, + {NULL, 0, NULL, 0} + }; + + while ((option_value = getopt_long(argc, argv, "hp:m:d:", long_options, &option_index)) != -1) { + switch (option_value) { + case 'm': { + parseAddr(optarg, pConf->me.host, sizeof(pConf->me.host), &pConf->me.port); + break; + } + + case 'p': { + char tokens[MAX_PEERS][MAX_TOKEN_LEN]; + int peerCount = splitString(optarg, ",", tokens, MAX_PEERS); + pConf->peersCount = peerCount; + for (int i = 0; i < peerCount; ++i) { + Addr *pAddr = &pConf->peers[i]; + parseAddr(tokens[i], pAddr->host, sizeof(pAddr->host), &pAddr->port); + } + break; + } + + + case 'd': { + snprintf(pConf->dir, sizeof(pConf->dir), "%s", optarg); + break; + } + + case 'h': { + usage(); + exit(-1); + } + + default: { + usage(); + exit(-1); + } + } + } + snprintf(pConf->dataDir, sizeof(pConf->dataDir), "%s/%s:%u", pConf->dir, pConf->me.host, pConf->me.port); } void printConf(SRaftServerConfig *pConf) { - printf("conf: %s:%u %s \n", pConf->host, pConf->port, pConf->dir); + printf("\nconf: \n"); + printf("me: %s:%u \n", pConf->me.host, pConf->me.port); + printf("peersCount: %d \n", pConf->peersCount); + for (int i = 0; i < pConf->peersCount; ++i) { + Addr *pAddr = &pConf->peers[i]; + printf("peer%d: %s:%u \n", i, pAddr->host, pAddr->port); + } + printf("dataDir: %s \n\n", pConf->dataDir); + } -// ----------------------------------------- -void usage() { - printf("\n"); - printf("usage: %s host port dir \n", exe_name); - printf("\n"); - printf("eg: \n"); - printf("%s 127.0.0.1 10000 ./data \n", exe_name); - printf("\n"); -} int main(int argc, char **argv) { srand(time(NULL)); int32_t ret; exe_name = argv[0]; - if (argc != 4) { + if (argc < 3) { usage(); exit(-1); } @@ -91,11 +342,15 @@ int main(int argc, char **argv) { parseConf(argc, argv, &conf); printConf(&conf); + char cmd_buf[COMMAND_LEN]; + snprintf(cmd_buf, sizeof(cmd_buf), "mkdir -p %s", conf.dataDir); + system(cmd_buf); + struct raft_fsm fsm; initFsm(&fsm); SRaftServer raftServer; - ret = raftServerInit(&raftServer, conf.host, conf.port, conf.dir, &fsm); + ret = raftServerInit(&raftServer, &conf, &fsm); assert(ret == 0); pthread_t tidRaftServer; diff --git a/contrib/test/craft/raftServer.c b/contrib/test/craft/raftServer.c index 4a4d6cb7a3..6f4dbc1997 100644 --- a/contrib/test/craft/raftServer.c +++ b/contrib/test/craft/raftServer.c @@ -2,6 +2,70 @@ #include "common.h" #include "raftServer.h" +char *keys; +char *values; + +void initStore() { + keys = malloc(MAX_RECORD_COUNT * MAX_KV_LEN); + values = malloc(MAX_RECORD_COUNT * MAX_KV_LEN); + writeIndex = 0; +} + +void destroyStore() { + free(keys); + free(values); +} + +void putKV(const char *key, const char *value) { + if (writeIndex < MAX_RECORD_COUNT) { + strncpy(&keys[writeIndex], key, MAX_KV_LEN); + strncpy(&values[writeIndex], value, MAX_KV_LEN); + writeIndex++; + } +} + +char *getKV(const char *key) { + for (int i = 0; i < MAX_RECORD_COUNT; ++i) { + if (strcmp(&keys[i], key) == 0) { + return &values[i]; + } + } + return NULL; +} + + +int splitString(const char* str, char* separator, char (*arr)[MAX_TOKEN_LEN], int n_arr) +{ + if (n_arr <= 0) { + return -1; + } + + char* tmp = (char*)malloc(strlen(str) + 1); + strcpy(tmp, str); + char* context; + int n = 0; + + char* token = strtok_r(tmp, separator, &context); + if (!token) { + goto ret; + } + strncpy(arr[n], token, MAX_TOKEN_LEN); + n++; + + while (1) { + token = strtok_r(NULL, separator, &context); + if (!token || n >= n_arr) { + goto ret; + } + strncpy(arr[n], token, MAX_TOKEN_LEN); + n++; + } + +ret: + free(tmp); + return n; +} + uint64_t raftId(const char *host, uint32_t port) { uint32_t host_uint32 = (uint32_t)inet_addr(host); assert(host_uint32 != (uint32_t)-1); @@ -9,17 +73,13 @@ uint64_t raftId(const char *host, uint32_t port) { return code; } -int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port, const char *dir, struct raft_fsm *pFsm) { +int32_t raftServerInit(SRaftServer *pRaftServer, const SRaftServerConfig *pConf, struct raft_fsm *pFsm) { int ret; - char cmd_buf[COMMAND_LEN]; - snprintf(cmd_buf, sizeof(cmd_buf), "mkdir -p %s", dir); - system(cmd_buf); - - snprintf(pRaftServer->host, sizeof(pRaftServer->host), "%s", host); - pRaftServer->port = port; - snprintf(pRaftServer->address, sizeof(pRaftServer->address), "%s:%u", host, port); - strncpy(pRaftServer->dir, dir, sizeof(pRaftServer->dir)); + snprintf(pRaftServer->host, sizeof(pRaftServer->host), "%s", pConf->me.host); + pRaftServer->port = pConf->me.port; + snprintf(pRaftServer->address, sizeof(pRaftServer->address), "%s:%u", pRaftServer->host, pRaftServer->port); + strncpy(pRaftServer->dir, pConf->dataDir, sizeof(pRaftServer->dir)); pRaftServer->raftId = raftId(pRaftServer->host, pRaftServer->port); pRaftServer->fsm = pFsm; @@ -34,7 +94,7 @@ int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); } - ret = raft_uv_init(&pRaftServer->io, &pRaftServer->loop, dir, &pRaftServer->transport); + ret = raft_uv_init(&pRaftServer->io, &pRaftServer->loop, pRaftServer->dir, &pRaftServer->transport); if (!ret) { fprintf(stderr, "%s \n", raft_errmsg(&pRaftServer->raft)); } @@ -47,6 +107,16 @@ int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port struct raft_configuration conf; raft_configuration_init(&conf); raft_configuration_add(&conf, pRaftServer->raftId, pRaftServer->address, RAFT_VOTER); + printf("add myself: %llu - %s \n", pRaftServer->raftId, pRaftServer->address); + for (int i = 0; i < pConf->peersCount; ++i) { + const Addr *pAddr = &pConf->peers[i]; + raft_id rid = raftId(pAddr->host, pAddr->port); + char addrBuf[ADDRESS_LEN]; + snprintf(addrBuf, sizeof(addrBuf), "%s:%u", pAddr->host, pAddr->port); + raft_configuration_add(&conf, rid, addrBuf, RAFT_VOTER); + printf("add peers: %llu - %s \n", rid, addrBuf); + } + raft_bootstrap(&pRaftServer->raft, &conf); return 0; @@ -70,12 +140,17 @@ void raftServerClose(SRaftServer *pRaftServer) { int fsmApplyCb(struct raft_fsm *pFsm, const struct raft_buffer *buf, void **result) { char *msg = (char*)buf->base; - printf("%s \n", msg); + printf("fsm apply: %s \n", msg); + + char arr[2][MAX_TOKEN_LEN]; + splitString(msg, "--", arr, 2); + putKV(arr[0], arr[1]); return 0; } int32_t initFsm(struct raft_fsm *fsm) { + initStore(); fsm->apply = fsmApplyCb; return 0; } diff --git a/contrib/test/craft/raftServer.h b/contrib/test/craft/raftServer.h index 44cfa54dfe..5fccde6bf2 100644 --- a/contrib/test/craft/raftServer.h +++ b/contrib/test/craft/raftServer.h @@ -11,12 +11,23 @@ extern "C" { #include #include "raft.h" #include "raft/uv.h" +#include "common.h" + + +// simulate a db store, just for test +#define MAX_KV_LEN 100 +#define MAX_RECORD_COUNT 500 +char *keys; +char *values; +int writeIndex; + +void initStore(); +void destroyStore(); +void putKV(const char *key, const char *value); +char *getKV(const char *key); -#define DIR_LEN 128 -#define HOST_LEN 128 -#define ADDRESS_LEN (HOST_LEN + 16) typedef struct { - char dir[DIR_LEN]; /* Data dir of UV I/O backend */ + char dir[DIR_LEN + HOST_LEN * 2]; /* Data dir of UV I/O backend */ char host[HOST_LEN]; uint32_t port; char address[ADDRESS_LEN]; /* Raft instance address */ @@ -29,7 +40,11 @@ typedef struct { struct raft_uv_transport transport; /* UV I/O backend transport */ } SRaftServer; -int32_t raftServerInit(SRaftServer *pRaftServer, const char *host, uint32_t port, const char *dir, struct raft_fsm *pFsm); +#define MAX_TOKEN_LEN 32 +int splitString(const char* str, char* separator, char (*arr)[MAX_TOKEN_LEN], int n_arr); + +uint64_t raftId(const char *host, uint32_t port); +int32_t raftServerInit(SRaftServer *pRaftServer, const SRaftServerConfig *pConf, struct raft_fsm *pFsm); int32_t raftServerStart(SRaftServer *pRaftServer); void raftServerClose(SRaftServer *pRaftServer); From a9d13928dde02f233b26c9b7ce1340248f8245e6 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 03:59:42 -0800 Subject: [PATCH 18/22] fix bug in transaction --- source/dnode/mgmt/impl/src/dndMnode.c | 6 +++++- source/dnode/mgmt/impl/src/dndTransport.c | 4 ++-- source/dnode/mgmt/impl/test/mnode/mnode.cpp | 22 +++++++++++++++++++++ source/dnode/mnode/impl/inc/mndDef.h | 5 ----- source/dnode/mnode/impl/src/mndDb.c | 8 ++++---- source/dnode/mnode/impl/src/mndMnode.c | 6 ++++-- source/dnode/mnode/impl/src/mndTrans.c | 5 +++-- source/util/src/tworker.c | 2 ++ 8 files changed, 42 insertions(+), 16 deletions(-) diff --git a/source/dnode/mgmt/impl/src/dndMnode.c b/source/dnode/mgmt/impl/src/dndMnode.c index 4fd6b021c8..c4d69c4626 100644 --- a/source/dnode/mgmt/impl/src/dndMnode.c +++ b/source/dnode/mgmt/impl/src/dndMnode.c @@ -479,9 +479,11 @@ static int32_t dndDropMnode(SDnode *pDnode) { return -1; } + dndReleaseMnode(pDnode, pMnode); dndStopMnodeWorker(pDnode); dndWriteMnodeFile(pDnode); mndClose(pMnode); + pMgmt->pMnode = NULL; mndDestroy(pDnode->dir.mnode); return 0; @@ -661,6 +663,8 @@ void dndProcessMnodeMgmtMsg(SDnode *pDnode, SRpcMsg *pRpcMsg, SEpSet *pEpSet) { rpcFreeCont(pRpcMsg->pCont); taosFreeQitem(pMsg); } + + dndReleaseMnode(pDnode, pMnode); } void dndProcessMnodeWriteMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { @@ -945,7 +949,7 @@ void dndCleanupMnode(SDnode *pDnode) { SMnodeMgmt *pMgmt = &pDnode->mmgmt; dInfo("dnode-mnode start to clean up"); - dndStopMnodeWorker(pDnode); + if (pMgmt->pMnode) dndStopMnodeWorker(pDnode); dndCleanupMnodeMgmtWorker(pDnode); dndFreeMnodeMgmtQueue(pDnode); tfree(pMgmt->file); diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index be60d2fcae..69db619aaa 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -136,7 +136,7 @@ static void dndProcessResponse(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) { DndMsgFp fp = pMgmt->msgFp[msgType]; if (fp != NULL) { (*fp)(pDnode, pMsg, pEpSet); - dTrace("RPC %p, rsp:%s is processed, code:0x%0X", pMsg->handle, taosMsg[msgType], pMsg->code & 0XFFFF); + dTrace("RPC %p, rsp:%s is processed, code:0x%x", pMsg->handle, taosMsg[msgType], pMsg->code & 0XFFFF); } else { dError("RPC %p, rsp:%s not processed", pMsg->handle, taosMsg[msgType]); rpcFreeCont(pMsg->pCont); @@ -184,7 +184,7 @@ static void dndProcessRequest(void *param, SRpcMsg *pMsg, SEpSet *pEpSet) { int32_t msgType = pMsg->msgType; if (msgType == TSDB_MSG_TYPE_NETWORK_TEST) { - dTrace("RPC %p, network test req, app:%p will be processed", pMsg->handle, pMsg->ahandle); + dTrace("RPC %p, network test req, app:%p will be processed, code:0x%x", pMsg->handle, pMsg->ahandle, pMsg->code); dndProcessDnodeReq(pDnode, pMsg, pEpSet); return; } diff --git a/source/dnode/mgmt/impl/test/mnode/mnode.cpp b/source/dnode/mgmt/impl/test/mnode/mnode.cpp index 6f66a0b12f..6724c85500 100644 --- a/source/dnode/mgmt/impl/test/mnode/mnode.cpp +++ b/source/dnode/mgmt/impl/test/mnode/mnode.cpp @@ -140,6 +140,28 @@ TEST_F(DndTestMnode, 04_Create_Mnode) { CheckTimestamp(); CheckTimestamp(); } + + { + // drop mnode + int32_t contLen = sizeof(SDropMnodeMsg); + + SDropMnodeMsg* pReq = (SDropMnodeMsg*)rpcMallocCont(contLen); + pReq->dnodeId = htonl(2); + + SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_MNODE, pReq, contLen); + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + + test.SendShowMetaMsg(TSDB_MGMT_TABLE_MNODE, ""); + test.SendShowRetrieveMsg(); + EXPECT_EQ(test.GetShowRows(), 1); + + CheckInt16(1); + CheckBinary("localhost:9061", TSDB_EP_LEN); + CheckBinary("master", 12); + CheckInt64(0); + CheckTimestamp(); + } } // { // int32_t contLen = sizeof(SDropDnodeMsg); diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index da54920574..a0404d5bcc 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -290,11 +290,6 @@ typedef struct SMnodeMsg { char db[TSDB_FULL_DB_NAME_LEN]; int32_t acctId; SMnode *pMnode; - int16_t received; - int16_t successed; - int16_t expected; - int16_t retry; - int32_t code; int64_t createdTime; SRpcMsg rpcMsg; int32_t contLen; diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 108896c121..dd474d85f3 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -828,9 +828,9 @@ static int32_t mndProcessUseDbMsg(SMnodeMsg *pMsg) { static int32_t mndProcessSyncDbMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SSyncDbMsg *pSync = pMsg->rpcMsg.pCont; - SDbObj *pDb = mndAcquireDb(pMnode, pMsg->db); + SDbObj *pDb = mndAcquireDb(pMnode, pSync->db); if (pDb == NULL) { - mError("db:%s, failed to process sync db msg since %s", pMsg->db, terrstr()); + mError("db:%s, failed to process sync db msg since %s", pSync->db, terrstr()); return -1; } @@ -841,9 +841,9 @@ static int32_t mndProcessSyncDbMsg(SMnodeMsg *pMsg) { static int32_t mndProcessCompactDbMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SCompactDbMsg *pCompact = pMsg->rpcMsg.pCont; - SDbObj *pDb = mndAcquireDb(pMnode, pMsg->db); + SDbObj *pDb = mndAcquireDb(pMnode, pCompact->db); if (pDb == NULL) { - mError("db:%s, failed to process compact db msg since %s", pMsg->db, terrstr()); + mError("db:%s, failed to process compact db msg since %s", pCompact->db, terrstr()); return -1; } diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 37c9ac513a..a019c0dc55 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -440,6 +440,8 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode sdbRelease(pSdb, pMObj); } + alterMsg.replica = numOfReplicas; + while (1) { SMnodeObj *pMObj = NULL; pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pMObj); @@ -506,12 +508,12 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pObj) { mDebug("trans:%d, used to drop mnode:%d", pTrans->id, pObj->id); - if (mndSetCreateMnodeRedoLogs(pMnode, pTrans, pObj) != 0) { + if (mndSetDropMnodeRedoLogs(pMnode, pTrans, pObj) != 0) { mError("trans:%d, failed to set redo log since %s", pTrans->id, terrstr()); goto DROP_MNODE_OVER; } - if (mndSetCreateMnodeCommitLogs(pMnode, pTrans, pObj) != 0) { + if (mndSetDropMnodeCommitLogs(pMnode, pTrans, pObj) != 0) { mError("trans:%d, failed to set commit log since %s", pTrans->id, terrstr()); goto DROP_MNODE_OVER; } diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 504717117b..53e3bc5203 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -625,7 +625,7 @@ void mndTransHandleActionRsp(SMnodeMsg *pMsg) { pAction->errCode = pMsg->rpcMsg.code; } - mDebug("trans:%d, action:%d response is received, code:0x%x", transId, action, pMsg->code); + mDebug("trans:%d, action:%d response is received, code:0x%x", transId, action, pMsg->rpcMsg.code); mndTransExecute(pMnode, pTrans); HANDLE_ACTION_RSP_OVER: @@ -696,7 +696,7 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA for (int32_t action = 0; action < numOfActions; ++action) { STransAction *pAction = taosArrayGet(pArray, action); if (pAction == NULL) continue; - if (pAction->msgSent) continue; + if (pAction->msgReceived && pAction->errCode == 0) continue; int64_t signature = pTrans->id; signature = (signature << 32); @@ -736,6 +736,7 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA terrno = errorCode; return errorCode; } else { + mDebug("trans:%d, %d of %d actions executed, code:0x%x", pTrans->id, numOfReceivedMsgs, numOfActions, errorCode); return TSDB_CODE_MND_ACTION_IN_PROGRESS; } } diff --git a/source/util/src/tworker.c b/source/util/src/tworker.c index 11972e84cb..fb7b71b845 100644 --- a/source/util/src/tworker.c +++ b/source/util/src/tworker.c @@ -38,6 +38,7 @@ int32_t tWorkerInit(SWorkerPool *pool) { void tWorkerCleanup(SWorkerPool *pool) { for (int i = 0; i < pool->max; ++i) { SWorker *worker = pool->workers + i; + if (worker == NULL) continue; if (taosCheckPthreadValid(worker->thread)) { taosQsetThreadResume(pool->qset); } @@ -45,6 +46,7 @@ void tWorkerCleanup(SWorkerPool *pool) { for (int i = 0; i < pool->max; ++i) { SWorker *worker = pool->workers + i; + if (worker == NULL) continue; if (taosCheckPthreadValid(worker->thread)) { pthread_join(worker->thread, NULL); } From af96f5b5030a5f50f33d28cda39ff58547b63698 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 23 Dec 2021 20:01:51 +0800 Subject: [PATCH 19/22] feature/qnode --- include/common/taosmsg.h | 4 - source/libs/qworker/src/qworker.c | 12 ++ source/libs/scheduler/inc/schedulerInt.h | 29 +++- source/libs/scheduler/src/scheduler.c | 168 +++++++++++++++++++---- 4 files changed, 172 insertions(+), 41 deletions(-) diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index ec51a67808..8fd1ca9e9f 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -587,10 +587,6 @@ typedef struct { typedef struct { int32_t code; - union { - uint64_t qhandle; - uint64_t qId; - }; // query handle } SQueryTableRsp; // todo: the show handle should be replaced with id diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 628077a020..6955da8a8c 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -553,7 +553,19 @@ _return: int32_t qwBuildAndSendQueryRsp(SRpcMsg *pMsg, int32_t code) { + SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp)); + pRsp->code = code; + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .pCont = pRsp, + .contLen = sizeof(*pRsp), + .code = code, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } int32_t qwBuildAndSendReadyRsp(SRpcMsg *pMsg, int32_t code) { diff --git a/source/libs/scheduler/inc/schedulerInt.h b/source/libs/scheduler/inc/schedulerInt.h index 3fab91edac..f3de499dcd 100644 --- a/source/libs/scheduler/inc/schedulerInt.h +++ b/source/libs/scheduler/inc/schedulerInt.h @@ -31,17 +31,24 @@ extern "C" { #define SCH_MAX_CONDIDATE_EP_NUM TSDB_MAX_REPLICA +enum { + SCH_READ = 1, + SCH_WRITE, +}; + typedef struct SSchedulerMgmt { uint64_t taskId; uint64_t schedulerId; SSchedulerCfg cfg; - SHashObj *Jobs; // key: queryId, value: SQueryJob* + SHashObj *jobs; // key: queryId, value: SQueryJob* } SSchedulerMgmt; typedef struct SQueryTask { uint64_t taskId; // task id + SQueryLevel *level; // level SSubplan *plan; // subplan char *msg; // operator tree + int32_t msgLen; // msg length int8_t status; // task status SEpAddr execAddr; // task actual executed node address SQueryProfileSummary summary; // task execution summary @@ -51,10 +58,13 @@ typedef struct SQueryTask { } SQueryTask; typedef struct SQueryLevel { - int32_t level; - int8_t status; - int32_t taskNum; - SArray *subTasks; // Element is SQueryTask + int32_t level; + int8_t status; + SRWLatch lock; + int32_t taskFailed; + int32_t taskSucceed; + int32_t taskNum; + SArray *subTasks; // Element is SQueryTask } SQueryLevel; typedef struct SQueryJob { @@ -63,8 +73,8 @@ typedef struct SQueryJob { int32_t levelIdx; int8_t status; SQueryProfileSummary summary; - SEpSet dataSrcEps; - SEpAddr resEp; + SEpSet dataSrcEps; + SEpAddr resEp; void *transport; SArray *qnodeList; tsem_t rspSem; @@ -74,6 +84,7 @@ typedef struct SQueryJob { SHashObj *execTasks; // executing tasks, key:taskid, value:SQueryTask* SHashObj *succTasks; // succeed tasks, key:taskid, value:SQueryTask* + SHashObj *failTasks; // failed tasks, key:taskid, value:SQueryTask* SArray *levels; // Element is SQueryLevel, starting from 0. SArray *subPlans; // Element is SArray*, and nested element is SSubplan. The execution level of subplan, starting from 0. @@ -82,6 +93,7 @@ typedef struct SQueryJob { #define SCH_HAS_QNODE_IN_CLUSTER(type) (false) //TODO CLUSTER TYPE #define SCH_TASK_READY_TO_LUNCH(task) ((task)->childReady >= taosArrayGetSize((task)->children)) // MAY NEED TO ENHANCE #define SCH_IS_DATA_SRC_TASK(task) (task->plan->type == QUERY_TYPE_SCAN) +#define SCH_TASK_NEED_WAIT_ALL(type) (task->plan->type == QUERY_TYPE_MODIFY) #define SCH_JOB_ERR_LOG(param, ...) qError("QID:%"PRIx64 param, job->queryId, __VA_ARGS__) #define SCH_TASK_ERR_LOG(param, ...) qError("QID:%"PRIx64",TID:%"PRIx64 param, job->queryId, task->taskId, __VA_ARGS__) @@ -91,6 +103,9 @@ typedef struct SQueryJob { #define SCH_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); terrno = _code; return _code; } } while (0) #define SCH_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0) +#define SCH_LOCK(type, _lock) (SCH_READ == (type) ? taosRLockLatch(_lock) : taosWLockLatch(_lock)) +#define SCH_UNLOCK(type, _lock) (SCH_READ == (type) ? taosRUnLockLatch(_lock) : taosWUnLockLatch(_lock)) + extern int32_t schLaunchTask(SQueryJob *job, SQueryTask *task); diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index 83507c8dd7..a2fbdbe924 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -160,11 +160,19 @@ int32_t schValidateAndBuildJob(SQueryDag *dag, SQueryJob *job) { SQueryLevel level = {0}; SArray *levelPlans = NULL; int32_t levelPlanNum = 0; + SQueryLevel *pLevel = NULL; level.status = JOB_TASK_STATUS_NOT_START; for (int32_t i = 0; i < levelNum; ++i) { - level.level = i; + if (NULL == taosArrayPush(job->levels, &level)) { + qError("taosArrayPush failed"); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + pLevel = taosArrayGet(job->levels, i); + + pLevel->level = i; levelPlans = taosArrayGetP(dag->pSubplans, i); if (NULL == levelPlans) { qError("no level plans for level %d", i); @@ -177,10 +185,10 @@ int32_t schValidateAndBuildJob(SQueryDag *dag, SQueryJob *job) { SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); } - level.taskNum = levelPlanNum; + pLevel->taskNum = levelPlanNum; - level.subTasks = taosArrayInit(levelPlanNum, sizeof(SQueryTask)); - if (NULL == level.subTasks) { + pLevel->subTasks = taosArrayInit(levelPlanNum, sizeof(SQueryTask)); + if (NULL == pLevel->subTasks) { qError("taosArrayInit %d failed", levelPlanNum); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -191,9 +199,10 @@ int32_t schValidateAndBuildJob(SQueryDag *dag, SQueryJob *job) { task.taskId = atomic_add_fetch_64(&schMgmt.taskId, 1); task.plan = plan; + task.level = pLevel; task.status = JOB_TASK_STATUS_NOT_START; - void *p = taosArrayPush(level.subTasks, &task); + void *p = taosArrayPush(pLevel->subTasks, &task); if (NULL == p) { qError("taosArrayPush failed"); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -205,10 +214,6 @@ int32_t schValidateAndBuildJob(SQueryDag *dag, SQueryJob *job) { } } - if (NULL == taosArrayPush(job->levels, &level)) { - qError("taosArrayPush failed"); - SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } } SCH_ERR_JRET(schBuildTaskRalation(job, planToTask)); @@ -220,8 +225,8 @@ int32_t schValidateAndBuildJob(SQueryDag *dag, SQueryJob *job) { return TSDB_CODE_SUCCESS; _return: - if (level.subTasks) { - taosArrayDestroy(level.subTasks); + if (pLevel->subTasks) { + taosArrayDestroy(pLevel->subTasks); } if (planToTask) { @@ -273,7 +278,23 @@ int32_t schMoveTaskToSuccList(SQueryJob *job, SQueryTask *task, bool *moved) { return TSDB_CODE_SUCCESS; } - if (0 != taosHashPut(job->execTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { + if (0 != taosHashPut(job->succTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { + qError("taosHashPut failed"); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + *moved = true; + + return TSDB_CODE_SUCCESS; +} + +int32_t schMoveTaskToFailList(SQueryJob *job, SQueryTask *task, bool *moved) { + if (0 != taosHashRemove(job->execTasks, &task->taskId, sizeof(task->taskId))) { + qWarn("remove task[%"PRIx64"] from execTasks failed", task->taskId); + return TSDB_CODE_SUCCESS; + } + + if (0 != taosHashPut(job->failTasks, &task->taskId, sizeof(task->taskId), &task, POINTER_BYTES)) { qError("taosHashPut failed"); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -289,14 +310,23 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { void *msg = NULL; switch (msgType) { + case TSDB_MSG_TYPE_SUBMIT: { + if (NULL == task->msg || task->msgLen <= 0) { + qError("submit msg is NULL"); + SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); + } + + msgSize = task->msgLen; + msg = task->msg; + break; + } case TSDB_MSG_TYPE_QUERY: { if (NULL == task->msg) { qError("query msg is NULL"); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } - int32_t len = strlen(task->msg); - msgSize = sizeof(SSubQueryMsg) + len + 1; + msgSize = sizeof(SSubQueryMsg) + task->msgLen; msg = calloc(1, msgSize); if (NULL == msg) { qError("calloc %d failed", msgSize); @@ -308,11 +338,10 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { pMsg->schedulerId = htobe64(schMgmt.schedulerId); pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); - pMsg->contentLen = htonl(len); - memcpy(pMsg->msg, task->msg, len); - pMsg->msg[len] = 0; + pMsg->contentLen = htonl(task->msgLen); + memcpy(pMsg->msg, task->msg, task->msgLen); break; - } + } case TSDB_MSG_TYPE_RES_READY: { msgSize = sizeof(SResReadyMsg); msg = calloc(1, msgSize); @@ -322,6 +351,7 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { } SResReadyMsg *pMsg = msg; + pMsg->schedulerId = htobe64(schMgmt.schedulerId); pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); break; @@ -335,6 +365,21 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { } SResFetchMsg *pMsg = msg; + pMsg->schedulerId = htobe64(schMgmt.schedulerId); + pMsg->queryId = htobe64(job->queryId); + pMsg->taskId = htobe64(task->taskId); + break; + } + case TSDB_MSG_TYPE_DROP_TASK:{ + msgSize = sizeof(STaskDropMsg); + msg = calloc(1, msgSize); + if (NULL == msg) { + qError("calloc %d failed", msgSize); + SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + STaskDropMsg *pMsg = msg; + pMsg->schedulerId = htobe64(schMgmt.schedulerId); pMsg->queryId = htobe64(job->queryId); pMsg->taskId = htobe64(task->taskId); break; @@ -345,6 +390,7 @@ int32_t schAsyncSendMsg(SQueryJob *job, SQueryTask *task, int32_t msgType) { } //TODO SEND MSG + //taosAsyncExec(rpcSendRequest(void * shandle, const SEpSet * pEpSet, SRpcMsg * pMsg, int64_t * pRid), p, &code); return TSDB_CODE_SUCCESS; } @@ -425,8 +471,29 @@ int32_t schProcessOnTaskSuccess(SQueryJob *job, SQueryTask *task) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - strncpy(job->resEp.fqdn, task->execAddr.fqdn, sizeof(job->resEp.fqdn)); - job->resEp.port = task->execAddr.port; + int32_t taskDone = 0; + + if (SCH_TASK_NEED_WAIT_ALL(task)) { + SCH_LOCK(SCH_WRITE, &task->level->lock); + task->level->taskFailed++; + taskDone = task->level->taskSucceed + task->level->taskFailed; + SCH_UNLOCK(SCH_WRITE, &task->level->lock); + + if (taskDone < task->level->taskNum) { + qDebug("wait all tasks, done:%d, all:%d", taskDone, task->level->taskNum); + return TSDB_CODE_SUCCESS; + } + + if (task->level->taskFailed > 0) { + job->status = JOB_TASK_STATUS_FAILED; + SCH_ERR_RET(schProcessOnJobFailure(job)); + + return TSDB_CODE_SUCCESS; + } + } else { + strncpy(job->resEp.fqdn, task->execAddr.fqdn, sizeof(job->resEp.fqdn)); + job->resEp.port = task->execAddr.port; + } SCH_ERR_RET(schProcessOnJobSuccess(job)); @@ -457,10 +524,30 @@ int32_t schProcessOnTaskSuccess(SQueryJob *job, SQueryTask *task) { int32_t schProcessOnTaskFailure(SQueryJob *job, SQueryTask *task, int32_t errCode) { bool needRetry = false; + bool moved = false; + int32_t taskDone = 0; SCH_ERR_RET(schTaskCheckAndSetRetry(job, task, errCode, &needRetry)); if (!needRetry) { SCH_TASK_ERR_LOG("task failed[%x], no more retry", errCode); + + SCH_ERR_RET(schMoveTaskToFailList(job, task, &moved)); + if (!moved) { + SCH_TASK_ERR_LOG("task may already moved, status:%d", task->status); + return TSDB_CODE_SUCCESS; + } + + if (SCH_TASK_NEED_WAIT_ALL(task)) { + SCH_LOCK(SCH_WRITE, &task->level->lock); + task->level->taskFailed++; + taskDone = task->level->taskSucceed + task->level->taskFailed; + SCH_UNLOCK(SCH_WRITE, &task->level->lock); + + if (taskDone < task->level->taskNum) { + qDebug("wait all tasks, done:%d, all:%d", taskDone, task->level->taskNum); + return TSDB_CODE_SUCCESS; + } + } job->status = JOB_TASK_STATUS_FAILED; SCH_ERR_RET(schProcessOnJobFailure(job)); @@ -522,8 +609,7 @@ _return: int32_t schLaunchTask(SQueryJob *job, SQueryTask *task) { SSubplan *plan = task->plan; - int32_t len = 0; - SCH_ERR_RET(qSubPlanToString(plan, &task->msg, &len)); + SCH_ERR_RET(qSubPlanToString(plan, &task->msg, &task->msgLen)); if (plan->execEpSet.numOfEps <= 0) { SCH_ERR_RET(schSetTaskExecEpSet(job, &plan->execEpSet)); } @@ -532,8 +618,10 @@ int32_t schLaunchTask(SQueryJob *job, SQueryTask *task) { SCH_TASK_ERR_LOG("invalid execEpSet num:%d", plan->execEpSet.numOfEps); SCH_ERR_RET(TSDB_CODE_SCH_INTERNAL_ERROR); } + + int32_t msgType = (plan->type == QUERY_TYPE_MODIFY) ? TSDB_MSG_TYPE_SUBMIT : TSDB_MSG_TYPE_QUERY; - SCH_ERR_RET(schAsyncSendMsg(job, task, TSDB_MSG_TYPE_QUERY)); + SCH_ERR_RET(schAsyncSendMsg(job, task, msgType)); SCH_ERR_RET(schPushTaskToExecList(job, task)); @@ -554,6 +642,16 @@ int32_t schLaunchJob(SQueryJob *job) { return TSDB_CODE_SUCCESS; } +void schDropJobAllTasks(SQueryJob *job) { + void *pIter = taosHashIterate(job->succTasks, NULL); + while (pIter) { + SQueryTask *task = *(SQueryTask **)pIter; + + schAsyncSendMsg(job, task, int32_t msgType); + + pIter = taosHashIterate(schStatus->tasksHash, pIter); + } +} int32_t schedulerInit(SSchedulerCfg *cfg) { if (cfg) { @@ -562,8 +660,8 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { schMgmt.cfg.maxJobNum = SCHEDULE_DEFAULT_JOB_NUMBER; } - schMgmt.Jobs = taosHashInit(schMgmt.cfg.maxJobNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == schMgmt.Jobs) { + schMgmt.jobs = taosHashInit(schMgmt.cfg.maxJobNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + if (NULL == schMgmt.jobs) { SCH_ERR_LRET(TSDB_CODE_QRY_OUT_OF_MEMORY, "init %d schduler jobs failed", schMgmt.cfg.maxJobNum); } @@ -605,9 +703,15 @@ int32_t scheduleExecJob(void *transport, SArray *qnodeList, SQueryDag* pDag, voi SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } + job->failTasks = taosHashInit(pDag->numOfSubplans, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); + if (NULL == job->failTasks) { + qError("taosHashInit %d failed", pDag->numOfSubplans); + SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + tsem_init(&job->rspSem, 0, 0); - if (0 != taosHashPut(schMgmt.Jobs, &job->queryId, sizeof(job->queryId), &job, POINTER_BYTES)) { + if (0 != taosHashPut(schMgmt.jobs, &job->queryId, sizeof(job->queryId), &job, POINTER_BYTES)) { qError("taosHashPut queryId:%"PRIx64" failed", job->queryId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); } @@ -659,6 +763,8 @@ _return: int32_t scheduleCancelJob(void *pJob) { //TODO + //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST + return TSDB_CODE_SUCCESS; } @@ -670,7 +776,7 @@ void scheduleFreeJob(void *pJob) { SQueryJob *job = pJob; if (job->status > 0) { - if (0 != taosHashRemove(schMgmt.Jobs, &job->queryId, sizeof(job->queryId))) { + if (0 != taosHashRemove(schMgmt.jobs, &job->queryId, sizeof(job->queryId))) { qError("remove job:%"PRIx64"from mgmt failed", job->queryId); // maybe already freed return; } @@ -678,15 +784,17 @@ void scheduleFreeJob(void *pJob) { if (job->status == JOB_TASK_STATUS_EXECUTING) { scheduleCancelJob(pJob); } + + schDropJobAllTasks(job); } //TODO free job } void schedulerDestroy(void) { - if (schMgmt.Jobs) { - taosHashCleanup(schMgmt.Jobs); //TODO - schMgmt.Jobs = NULL; + if (schMgmt.jobs) { + taosHashCleanup(schMgmt.jobs); //TODO + schMgmt.jobs = NULL; } } From 6694e4b2dac2e19a72d971705480815ac7b79ed1 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Thu, 23 Dec 2021 22:46:32 +0800 Subject: [PATCH 20/22] fix tfile bug and add unit test --- source/libs/index/src/index_tfile.c | 75 +++++++------- source/libs/index/test/indexTests.cc | 140 ++++++++++++++++++++++----- 2 files changed, 156 insertions(+), 59 deletions(-) diff --git a/source/libs/index/src/index_tfile.c b/source/libs/index/src/index_tfile.c index e02a3e0327..9afc29457d 100644 --- a/source/libs/index/src/index_tfile.c +++ b/source/libs/index/src/index_tfile.c @@ -33,11 +33,11 @@ static int tfileWriteHeader(TFileWriter* writer); static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset); static int tfileWriteData(TFileWriter* write, TFileValue* tval); -static int tfileReadLoadHeader(TFileReader* reader); -static int tfileReadLoadFst(TFileReader* reader); -static int tfileReadLoadTableIds(TFileReader* reader, int32_t offset, SArray* result); -static void tfileReadRef(TFileReader* reader); -static void tfileReadUnRef(TFileReader* reader); +static int tfileReaderLoadHeader(TFileReader* reader); +static int tfileReaderLoadFst(TFileReader* reader); +static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result); +static void tfileReaderRef(TFileReader* reader); +static void tfileReaderUnRef(TFileReader* reader); static int tfileGetFileList(const char* path, SArray* result); static int tfileRmExpireFile(SArray* result); @@ -70,23 +70,12 @@ TFileCache* tfileCacheCreate(const char* path) { WriterCtx* wc = writerCtxCreate(TFile, file, true, 1024 * 64); if (wc == NULL) { - indexError("failed to open index: %s", file); + indexError("failed to open index:%s", file); goto End; } TFileReader* reader = tfileReaderCreate(wc); - if (0 != tfileReadLoadHeader(reader)) { - tfileReaderDestroy(reader); - indexError("failed to load index header, index file: %s", file); - goto End; - } - - if (0 != tfileReadLoadFst(reader)) { - tfileReaderDestroy(reader); - indexError("failed to load index fst, index file: %s", file); - goto End; - } - tfileReadRef(reader); + tfileReaderRef(reader); // loader fst and validate it TFileHeader* header = &reader->header; TFileCacheKey key = {.suid = header->suid, .colName = header->colName, .nColName = strlen(header->colName), .colType = header->colType}; @@ -111,7 +100,7 @@ void tfileCacheDestroy(TFileCache* tcache) { TFileReader* p = *reader; indexInfo("drop table cache suid: %" PRIu64 ", colName: %s, colType: %d", p->header.suid, p->header.colName, p->header.colType); - tfileReadUnRef(p); + tfileReaderUnRef(p); reader = taosHashIterate(tcache->tableCache, reader); } taosHashCleanup(tcache->tableCache); @@ -123,7 +112,7 @@ TFileReader* tfileCacheGet(TFileCache* tcache, TFileCacheKey* key) { tfileSerialCacheKey(key, buf); TFileReader* reader = taosHashGet(tcache->tableCache, buf, strlen(buf)); - tfileReadRef(reader); + tfileReaderRef(reader); return reader; } @@ -135,10 +124,10 @@ void tfileCachePut(TFileCache* tcache, TFileCacheKey* key, TFileReader* reader) if (*p != NULL) { TFileReader* oldReader = *p; taosHashRemove(tcache->tableCache, buf, strlen(buf)); - tfileReadUnRef(oldReader); + tfileReaderUnRef(oldReader); } - tfileReadRef(reader); + tfileReaderRef(reader); taosHashPut(tcache->tableCache, buf, strlen(buf), &reader, sizeof(void*)); return; } @@ -149,6 +138,19 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) { // T_REF_INC(reader); reader->ctx = ctx; + + if (0 != tfileReaderLoadHeader(reader)) { + tfileReaderDestroy(reader); + indexError("failed to load index header, suid: %" PRIu64 ", colName: %s", reader->header.suid, reader->header.colName); + return NULL; + } + + if (0 != tfileReaderLoadFst(reader)) { + tfileReaderDestroy(reader); + indexError("failed to load index fst, suid: %" PRIu64 ", colName: %s", reader->header.suid, reader->header.colName); + return NULL; + } + return reader; } void tfileReaderDestroy(TFileReader* reader) { @@ -170,7 +172,7 @@ int tfileReaderSearch(TFileReader* reader, SIndexTermQuery* query, SArray* resul FstSlice key = fstSliceCreate(term->colVal, term->nColVal); if (fstGet(reader->fst, &key, &offset)) { indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, found table info in tindex", term->suid, term->colName, term->colVal); - ret = tfileReadLoadTableIds(reader, offset, result); + ret = tfileReaderLoadTableIds(reader, offset, result); } else { indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, not found table info in tindex", term->suid, term->colName, term->colVal); } @@ -181,7 +183,7 @@ int tfileReaderSearch(TFileReader* reader, SIndexTermQuery* query, SArray* resul } else { // handle later } - tfileReadUnRef(reader); + tfileReaderUnRef(reader); return ret; } @@ -205,11 +207,6 @@ TFileWriter* tfileWriterCreate(WriterCtx* ctx, TFileHeader* header) { tw->ctx = ctx; tw->header = *header; tfileWriteHeader(tw); - tw->fb = fstBuilderCreate(ctx, 0); - if (tw->fb == NULL) { - tfileWriterDestroy(tw); - return NULL; - } return tw; } @@ -267,6 +264,11 @@ int tfileWriterPut(TFileWriter* tw, void* data) { } tfree(buf); + tw->fb = fstBuilderCreate(tw->ctx, 0); + if (tw->fb == NULL) { + tfileWriterDestroy(tw); + return -1; + } // write fst for (size_t i = 0; i < sz; i++) { // TODO, fst batch write later @@ -343,6 +345,7 @@ static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) { int32_t fstOffset = offset + sizeof(tw->header.fstOffset); tw->header.fstOffset = fstOffset; if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) { return -1; } + tw->offset += sizeof(fstOffset); return 0; } static int tfileWriteHeader(TFileWriter* writer) { @@ -372,16 +375,16 @@ static int tfileWriteData(TFileWriter* write, TFileValue* tval) { } return 0; } -static int tfileReadLoadHeader(TFileReader* reader) { +static int tfileReaderLoadHeader(TFileReader* reader) { // TODO simple tfile header later char buf[TFILE_HEADER_SIZE] = {0}; - int64_t nread = reader->ctx->read(reader->ctx, buf, sizeof(buf)); + int64_t nread = reader->ctx->readFrom(reader->ctx, buf, sizeof(buf), 0); assert(nread == sizeof(buf)); memcpy(&reader->header, buf, sizeof(buf)); return 0; } -static int tfileReadLoadFst(TFileReader* reader) { +static int tfileReaderLoadFst(TFileReader* reader) { // current load fst into memory, refactor it later static int FST_MAX_SIZE = 16 * 1024; @@ -398,9 +401,9 @@ static int tfileReadLoadFst(TFileReader* reader) { free(buf); fstSliceDestroy(&st); - return reader->fst == NULL ? 0 : -1; + return reader->fst != NULL ? 0 : -1; } -static int tfileReadLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) { +static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) { int32_t nid; WriterCtx* ctx = reader->ctx; @@ -420,12 +423,12 @@ static int tfileReadLoadTableIds(TFileReader* reader, int32_t offset, SArray* re free(buf); return 0; } -static void tfileReadRef(TFileReader* reader) { +static void tfileReaderRef(TFileReader* reader) { int ref = T_REF_INC(reader); UNUSED(ref); } -static void tfileReadUnRef(TFileReader* reader) { +static void tfileReaderUnRef(TFileReader* reader) { int ref = T_REF_DEC(reader); if (ref == 0) { tfileReaderDestroy(reader); } } diff --git a/source/libs/index/test/indexTests.cc b/source/libs/index/test/indexTests.cc index f8dae787b8..6c6f45bd11 100644 --- a/source/libs/index/test/indexTests.cc +++ b/source/libs/index/test/indexTests.cc @@ -21,7 +21,7 @@ #include "index_fst_util.h" #include "index_tfile.h" #include "tutil.h" - +using namespace std; class FstWriter { public: FstWriter() { @@ -355,41 +355,121 @@ class IndexEnv : public ::testing::Test { // // //} +class TFileObj { + public: + TFileObj(const std::string& path = "/tmp/tindex", const std::string& colName = "voltage") : path_(path), colName_(colName) { + colId_ = 10; + // Do Nothing + // + } + int Put(SArray* tv) { + if (reader_ != NULL) { + tfileReaderDestroy(reader_); + reader_ = NULL; + } + if (writer_ == NULL) { InitWriter(); } + return tfileWriterPut(writer_, tv); + } + bool InitWriter() { + TFileHeader header; + header.suid = 1; + header.version = 1; + memcpy(header.colName, colName_.c_str(), colName_.size()); + header.colType = TSDB_DATA_TYPE_BINARY; + + std::string path(path_); + int colId = 2; + char buf[64] = {0}; + sprintf(buf, "%" PRIu64 "-%d-%d.tindex", header.suid, colId_, header.version); + path.append("/").append(buf); + + fileName_ = path; + + WriterCtx* ctx = writerCtxCreate(TFile, path.c_str(), false, 64 * 1024 * 1024); + + writer_ = tfileWriterCreate(ctx, &header); + return writer_ != NULL ? true : false; + } + bool InitReader() { + WriterCtx* ctx = writerCtxCreate(TFile, fileName_.c_str(), true, 64 * 1024 * 1024); + reader_ = tfileReaderCreate(ctx); + return reader_ != NULL ? true : false; + } + int Get(SIndexTermQuery* query, SArray* result) { + if (writer_ != NULL) { + tfileWriterDestroy(writer_); + writer_ = NULL; + } + if (reader_ == NULL && InitReader()) { + // + // + } + return tfileReaderSearch(reader_, query, result); + } + ~TFileObj() { + if (writer_) { tfileWriterDestroy(writer_); } + if (reader_) { tfileReaderDestroy(reader_); } + } + + private: + std::string path_; + std::string colName_; + std::string fileName_; + + TFileWriter* writer_; + TFileReader* reader_; + + int colId_; +}; class IndexTFileEnv : public ::testing::Test { protected: virtual void SetUp() { - taosRemoveDir(dir); - taosMkDir(dir); + taosRemoveDir(dir.c_str()); + taosMkDir(dir.c_str()); tfInit(); - std::string colName("voltage"); - header.suid = 1; - header.version = 1; - memcpy(header.colName, colName.c_str(), colName.size()); - header.colType = TSDB_DATA_TYPE_BINARY; + fObj = new TFileObj(dir, colName); - std::string path(dir); - int colId = 2; - char buf[64] = {0}; - sprintf(buf, "%" PRIu64 "-%d-%d.tindex", header.suid, colId, header.version); - path.append("/").append(buf); + // std::string colName("voltage"); + // header.suid = 1; + // header.version = 1; + // memcpy(header.colName, colName.c_str(), colName.size()); + // header.colType = TSDB_DATA_TYPE_BINARY; - ctx = writerCtxCreate(TFile, path.c_str(), false, 64 * 1024 * 1024); + // std::string path(dir); + // int colId = 2; + // char buf[64] = {0}; + // sprintf(buf, "%" PRIu64 "-%d-%d.tindex", header.suid, colId, header.version); + // path.append("/").append(buf); - twrite = tfileWriterCreate(ctx, &header); + // ctx = writerCtxCreate(TFile, path.c_str(), false, 64 * 1024 * 1024); + + // twrite = tfileWriterCreate(ctx, &header); } virtual void TearDown() { // indexClose(index); // indexeptsDestroy(opts); + delete fObj; tfCleanup(); - tfileWriterDestroy(twrite); + // tfileWriterDestroy(twrite); } - const char* dir = "/tmp/tindex"; - WriterCtx* ctx = NULL; - TFileHeader header; - TFileWriter* twrite = NULL; + TFileObj* fObj; + std::string dir = "/tmp/tindex"; + std::string colName = "voltage"; + + int coldId = 2; + int version = 1; + int colType = TSDB_DATA_TYPE_BINARY; + + // WriterCtx* ctx = NULL; + // TFileHeader header; + // TFileWriter* twrite = NULL; }; +// static TFileWriter* genTFileWriter(const char* path, TFileHeader* header) { +// char buf[128] = {0}; +// WriterCtx* ctx = writerCtxCreate(TFile, path, false, ) +//} static TFileValue* genTFileValue(const char* val) { TFileValue* tv = (TFileValue*)calloc(1, sizeof(TFileValue)); int32_t vlen = strlen(val) + 1; @@ -413,17 +493,31 @@ static void destroyTFileValue(void* val) { TEST_F(IndexTFileEnv, test_tfile_write) { TFileValue* v1 = genTFileValue("c"); TFileValue* v2 = genTFileValue("a"); + TFileValue* v3 = genTFileValue("b"); + TFileValue* v4 = genTFileValue("d"); SArray* data = (SArray*)taosArrayInit(4, sizeof(void*)); taosArrayPush(data, &v1); taosArrayPush(data, &v2); + taosArrayPush(data, &v3); + taosArrayPush(data, &v4); - tfileWriterPut(twrite, data); - // tfileWriterDestroy(twrite); - + fObj->Put(data); for (size_t i = 0; i < taosArrayGetSize(data); i++) { destroyTFileValue(taosArrayGetP(data, i)); } taosArrayDestroy(data); + + std::string colName("voltage"); + std::string colVal("b"); + SIndexTerm* term = indexTermCreate(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(), colVal.c_str(), colVal.size()); + SIndexTermQuery query = {.term = term, .qType = QUERY_TERM}; + + SArray* result = (SArray*)taosArrayInit(1, sizeof(uint64_t)); + fObj->Get(&query, result); + assert(taosArrayGetSize(result) == 10); + indexTermDestroy(term); + + // tfileWriterDestroy(twrite); } From fddd11ed470e043f85eb198d40ce6295256decda Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Fri, 24 Dec 2021 09:41:09 +0800 Subject: [PATCH 21/22] feature/qnode --- include/common/taosmsg.h | 12 ++ include/libs/qworker/qworker.h | 12 +- source/dnode/vnode/impl/CMakeLists.txt | 3 +- source/dnode/vnode/impl/inc/vnodeDef.h | 2 + source/dnode/vnode/impl/inc/vnodeQuery.h | 31 +++++ source/dnode/vnode/impl/src/vnodeInt.c | 10 -- source/dnode/vnode/impl/src/vnodeMain.c | 5 + source/dnode/vnode/impl/src/vnodeQuery.c | 35 ++++++ source/dnode/vnode/meta/inc/metaQuery.h | 6 +- source/libs/qworker/src/qworker.c | 149 +++++++++++++++++++---- source/libs/scheduler/inc/schedulerInt.h | 25 ++-- source/libs/scheduler/src/scheduler.c | 13 +- 12 files changed, 246 insertions(+), 57 deletions(-) create mode 100644 source/dnode/vnode/impl/inc/vnodeQuery.h create mode 100644 source/dnode/vnode/impl/src/vnodeQuery.c diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index 8fd1ca9e9f..8cafa39d8c 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -1121,6 +1121,10 @@ typedef struct SResReadyMsg { uint64_t taskId; } SResReadyMsg; +typedef struct SResReadyRsp { + int32_t code; +} SResReadyRsp; + typedef struct SResFetchMsg { uint64_t schedulerId; uint64_t queryId; @@ -1149,12 +1153,20 @@ typedef struct STaskCancelMsg { uint64_t taskId; } STaskCancelMsg; +typedef struct STaskCancelRsp { + int32_t code; +} STaskCancelRsp; + typedef struct STaskDropMsg { uint64_t schedulerId; uint64_t queryId; uint64_t taskId; } STaskDropMsg; +typedef struct STaskDropRsp { + int32_t code; +} STaskDropRsp; + #pragma pack(pop) diff --git a/include/libs/qworker/qworker.h b/include/libs/qworker/qworker.h index 8e36178497..83047a44de 100644 --- a/include/libs/qworker/qworker.h +++ b/include/libs/qworker/qworker.h @@ -42,17 +42,17 @@ typedef struct { int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt); -int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg **rsp); +int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); -int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); +int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); -int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); +int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); -int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); +int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); -int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); +int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); -int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp); +int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg); void qWorkerDestroy(void **qWorkerMgmt); diff --git a/source/dnode/vnode/impl/CMakeLists.txt b/source/dnode/vnode/impl/CMakeLists.txt index 6972605afd..9e892bc4c4 100644 --- a/source/dnode/vnode/impl/CMakeLists.txt +++ b/source/dnode/vnode/impl/CMakeLists.txt @@ -15,9 +15,10 @@ target_link_libraries( PUBLIC wal PUBLIC sync PUBLIC cjson + PUBLIC qworker ) # test if(${BUILD_TEST}) add_subdirectory(test) -endif(${BUILD_TEST}) \ No newline at end of file +endif(${BUILD_TEST}) diff --git a/source/dnode/vnode/impl/inc/vnodeDef.h b/source/dnode/vnode/impl/inc/vnodeDef.h index 605557d4ea..c5a57b02a6 100644 --- a/source/dnode/vnode/impl/inc/vnodeDef.h +++ b/source/dnode/vnode/impl/inc/vnodeDef.h @@ -34,6 +34,7 @@ #include "vnodeRequest.h" #include "vnodeStateMgr.h" #include "vnodeSync.h" +#include "vnodeQuery.h" #ifdef __cplusplus extern "C" { @@ -72,6 +73,7 @@ struct SVnode { SVnodeSync* pSync; SVnodeFS* pFs; tsem_t canCommit; + void* pQuery; }; int vnodeScheduleTask(SVnodeTask* task); diff --git a/source/dnode/vnode/impl/inc/vnodeQuery.h b/source/dnode/vnode/impl/inc/vnodeQuery.h new file mode 100644 index 0000000000..59bab42f62 --- /dev/null +++ b/source/dnode/vnode/impl/inc/vnodeQuery.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _TD_VNODE_READ_H_ +#define _TD_VNODE_READ_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#include "vnodeInt.h" +#include "qworker.h" + +int vnodeQueryOpen(SVnode *pVnode); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_VNODE_READ_H_*/ diff --git a/source/dnode/vnode/impl/src/vnodeInt.c b/source/dnode/vnode/impl/src/vnodeInt.c index 5deaffe6d2..65185f4a16 100644 --- a/source/dnode/vnode/impl/src/vnodeInt.c +++ b/source/dnode/vnode/impl/src/vnodeInt.c @@ -24,16 +24,6 @@ int32_t vnodeSync(SVnode *pVnode) { return 0; } int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) { return 0; } -int vnodeProcessQueryReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { - vInfo("query message is processed"); - return 0; -} - -int vnodeProcessFetchReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { - vInfo("fetch message is processed"); - return 0; -} - int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { vInfo("sync message is processed"); return 0; diff --git a/source/dnode/vnode/impl/src/vnodeMain.c b/source/dnode/vnode/impl/src/vnodeMain.c index c98f3e0800..2b0363c97f 100644 --- a/source/dnode/vnode/impl/src/vnodeMain.c +++ b/source/dnode/vnode/impl/src/vnodeMain.c @@ -127,6 +127,11 @@ static int vnodeOpenImpl(SVnode *pVnode) { return -1; } + // Open Query + if (vnodeQueryOpen(pVnode)) { + return -1; + } + // TODO return 0; } diff --git a/source/dnode/vnode/impl/src/vnodeQuery.c b/source/dnode/vnode/impl/src/vnodeQuery.c new file mode 100644 index 0000000000..31481bf7c4 --- /dev/null +++ b/source/dnode/vnode/impl/src/vnodeQuery.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "vnodeDef.h" +#include "vnodeQuery.h" + +int vnodeQueryOpen(SVnode *pVnode) { + return qWorkerInit(NULL, &pVnode->pQuery); +} + +int vnodeProcessQueryReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { + vInfo("query message is processed"); + qWorkerProcessQueryMsg(pVnode, pVnode->pQuery, pMsg); + return 0; +} + +int vnodeProcessFetchReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) { + vInfo("fetch message is processed"); + qWorkerProcessFetchMsg(pVnode, pVnode->pQuery, pMsg); + return 0; +} + + diff --git a/source/dnode/vnode/meta/inc/metaQuery.h b/source/dnode/vnode/meta/inc/metaQuery.h index 110df8dd45..ca3b68b415 100644 --- a/source/dnode/vnode/meta/inc/metaQuery.h +++ b/source/dnode/vnode/meta/inc/metaQuery.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef _TD_META_QUERY_H_ -#define _TD_META_QUERY_H_ +#ifndef _VNODE_QUERY_H_ +#define _VNODE_QUERY_H_ #ifdef __cplusplus extern "C" { @@ -24,4 +24,4 @@ extern "C" { } #endif -#endif /*_TD_META_QUERY_H_*/ \ No newline at end of file +#endif /*_VNODE_QUERY_H_*/ \ No newline at end of file diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index 6955da8a8c..37d3e655c2 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -558,6 +558,7 @@ int32_t qwBuildAndSendQueryRsp(SRpcMsg *pMsg, int32_t code) { SRpcMsg rpcRsp = { .handle = pMsg->handle, + .ahandle = pMsg->ahandle, .pCont = pRsp, .contLen = sizeof(*pRsp), .code = code, @@ -569,24 +570,105 @@ int32_t qwBuildAndSendQueryRsp(SRpcMsg *pMsg, int32_t code) { } int32_t qwBuildAndSendReadyRsp(SRpcMsg *pMsg, int32_t code) { + SResReadyRsp *pRsp = (SResReadyRsp *)rpcMallocCont(sizeof(SResReadyRsp)); + pRsp->code = code; + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .ahandle = pMsg->ahandle, + .pCont = pRsp, + .contLen = sizeof(*pRsp), + .code = code, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } int32_t qwBuildAndSendStatusRsp(SRpcMsg *pMsg, SSchedulerStatusRsp *sStatus) { + int32_t size = 0; + + if (sStatus) { + size = sizeof(SSchedulerStatusRsp) + sizeof(sStatus->status[0]) * sStatus->num; + } else { + size = sizeof(SSchedulerStatusRsp); + } + + SSchedulerStatusRsp *pRsp = (SSchedulerStatusRsp *)rpcMallocCont(size); + if (sStatus) { + memcpy(pRsp, sStatus, size); + } else { + pRsp->num = 0; + } + + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .ahandle = pMsg->ahandle, + .pCont = pRsp, + .contLen = size, + .code = 0, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } int32_t qwBuildAndSendFetchRsp(SRpcMsg *pMsg, void *data) { + SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp)); + memset(pRsp, 0, sizeof(SRetrieveTableRsp)); + //TODO fill msg + pRsp->completed = true; + + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .ahandle = pMsg->ahandle, + .pCont = pRsp, + .contLen = sizeof(*pRsp), + .code = 0, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } -int32_t qwBuildAndSendCancelRsp(SRpcMsg *pMsg) { +int32_t qwBuildAndSendCancelRsp(SRpcMsg *pMsg, int32_t code) { + STaskCancelRsp *pRsp = (STaskCancelRsp *)rpcMallocCont(sizeof(STaskCancelRsp)); + pRsp->code = code; + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .ahandle = pMsg->ahandle, + .pCont = pRsp, + .contLen = sizeof(*pRsp), + .code = code, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } -int32_t qwBuildAndSendDropRsp(SRpcMsg *pMsg) { +int32_t qwBuildAndSendDropRsp(SRpcMsg *pMsg, int32_t code) { + STaskDropRsp *pRsp = (STaskDropRsp *)rpcMallocCont(sizeof(STaskDropRsp)); + pRsp->code = code; + SRpcMsg rpcRsp = { + .handle = pMsg->handle, + .ahandle = pMsg->ahandle, + .pCont = pRsp, + .contLen = sizeof(*pRsp), + .code = code, + }; + + rpcSendResponse(&rpcRsp); + + return TSDB_CODE_SUCCESS; } @@ -724,8 +806,10 @@ int32_t qwHandleFetch(SQWorkerResCache *res, SQWorkerMgmt *mgmt, uint64_t schedu SQWorkerSchStatus *sch = NULL; SQWorkerTaskStatus *task = NULL; int32_t code = 0; + int32_t needRsp = true; + void *data = NULL; - QW_ERR_RET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); + QW_ERR_JRET(qwAcquireScheduler(QW_READ, mgmt, schedulerId, &sch)); QW_ERR_JRET(qwAcquireTask(QW_READ, sch, queryId, taskId, &task)); QW_LOCK(QW_READ, &task->lock); @@ -736,7 +820,7 @@ int32_t qwHandleFetch(SQWorkerResCache *res, SQWorkerMgmt *mgmt, uint64_t schedu } if (QW_GOT_RES_DATA(res->data)) { - QW_ERR_JRET(qwBuildAndSendFetchRsp(pMsg, res->data)); + data = res->data; if (QW_LOW_RES_DATA(res->data)) { if (task->status == JOB_TASK_STATUS_PARTIAL_SUCCEED) { //TODO add query back to queue @@ -749,6 +833,8 @@ int32_t qwHandleFetch(SQWorkerResCache *res, SQWorkerMgmt *mgmt, uint64_t schedu } //TODO SET FLAG FOR QUERY TO SEND RSP WHEN RES READY + + needRsp = false; } _return: @@ -758,9 +844,12 @@ _return: if (sch) { qwReleaseTask(QW_READ, sch); + qwReleaseScheduler(QW_READ, mgmt); } - qwReleaseScheduler(QW_READ, mgmt); + if (needRsp) { + qwBuildAndSendFetchRsp(pMsg, res->data); + } QW_RET(code); } @@ -844,13 +933,14 @@ int32_t qWorkerInit(SQWorkerCfg *cfg, void **qWorkerMgmt) { return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg **rsp) { - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SSubQueryMsg *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + qError("invalid query msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } @@ -863,7 +953,7 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRp QW_ERR_JRET(qwCheckTaskCancelDrop(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId, &needStop)); if (needStop) { qWarn("task need stop"); - QW_ERR_RET(TSDB_CODE_QRY_TASK_CANCELLED); + QW_ERR_JRET(TSDB_CODE_QRY_TASK_CANCELLED); } code = qStringToSubplan(msg->msg, &plan); @@ -922,13 +1012,14 @@ _return: QW_RET(code); } -int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp){ - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg){ + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } SResReadyMsg *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + qError("invalid task status msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } @@ -937,27 +1028,31 @@ int32_t qWorkerProcessReadyMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRp return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessStatusMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } + int32_t code = 0; SSchTasksStatusMsg *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + qError("invalid task status msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SSchedulerStatusRsp *sStatus = NULL; - QW_ERR_RET(qwGetSchTasksStatus(qWorkerMgmt, msg->schedulerId, &sStatus)); + QW_ERR_JRET(qwGetSchTasksStatus(qWorkerMgmt, msg->schedulerId, &sStatus)); + +_return: QW_ERR_RET(qwBuildAndSendStatusRsp(pMsg, sStatus)); return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessFetchMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } @@ -983,36 +1078,44 @@ _return: QW_RET(code); } -int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessCancelMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } + int32_t code = 0; STaskCancelMsg *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + qError("invalid task cancel msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - QW_ERR_RET(qwCancelTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); + QW_ERR_JRET(qwCancelTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); - QW_ERR_RET(qwBuildAndSendCancelRsp(pMsg)); +_return: + + QW_ERR_RET(qwBuildAndSendCancelRsp(pMsg, code)); return TSDB_CODE_SUCCESS; } -int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg, SRpcMsg *rsp) { - if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg || NULL == rsp) { +int32_t qWorkerProcessDropMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) { + if (NULL == node || NULL == qWorkerMgmt || NULL == pMsg) { return TSDB_CODE_QRY_INVALID_INPUT; } + int32_t code = 0; STaskDropMsg *msg = pMsg->pCont; if (NULL == msg || pMsg->contLen <= sizeof(*msg)) { + qError("invalid task drop msg"); QW_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - QW_ERR_RET(qwCancelDropTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); + QW_ERR_JRET(qwCancelDropTask(qWorkerMgmt, msg->schedulerId, msg->queryId, msg->taskId)); - QW_ERR_RET(qwBuildAndSendDropRsp(pMsg)); +_return: + + QW_ERR_RET(qwBuildAndSendDropRsp(pMsg, code)); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/scheduler/inc/schedulerInt.h b/source/libs/scheduler/inc/schedulerInt.h index f3de499dcd..bc7bc44350 100644 --- a/source/libs/scheduler/inc/schedulerInt.h +++ b/source/libs/scheduler/inc/schedulerInt.h @@ -43,6 +43,17 @@ typedef struct SSchedulerMgmt { SHashObj *jobs; // key: queryId, value: SQueryJob* } SSchedulerMgmt; +typedef struct SQueryLevel { + int32_t level; + int8_t status; + SRWLatch lock; + int32_t taskFailed; + int32_t taskSucceed; + int32_t taskNum; + SArray *subTasks; // Element is SQueryTask +} SQueryLevel; + + typedef struct SQueryTask { uint64_t taskId; // task id SQueryLevel *level; // level @@ -57,16 +68,6 @@ typedef struct SQueryTask { SArray *parents; // the data destination tasks, get data from current task, element is SQueryTask* } SQueryTask; -typedef struct SQueryLevel { - int32_t level; - int8_t status; - SRWLatch lock; - int32_t taskFailed; - int32_t taskSucceed; - int32_t taskNum; - SArray *subTasks; // Element is SQueryTask -} SQueryLevel; - typedef struct SQueryJob { uint64_t queryId; int32_t levelNum; @@ -92,8 +93,8 @@ typedef struct SQueryJob { #define SCH_HAS_QNODE_IN_CLUSTER(type) (false) //TODO CLUSTER TYPE #define SCH_TASK_READY_TO_LUNCH(task) ((task)->childReady >= taosArrayGetSize((task)->children)) // MAY NEED TO ENHANCE -#define SCH_IS_DATA_SRC_TASK(task) (task->plan->type == QUERY_TYPE_SCAN) -#define SCH_TASK_NEED_WAIT_ALL(type) (task->plan->type == QUERY_TYPE_MODIFY) +#define SCH_IS_DATA_SRC_TASK(task) ((task)->plan->type == QUERY_TYPE_SCAN) +#define SCH_TASK_NEED_WAIT_ALL(task) ((task)->plan->type == QUERY_TYPE_MODIFY) #define SCH_JOB_ERR_LOG(param, ...) qError("QID:%"PRIx64 param, job->queryId, __VA_ARGS__) #define SCH_TASK_ERR_LOG(param, ...) qError("QID:%"PRIx64",TID:%"PRIx64 param, job->queryId, task->taskId, __VA_ARGS__) diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index a2fbdbe924..4185b3176c 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -647,9 +647,18 @@ void schDropJobAllTasks(SQueryJob *job) { while (pIter) { SQueryTask *task = *(SQueryTask **)pIter; - schAsyncSendMsg(job, task, int32_t msgType); + schAsyncSendMsg(job, task, TSDB_MSG_TYPE_DROP_TASK); - pIter = taosHashIterate(schStatus->tasksHash, pIter); + pIter = taosHashIterate(job->succTasks, pIter); + } + + pIter = taosHashIterate(job->failTasks, NULL); + while (pIter) { + SQueryTask *task = *(SQueryTask **)pIter; + + schAsyncSendMsg(job, task, TSDB_MSG_TYPE_DROP_TASK); + + pIter = taosHashIterate(job->succTasks, pIter); } } From 4426e88098566b8ffaadb7f75960b6d7f9b768b1 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 23 Dec 2021 18:24:24 -0800 Subject: [PATCH 22/22] minor changes --- source/dnode/mgmt/impl/test/db/db.cpp | 73 ++++++++++++++------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/source/dnode/mgmt/impl/test/db/db.cpp b/source/dnode/mgmt/impl/test/db/db.cpp index 378f46aa4d..823f58e3a8 100644 --- a/source/dnode/mgmt/impl/test/db/db.cpp +++ b/source/dnode/mgmt/impl/test/db/db.cpp @@ -162,51 +162,52 @@ TEST_F(DndTestDb, 02_Create_Alter_Drop_Db) { CheckBinary("ms", 3); // precision CheckInt8(0); // update - // restart - test.Restart(); + // // restart + // test.Restart(); - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 17); + // test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + // CHECK_META("show databases", 17); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 1); + // test.SendShowRetrieveMsg(); + // EXPECT_EQ(test.GetShowRows(), 1); - CheckBinary("d1", TSDB_DB_NAME_LEN - 1); - CheckTimestamp(); - CheckInt16(2); // vgroups - CheckInt16(1); // replica - CheckInt16(2); // quorum - CheckInt16(10); // days - CheckBinary("300,400,500", 24); // days - CheckInt32(16); // cache - CheckInt32(12); // blocks - CheckInt32(100); // minrows - CheckInt32(4096); // maxrows - CheckInt8(2); // wallevel - CheckInt32(4000); // fsync - CheckInt8(2); // comp - CheckInt8(1); // cachelast - CheckBinary("ms", 3); // precision - CheckInt8(0); // update + // CheckBinary("d1", TSDB_DB_NAME_LEN - 1); + // CheckTimestamp(); + // CheckInt16(2); // vgroups + // CheckInt16(1); // replica + // CheckInt16(2); // quorum + // CheckInt16(10); // days + // CheckBinary("300,400,500", 24); // days + // CheckInt32(16); // cache + // CheckInt32(12); // blocks + // CheckInt32(100); // minrows + // CheckInt32(4096); // maxrows + // CheckInt8(2); // wallevel + // CheckInt32(4000); // fsync + // CheckInt8(2); // comp + // CheckInt8(1); // cachelast + // CheckBinary("ms", 3); // precision + // CheckInt8(0); // update - { - int32_t contLen = sizeof(SDropDbMsg); + // { + // int32_t contLen = sizeof(SDropDbMsg); - SDropDbMsg* pReq = (SDropDbMsg*)rpcMallocCont(contLen); - strcpy(pReq->db, "1.d1"); + // SDropDbMsg* pReq = (SDropDbMsg*)rpcMallocCont(contLen); + // strcpy(pReq->db, "1.d1"); - SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_DB, pReq, contLen); - ASSERT_NE(pMsg, nullptr); - ASSERT_EQ(pMsg->code, 0); - } + // SRpcMsg* pMsg = test.SendMsg(TSDB_MSG_TYPE_DROP_DB, pReq, contLen); + // ASSERT_NE(pMsg, nullptr); + // ASSERT_EQ(pMsg->code, 0); + // } - test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); - CHECK_META("show databases", 17); + // test.SendShowMetaMsg(TSDB_MGMT_TABLE_DB, ""); + // CHECK_META("show databases", 17); - test.SendShowRetrieveMsg(); - EXPECT_EQ(test.GetShowRows(), 0); + // test.SendShowRetrieveMsg(); + // EXPECT_EQ(test.GetShowRows(), 0); } +#if 0 TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { { int32_t contLen = sizeof(SCreateDbMsg); @@ -298,3 +299,5 @@ TEST_F(DndTestDb, 03_Create_Use_Restart_Use_Db) { } } } + +#endif \ No newline at end of file