diff --git a/Jenkinsfile2 b/Jenkinsfile2 index d90bc3061b..cbf663cdcf 100644 --- a/Jenkinsfile2 +++ b/Jenkinsfile2 @@ -33,16 +33,17 @@ def abort_previous(){ milestone(buildNumber) } def pre_test(){ - sh 'hostname' sh ''' + hostname date - sudo rmtaos || echo "taosd has not installed" ''' sh ''' - killall -9 taosd ||echo "no taosd running" - killall -9 gdb || echo "no gdb running" - killall -9 python3.8 || echo "no python program running" + cd ${WK} + git reset --hard + git fetch || git fetch cd ${WKC} + git reset --hard + git fetch || git fetch ''' script { if (env.CHANGE_TARGET == 'master') { @@ -81,10 +82,10 @@ def pre_test(){ git pull >/dev/null git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - git log|head -n20 + git log -5 cd ${WK} git pull >/dev/null - git log|head -n20 + git log -5 ''' } else if (env.CHANGE_URL =~ /\/TDinternal\//) { sh ''' @@ -92,10 +93,10 @@ def pre_test(){ git pull >/dev/null git fetch origin +refs/pull/${CHANGE_ID}/merge git checkout -qf FETCH_HEAD - git log|head -n20 + git log -5 cd ${WKC} git pull >/dev/null - git log|head -n20 + git log -5 ''' } else { sh ''' @@ -106,21 +107,10 @@ def pre_test(){ cd ${WKC} git submodule update --init --recursive ''' - sh ''' - cd ${WK} - export TZ=Asia/Harbin - date - rm -rf debug - mkdir debug - cd debug - cmake .. > /dev/null - make -j4> /dev/null - ''' sh ''' cd ${WKPY} git reset --hard git pull - pip3 install . ''' return 1 } @@ -131,12 +121,14 @@ def pre_test_win(){ time /t taskkill /f /t /im python.exe taskkill /f /t /im bash.exe - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine - rd /s /Q C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine\\debug + rd /s /Q C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\debug exit 0 ''' bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git reset --hard + git fetch || git fetch + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community git reset --hard git fetch || git fetch git checkout -f @@ -144,39 +136,73 @@ def pre_test_win(){ script { if (env.CHANGE_TARGET == 'master') { bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git checkout master + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community git checkout master ''' } else if(env.CHANGE_TARGET == '2.0') { bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git checkout 2.0 + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community git checkout 2.0 ''' } else if(env.CHANGE_TARGET == '3.0') { bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git checkout 3.0 + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community git checkout 3.0 ''' } else { bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git checkout develop + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community git checkout develop ''' } } + script { + if (env.CHANGE_URL =~ /\/TDengine\//) { + bat ''' + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git pull + git log -5 + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community + git pull + git fetch origin +refs/pull/${CHANGE_ID}/merge + git checkout -qf FETCH_HEAD + git log -5 + ''' + } else if (env.CHANGE_URL =~ /\/TDinternal\//) { + bat ''' + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal + git pull + git fetch origin +refs/pull/${CHANGE_ID}/merge + git checkout -qf FETCH_HEAD + git log -5 + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community + git pull + git log -5 + ''' + } else { + sh ''' + echo "unmatched reposiotry ${CHANGE_URL}" + ''' + } + } bat ''' - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine - git branch - git pull || git pull - git fetch origin +refs/pull/%CHANGE_ID%/merge - git checkout -qf FETCH_HEAD + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community + git submodule update --init --recursive ''' } def pre_test_build_win() { bat ''' echo "building ..." time /t - cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDengine + cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal mkdir debug cd debug call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" x64 @@ -192,6 +218,7 @@ pipeline { agent none options { skipDefaultCheckout() } environment{ + WKDIR = '/var/lib/jenkins/workspace' WK = '/var/lib/jenkins/workspace/TDinternal' WKC = '/var/lib/jenkins/workspace/TDinternal/community' WKPY = '/var/lib/jenkins/workspace/taos-connector-python' @@ -206,39 +233,23 @@ pipeline { changeRequest() } steps { - timeout(time: 45, unit: 'MINUTES'){ + timeout(time: 40, unit: 'MINUTES'){ pre_test() script { - if (env.CHANGE_URL =~ /\/TDengine\//) { - sh ''' - cd ${WK}/debug - ctest -VV - ''' - sh ''' - export LD_LIBRARY_PATH=${WK}/debug/build/lib - cd ${WKC}/tests/system-test - ./fulltest.sh - ''' - } else if (env.CHANGE_URL =~ /\/TDinternal\//) { - sh ''' - cd ${WKC}/debug - ctest -VV - ''' - sh ''' - export LD_LIBRARY_PATH=${WKC}/debug/build/lib - cd ${WKC}/tests/system-test - ./fulltest.sh - ''' - } else { - sh ''' - echo "unmatched reposiotry ${CHANGE_URL}" - ''' - } + sh ''' + cd ${WKC}/tests/parallel_test + date + time ./container_build.sh -w ${WKDIR} -t 8 -e + rm -f /tmp/cases.task + ./collect_cases.sh -e + ''' + sh ''' + cd ${WKC}/tests/parallel_test + export DEFAULT_RETRY_TIME=2 + date + timeout 2100 time ./run.sh -e -m /home/m.json -t /tmp/cases.task -b ${BRANCH_NAME} -l ${WKDIR}/log -o 480 + ''' } - sh ''' - cd ${WKC}/tests - ./test-all.sh b1fq - ''' } } } diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 926fbc8957..14a85ee4f6 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -365,7 +365,7 @@ if(${BUILD_ADDR2LINE}) if(HAVE_LIBELF_H OR HAVE_LIBELF_LIBELF_H) target_link_libraries(libdwarf PUBLIC libelf) endif() - target_include_directories(libdwarf SYSTEM PUBLIC "libdwarf/src/lib/libdwarf" ${CMAKE_BINARY_DIR}/contrib) + target_include_directories(libdwarf SYSTEM PUBLIC "libdwarf/src/lib/libdwarf" ${CMAKE_CURRENT_BINARY_DIR}) file(READ "addr2line/addr2line.c" ADDR2LINE_CONTENT) string(REPLACE "static int" "int" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}") string(REPLACE "static void" "void" ADDR2LINE_CONTENT "${ADDR2LINE_CONTENT}") diff --git a/example/src/tmq.c b/example/src/tmq.c index 0b5f3be1b0..b4013f26ee 100644 --- a/example/src/tmq.c +++ b/example/src/tmq.c @@ -22,7 +22,7 @@ static int running = 1; static void msg_process(TAOS_RES* msg) { char buf[1024]; - memset(buf, 0, 1024); + /*memset(buf, 0, 1024);*/ printf("topic: %s\n", tmq_get_topic_name(msg)); printf("vg: %d\n", tmq_get_vgroup_id(msg)); while (1) { @@ -61,7 +61,7 @@ int32_t init_env() { taos_free_result(pRes); pRes = - taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(10)) tags(t1 int)"); + taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int)"); if (taos_errno(pRes) != 0) { printf("failed to create super table st1, reason:%s\n", taos_errstr(pRes)); return -1; @@ -106,8 +106,8 @@ int32_t create_topic() { } taos_free_result(pRes); - /*pRes = taos_query(pConn, "create topic topic_ctb_column as abc1");*/ - pRes = taos_query(pConn, "create topic topic_ctb_column as select ts, c1, c2, c3 from st1"); + pRes = taos_query(pConn, "create topic topic_ctb_column as abc1"); + /*pRes = taos_query(pConn, "create topic topic_ctb_column as select ts, c1, c2, c3 from st1");*/ if (taos_errno(pRes) != 0) { printf("failed to create topic topic_ctb_column, reason:%s\n", taos_errstr(pRes)); return -1; diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 3c1189da6e..9e3ad42a82 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -48,6 +48,7 @@ enum { typedef enum EStreamType { STREAM_NORMAL = 1, STREAM_INVERT, + STREAM_REPROCESS, STREAM_INVALID, } EStreamType; diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 84aae46347..fd8cea449f 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -34,7 +34,6 @@ extern int32_t tsVersion; extern int32_t tsStatusInterval; // common -extern int32_t tsMaxConnections; extern int32_t tsMaxShellConns; extern int32_t tsShellActivityTimer; extern int32_t tsCompressMsgSize; diff --git a/include/common/tmsgcb.h b/include/common/tmsgcb.h index b6c96bb2d1..a484c2acc9 100644 --- a/include/common/tmsgcb.h +++ b/include/common/tmsgcb.h @@ -37,11 +37,12 @@ typedef enum { QUEUE_MAX, } EQueueType; -typedef int32_t (*PutToQueueFp)(SMgmtWrapper* pWrapper, SRpcMsg* pReq); -typedef int32_t (*GetQueueSizeFp)(SMgmtWrapper* pWrapper, int32_t vgId, EQueueType qtype); +typedef int32_t (*PutToQueueFp)(void *pMgmt, SRpcMsg* pReq); +typedef int32_t (*GetQueueSizeFp)(void *pMgmt, int32_t vgId, EQueueType qtype); typedef int32_t (*SendReqFp)(SMgmtWrapper* pWrapper, const SEpSet* epSet, SRpcMsg* pReq); typedef int32_t (*SendMnodeReqFp)(SMgmtWrapper* pWrapper, SRpcMsg* pReq); typedef void (*SendRspFp)(SMgmtWrapper* pWrapper, const SRpcMsg* pRsp); +typedef void (*SendMnodeRecvFp)(SMgmtWrapper* pWrapper, SRpcMsg* pReq, SRpcMsg* pRsp); typedef void (*SendRedirectRspFp)(SMgmtWrapper* pWrapper, const SRpcMsg* pRsp, const SEpSet* pNewEpSet); typedef void (*RegisterBrokenLinkArgFp)(SMgmtWrapper* pWrapper, SRpcMsg* pMsg); typedef void (*ReleaseHandleFp)(SMgmtWrapper* pWrapper, void* handle, int8_t type); @@ -49,23 +50,26 @@ typedef void (*ReportStartup)(SMgmtWrapper* pWrapper, const char* name, const ch typedef struct { SMgmtWrapper* pWrapper; + void* pMgmt; + void* clientRpc; PutToQueueFp queueFps[QUEUE_MAX]; GetQueueSizeFp qsizeFp; SendReqFp sendReqFp; SendRspFp sendRspFp; + SendMnodeRecvFp sendMnodeRecvFp; SendRedirectRspFp sendRedirectRspFp; RegisterBrokenLinkArgFp registerBrokenLinkArgFp; ReleaseHandleFp releaseHandleFp; ReportStartup reportStartupFp; - void* clientRpc; } SMsgCb; void tmsgSetDefaultMsgCb(const SMsgCb* pMsgCb); int32_t tmsgPutToQueue(const SMsgCb* pMsgCb, EQueueType qtype, SRpcMsg* pReq); int32_t tmsgGetQueueSize(const SMsgCb* pMsgCb, int32_t vgId, EQueueType qtype); int32_t tmsgSendReq(const SMsgCb* pMsgCb, const SEpSet* epSet, SRpcMsg* pReq); -void tmsgSendRsp(const SRpcMsg* pRsp); -void tmsgSendRedirectRsp(const SRpcMsg* pRsp, const SEpSet* pNewEpSet); +void tmsgSendRsp(SRpcMsg* pRsp); +void tmsgSendMnodeRecv(SRpcMsg* pReq, SRpcMsg* pRsp); +void tmsgSendRedirectRsp(SRpcMsg* pRsp, const SEpSet* pNewEpSet); void tmsgRegisterBrokenLinkArg(const SMsgCb* pMsgCb, SRpcMsg* pMsg); void tmsgReleaseHandle(void* handle, int8_t type); void tmsgReportStartup(const char* name, const char* desc); diff --git a/include/libs/function/function.h b/include/libs/function/function.h index 88ac1532c2..8d0b93dde2 100644 --- a/include/libs/function/function.h +++ b/include/libs/function/function.h @@ -126,7 +126,7 @@ enum { enum { MAIN_SCAN = 0x0u, - REVERSE_SCAN = 0x1u, + REVERSE_SCAN = 0x1u, // todo remove it REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan MERGE_STAGE = 0x20u, }; @@ -173,6 +173,7 @@ typedef struct SqlFunctionCtx { SInputColumnInfoData input; SResultDataInfo resDataInfo; uint32_t order; // data block scanner order: asc|desc + uint8_t scanFlag; // record current running step, default: 0 //////////////////////////////////////////////////////////////// int32_t startRow; // start row index int32_t size; // handled processed row number @@ -183,7 +184,6 @@ typedef struct SqlFunctionCtx { bool hasNull; // null value exist in current block, TODO remove it bool requireNull; // require null in some function, TODO remove it int32_t columnIndex; // TODO remove it - uint8_t currentStage; // record current running step, default: 0 bool isAggSet; int64_t startTs; // timestamp range of current query when function is executed on a specific data block, TODO remove it bool stableQuery; @@ -222,13 +222,6 @@ enum { typedef struct tExprNode { int32_t nodeType; union { - struct { - int32_t optr; // binary operator - void *info; // support filter operation on this expression only available for leaf node - struct tExprNode *pLeft; // left child pointer - struct tExprNode *pRight; // right child pointer - } _node; - SSchema *pSchema;// column node struct SVariant *pVal; // value node @@ -237,12 +230,6 @@ typedef struct tExprNode { int32_t functionId; int32_t num; struct SFunctionNode *pFunctNode; - // Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the - // calculation instead. - // E.g., Cov(col1, col2), the column information, w.r.t. the col1 and col2, is kept in pChild nodes. - // The concat function, concat(col1, col2), is a binary scalar - // operator and is kept in the attribute of _node. - struct tExprNode **pChild; } _function; struct { @@ -271,9 +258,10 @@ typedef struct SAggFunctionInfo { } SAggFunctionInfo; struct SScalarParam { - SColumnInfoData *columnData; - SHashObj *pHashFilter; - int32_t numOfRows; + SColumnInfoData *columnData; + SHashObj *pHashFilter; + void *param; // other parameter, such as meta handle from vnode, to extract table name/tag value + int32_t numOfRows; }; int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength, @@ -281,10 +269,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId); -tExprNode* exprTreeFromBinary(const void* data, size_t size); - -tExprNode* exprdup(tExprNode* pTree); - void resetResultRowEntryResult(SqlFunctionCtx* pCtx, int32_t num); void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell); int32_t getNumOfResult(SqlFunctionCtx* pCtx, int32_t num, SSDataBlock* pResBlock); diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index d0d10b2761..7ca4ca9172 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -193,7 +193,6 @@ typedef struct SScanPhysiNode { } SScanPhysiNode; typedef SScanPhysiNode STagScanPhysiNode; -typedef SScanPhysiNode SStreamScanPhysiNode; typedef struct SSystemTableScanPhysiNode { SScanPhysiNode scan; @@ -217,6 +216,7 @@ typedef struct STableScanPhysiNode { } STableScanPhysiNode; typedef STableScanPhysiNode STableSeqScanPhysiNode; +typedef STableScanPhysiNode SStreamScanPhysiNode; typedef struct SProjectPhysiNode { SPhysiNode node; diff --git a/include/util/tdef.h b/include/util/tdef.h index 022fd8ba8e..f95d96be56 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -425,9 +425,12 @@ enum { SND_WORKER_TYPE__UNIQUE, }; -#define MNODE_HANDLE -1 -#define QNODE_HANDLE 1 #define DEFAULT_HANDLE 0 +#define MNODE_HANDLE -1 +#define QNODE_HANDLE -2 +#define SNODE_HANDLE -3 +#define VNODE_HANDLE -4 +#define BNODE_HANDLE -5 #define TSDB_CONFIG_OPTION_LEN 16 #define TSDB_CONIIG_VALUE_LEN 48 diff --git a/include/util/tjson.h b/include/util/tjson.h index d23f7b402e..a95efe56e7 100644 --- a/include/util/tjson.h +++ b/include/util/tjson.h @@ -22,17 +22,12 @@ extern "C" { #endif -#ifdef WINDOWS -#define tjsonGetNumberValue(pJson, pName, val) -1 -#else -#define tjsonGetNumberValue(pJson, pName, val) \ - ({ \ - uint64_t _tmp = 0; \ - int32_t _code = tjsonGetUBigIntValue(pJson, pName, &_tmp); \ - val = _tmp; \ - _code; \ - }) -#endif +#define tjsonGetNumberValue(pJson, pName, val, code) \ + do { \ + uint64_t _tmp = 0; \ + code = tjsonGetUBigIntValue(pJson, pName, &_tmp); \ + val = _tmp; \ + } while (0) typedef void SJson; diff --git a/source/client/inc/clientStmt.h b/source/client/inc/clientStmt.h index ae27e611cb..f0c9dcd67d 100644 --- a/source/client/inc/clientStmt.h +++ b/source/client/inc/clientStmt.h @@ -63,7 +63,7 @@ typedef struct SStmtBindInfo { int8_t tbType; bool tagsCached; void* boundTags; - char tbName[TSDB_TABLE_FNAME_LEN];; + char tbName[TSDB_TABLE_FNAME_LEN]; char tbFName[TSDB_TABLE_FNAME_LEN]; char stbFName[TSDB_TABLE_FNAME_LEN]; SName sname; @@ -71,7 +71,6 @@ typedef struct SStmtBindInfo { typedef struct SStmtExecInfo { int32_t affectedRows; - bool emptyRes; SRequestObj* pRequest; SHashObj* pVgHash; SHashObj* pBlockHash; @@ -87,7 +86,6 @@ typedef struct SStmtSQLInfo { char* sqlStr; int32_t sqlLen; SArray* nodeList; - SQueryPlan* pQueryPlan; SStmtQueryResInfo queryRes; bool autoCreateTbl; } SStmtSQLInfo; diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 819c50275b..c82cce9af3 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -91,7 +91,7 @@ void *openTransporter(const char *user, const char *auth, int32_t numOfThread) { rpcInit.label = "TSC"; rpcInit.numOfThreads = numOfThread; rpcInit.cfp = processMsgFromServer; - rpcInit.sessions = tsMaxConnections; + rpcInit.sessions = 1024; rpcInit.connType = TAOS_CONN_CLIENT; rpcInit.user = (char *)user; rpcInit.idleTime = tsShellActivityTimer * 1000; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index ae6aee13d5..7360b054e2 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -303,6 +303,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) break; } } + str[len] = 0; return len; } @@ -567,7 +568,7 @@ void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param // todo directly call fp } - taos_query_l(taos, sql, (int32_t) strlen(sql)); + taos_query_l(taos, sql, (int32_t)strlen(sql)); } void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index c6fb83b296..605d71ffed 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -2006,8 +2006,8 @@ static int32_t smlParseInfluxLine(SSmlHandle* info, const char* sql) { (*oneTable)->sTableName = elements.measure; (*oneTable)->sTableNameLen = elements.measureLen; - RandTableName rName = {.tags=(*oneTable)->tags, .sTableName=(*oneTable)->sTableName, .sTableNameLen=(uint8_t)(*oneTable)->sTableNameLen, - .childTableName=(*oneTable)->childTableName}; + RandTableName rName = { (*oneTable)->tags, (*oneTable)->sTableName, (uint8_t)(*oneTable)->sTableNameLen, + (*oneTable)->childTableName, 0 }; buildChildTableName(&rName); (*oneTable)->uid = rName.uid; @@ -2070,8 +2070,8 @@ static int32_t smlParseTelnetLine(SSmlHandle* info, void *data) { } taosHashClear(info->dumplicateKey); - RandTableName rName = {.tags=tinfo->tags, .sTableName=tinfo->sTableName, .sTableNameLen=(uint8_t)tinfo->sTableNameLen, - .childTableName=tinfo->childTableName}; + RandTableName rName = { tinfo->tags, tinfo->sTableName, (uint8_t)tinfo->sTableNameLen, + tinfo->childTableName, 0 }; buildChildTableName(&rName); tinfo->uid = rName.uid; diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 29f965fd74..1e9cb7b24f 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -279,7 +279,6 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) { } pStmt->exec.autoCreateTbl = false; - pStmt->exec.emptyRes = false; if (keepTable) { return TSDB_CODE_SUCCESS; @@ -298,7 +297,6 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) { taosMemoryFree(pStmt->sql.queryRes.userFields); taosMemoryFree(pStmt->sql.sqlStr); qDestroyQuery(pStmt->sql.pQuery); - qDestroyQueryPlan(pStmt->sql.pQueryPlan); taosArrayDestroy(pStmt->sql.nodeList); void* pIter = taosHashIterate(pStmt->sql.pTableCache, NULL); @@ -599,6 +597,8 @@ int32_t stmtFetchColFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fiel int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) { STscStmt* pStmt = (STscStmt*)stmt; + STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_BIND)); + if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { pStmt->bInfo.needParse = false; @@ -617,21 +617,42 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) { STMT_ERR_RET(stmtParseSql(pStmt)); } - STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_BIND)); - if (STMT_TYPE_QUERY == pStmt->sql.type) { - if (NULL == pStmt->sql.pQueryPlan) { - STMT_ERR_RET(getQueryPlan(pStmt->exec.pRequest, pStmt->sql.pQuery, &pStmt->sql.nodeList)); - pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag; - pStmt->exec.pRequest->body.pDag = NULL; - STMT_ERR_RET(stmtBackupQueryFields(pStmt)); - } else { - STMT_ERR_RET(stmtRestoreQueryFields(pStmt)); - } + STMT_ERR_RET(qStmtBindParams(pStmt->sql.pQuery, bind, colIdx, pStmt->exec.pRequest->requestId)); + + SParseContext ctx = {.requestId = pStmt->exec.pRequest->requestId, + .acctId = pStmt->taos->acctId, + .db = pStmt->exec.pRequest->pDb, + .topicQuery = false, + .pSql = pStmt->sql.sqlStr, + .sqlLen = pStmt->sql.sqlLen, + .pMsg = pStmt->exec.pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE, + .pTransporter = pStmt->taos->pAppInfo->pTransporter, + .pStmtCb = NULL, + .pUser = pStmt->taos->user}; + ctx.mgmtEpSet = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp); + STMT_ERR_RET(catalogGetHandle(pStmt->taos->pAppInfo->clusterId, &ctx.pCatalog)); + + STMT_ERR_RET(qStmtParseQuerySql(&ctx, pStmt->sql.pQuery)); - STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId, &pStmt->exec.emptyRes)); - } + if (pStmt->sql.pQuery->haveResultSet) { + setResSchemaInfo(&pStmt->exec.pRequest->body.resInfo, pStmt->sql.pQuery->pResSchema, pStmt->sql.pQuery->numOfResCols); + setResPrecision(&pStmt->exec.pRequest->body.resInfo, pStmt->sql.pQuery->precision); + } + TSWAP(pStmt->exec.pRequest->dbList, pStmt->sql.pQuery->pDbList); + TSWAP(pStmt->exec.pRequest->tableList, pStmt->sql.pQuery->pTableList); + + //if (STMT_TYPE_QUERY == pStmt->sql.queryRes) { + // STMT_ERR_RET(stmtRestoreQueryFields(pStmt)); + //} + + //STMT_ERR_RET(stmtBackupQueryFields(pStmt)); + + return TSDB_CODE_SUCCESS; + } + STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, pStmt->bInfo.tbFName, strlen(pStmt->bInfo.tbFName)); if (NULL == pDataBlock) { tscError("table %s not found in exec blockHash", pStmt->bInfo.tbFName); @@ -736,11 +757,7 @@ int stmtExec(TAOS_STMT *stmt) { STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_EXECUTE)); if (STMT_TYPE_QUERY == pStmt->sql.type) { - if (pStmt->exec.emptyRes) { - pStmt->exec.pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT; - } else { - scheduleQuery(pStmt->exec.pRequest, pStmt->sql.pQueryPlan, pStmt->sql.nodeList, NULL); - } + launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true, NULL); } else { STMT_ERR_RET(qBuildStmtOutput(pStmt->sql.pQuery, pStmt->exec.pVgHash, pStmt->exec.pBlockHash)); launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, TSDB_CODE_SUCCESS, true, (autoCreateTbl ? (void**)&pRsp : NULL)); @@ -839,16 +856,7 @@ int stmtGetParamNum(TAOS_STMT* stmt, int* nums) { } if (STMT_TYPE_QUERY == pStmt->sql.type) { - if (NULL == pStmt->sql.pQueryPlan) { - STMT_ERR_RET(getQueryPlan(pStmt->exec.pRequest, pStmt->sql.pQuery, &pStmt->sql.nodeList)); - pStmt->sql.pQueryPlan = pStmt->exec.pRequest->body.pDag; - pStmt->exec.pRequest->body.pDag = NULL; - STMT_ERR_RET(stmtBackupQueryFields(pStmt)); - } else { - STMT_ERR_RET(stmtRestoreQueryFields(pStmt)); - } - - *nums = taosArrayGetSize(pStmt->sql.pQueryPlan->pPlaceholderValues); + *nums = taosArrayGetSize(pStmt->sql.pQuery->pPlaceholderValues); } else { STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL)); } diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index a6b8b842f9..639f00ab86 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -185,6 +185,7 @@ typedef struct { int32_t async; tsem_t rspSem; tmq_resp_err_t rspErr; + SArray* offsets; } SMqCommitCbParam; tmq_conf_t* tmq_conf_new() { @@ -246,10 +247,13 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value if (strcmp(key, "msg.with.table.name") == 0) { if (strcmp(value, "true") == 0) { conf->withTbName = 1; + return TMQ_CONF_OK; } else if (strcmp(value, "false") == 0) { conf->withTbName = 0; + return TMQ_CONF_OK; } else if (strcmp(value, "none") == 0) { conf->withTbName = -1; + return TMQ_CONF_OK; } else { return TMQ_CONF_INVALID; } @@ -395,6 +399,9 @@ int32_t tmqCommitCb(void* param, const SDataBuf* pMsg, int32_t code) { if (!pParam->async) tsem_post(&pParam->rspSem); else { + if (pParam->offsets) { + taosArrayDestroy(pParam->offsets); + } tsem_destroy(&pParam->rspSem); /*if (pParam->pArray) {*/ /*taosArrayDestroy(pParam->pArray);*/ @@ -540,10 +547,10 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in // build msg // send to mnode SMqCMCommitOffsetReq req; - SArray* pArray = NULL; + SArray* pOffsets = NULL; if (offsets == NULL) { - pArray = taosArrayInit(0, sizeof(SMqOffset)); + pOffsets = taosArrayInit(0, sizeof(SMqOffset)); for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) { SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i); for (int j = 0; j < taosArrayGetSize(pTopic->vgs); j++) { @@ -553,11 +560,11 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in strcpy(offset.cgroup, tmq->groupId); offset.vgId = pVg->vgId; offset.offset = pVg->currentOffset; - taosArrayPush(pArray, &offset); + taosArrayPush(pOffsets, &offset); } } - req.num = pArray->size; - req.offsets = pArray->pData; + req.num = pOffsets->size; + req.offsets = pOffsets->pData; } else { req.num = taosArrayGetSize(&offsets->container); req.offsets = (SMqOffset*)offsets->container.pData; @@ -591,6 +598,7 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in pParam->tmq = tmq; tsem_init(&pParam->rspSem, 0, 0); pParam->async = async; + pParam->offsets = pOffsets; pRequest->body.requestMsg = (SDataBuf){ .pData = buf, @@ -613,8 +621,8 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, in tsem_destroy(&pParam->rspSem); taosMemoryFree(pParam); - if (pArray) { - taosArrayDestroy(pArray); + if (pOffsets) { + taosArrayDestroy(pOffsets); } } @@ -1015,7 +1023,7 @@ int32_t tmqAskEp(tmq_t* tmq, bool async) { atomic_store_32(&tmq->epSkipCnt, 0); #endif int32_t tlen = sizeof(SMqAskEpReq); - SMqAskEpReq* req = taosMemoryMalloc(tlen); + SMqAskEpReq* req = taosMemoryCalloc(1, tlen); if (req == NULL) { tscError("failed to malloc get subscribe ep buf"); /*atomic_store_8(&tmq->epStatus, 0);*/ @@ -1025,7 +1033,7 @@ int32_t tmqAskEp(tmq_t* tmq, bool async) { req->epoch = htonl(tmq->epoch); strcpy(req->cgroup, tmq->groupId); - SMqAskEpCbParam* pParam = taosMemoryMalloc(sizeof(SMqAskEpCbParam)); + SMqAskEpCbParam* pParam = taosMemoryCalloc(1, sizeof(SMqAskEpCbParam)); if (pParam == NULL) { tscError("failed to malloc subscribe param"); taosMemoryFree(req); @@ -1107,7 +1115,7 @@ SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic* reqOffset = tmq->resetOffsetCfg; } - SMqPollReq* pReq = taosMemoryMalloc(sizeof(SMqPollReq)); + SMqPollReq* pReq = taosMemoryCalloc(1, sizeof(SMqPollReq)); if (pReq == NULL) { return NULL; } diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 81682bb734..e4e5abe148 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -26,7 +26,7 @@ static const SSysDbTableSchema dnodesSchema[] = { {.name = "id", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT}, {.name = "endpoint", .bytes = TSDB_EP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, {.name = "vnodes", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT}, - {.name = "max_vnodes", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT}, + {.name = "support_vnodes", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT}, {.name = "status", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP}, {.name = "note", .bytes = 256 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR}, diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 9053101938..43dcf2dfa9 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1447,6 +1447,10 @@ void blockDebugShowData(const SArray* dataBlocks) { for (int32_t k = 0; k < colNum; k++) { SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k); void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes); + if (pColInfoData->hasNull) { + printf(" %15s |", "NULL"); + continue; + } switch (pColInfoData->info.type) { case TSDB_DATA_TYPE_TIMESTAMP: formatTimestamp(pBuf, *(uint64_t*)var, TSDB_TIME_PRECISION_MILLI); @@ -1464,6 +1468,9 @@ void blockDebugShowData(const SArray* dataBlocks) { case TSDB_DATA_TYPE_UBIGINT: printf(" %15lu |", *(uint64_t*)var); break; + case TSDB_DATA_TYPE_DOUBLE: + printf(" %15f |", *(double*)var); + break; } } printf("\n"); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 0999cb4d2c..e750b26af7 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -33,18 +33,17 @@ int32_t tsStatusInterval = 1; // second // common int32_t tsMaxShellConns = 50000; -int32_t tsMaxConnections = 50000; int32_t tsShellActivityTimer = 3; // second bool tsEnableSlaveQuery = true; bool tsPrintAuth = false; // multi process bool tsMultiProcess = false; -int32_t tsMnodeShmSize = TSDB_MAX_WAL_SIZE * 2; -int32_t tsVnodeShmSize = TSDB_MAX_WAL_SIZE * 10; -int32_t tsQnodeShmSize = TSDB_MAX_WAL_SIZE * 4; -int32_t tsSnodeShmSize = TSDB_MAX_WAL_SIZE * 4; -int32_t tsBnodeShmSize = TSDB_MAX_WAL_SIZE * 4; +int32_t tsMnodeShmSize = TSDB_MAX_WAL_SIZE * 2 + 128; +int32_t tsVnodeShmSize = TSDB_MAX_WAL_SIZE * 10 + 128; +int32_t tsQnodeShmSize = TSDB_MAX_WAL_SIZE * 4 + 128; +int32_t tsSnodeShmSize = TSDB_MAX_WAL_SIZE * 4 + 128; +int32_t tsBnodeShmSize = TSDB_MAX_WAL_SIZE * 4 + 128; // queue & threads int32_t tsNumOfRpcThreads = 1; @@ -280,6 +279,7 @@ int32_t taosAddClientLogCfg(SConfig *pCfg) { if (cfgAddInt32(pCfg, "cDebugFlag", cDebugFlag, 0, 255, 1) != 0) return -1; if (cfgAddInt32(pCfg, "uDebugFlag", uDebugFlag, 0, 255, 1) != 0) return -1; if (cfgAddInt32(pCfg, "rpcDebugFlag", rpcDebugFlag, 0, 255, 1) != 0) return -1; + if (cfgAddInt32(pCfg, "qDebugFlag", qDebugFlag, 0, 255, 1) != 0) return -1; if (cfgAddInt32(pCfg, "tmrDebugFlag", tmrDebugFlag, 0, 255, 1) != 0) return -1; if (cfgAddInt32(pCfg, "jniDebugFlag", jniDebugFlag, 0, 255, 1) != 0) return -1; if (cfgAddInt32(pCfg, "simDebugFlag", 143, 0, 255, 1) != 0) return -1; @@ -351,15 +351,14 @@ static int32_t taosAddSystemCfg(SConfig *pCfg) { } static int32_t taosAddServerCfg(SConfig *pCfg) { - if (cfgAddInt32(pCfg, "supportVnodes", 256, 0, 4096, 0) != 0) return -1; if (cfgAddDir(pCfg, "dataDir", tsDataDir, 0) != 0) return -1; if (cfgAddFloat(pCfg, "minimalDataDirGB", 2.0f, 0.001f, 10000000, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "maxNumOfDistinctRes", tsMaxNumOfDistinctResults, 10 * 10000, 10000 * 10000, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "maxConnections", tsMaxConnections, 1, 100000, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "supportVnodes", 256, 0, 4096, 0) != 0) return -1; if (cfgAddInt32(pCfg, "maxShellConns", tsMaxShellConns, 10, 50000000, 0) != 0) return -1; if (cfgAddInt32(pCfg, "statusInterval", tsStatusInterval, 1, 30, 0) != 0) return -1; if (cfgAddInt32(pCfg, "minSlidingTime", tsMinSlidingTime, 10, 1000000, 0) != 0) return -1; if (cfgAddInt32(pCfg, "minIntervalTime", tsMinIntervalTime, 1, 1000000, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "maxNumOfDistinctRes", tsMaxNumOfDistinctResults, 10 * 10000, 10000 * 10000, 0) != 0) return -1; if (cfgAddInt32(pCfg, "maxStreamCompDelay", tsMaxStreamComputDelay, 10, 1000000000, 0) != 0) return -1; if (cfgAddInt32(pCfg, "maxFirstStreamCompDelay", tsStreamCompStartDelay, 1000, 1000000000, 0) != 0) return -1; if (cfgAddInt32(pCfg, "retryStreamCompDelay", tsRetryStreamCompDelay, 10, 1000000000, 0) != 0) return -1; @@ -371,11 +370,11 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "deadLockKillQuery", tsDeadLockKillQuery, 0) != 0) return -1; if (cfgAddBool(pCfg, "multiProcess", tsMultiProcess, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "mnodeShmSize", tsMnodeShmSize, 4096, INT32_MAX, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "vnodeShmSize", tsVnodeShmSize, 4096, INT32_MAX, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "qnodeShmSize", tsQnodeShmSize, 4096, INT32_MAX, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "snodeShmSize", tsSnodeShmSize, 4096, INT32_MAX, 0) != 0) return -1; - if (cfgAddInt32(pCfg, "bnodeShmSize", tsBnodeShmSize, 4096, INT32_MAX, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "mnodeShmSize", tsMnodeShmSize, TSDB_MAX_WAL_SIZE + 128, INT32_MAX, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "vnodeShmSize", tsVnodeShmSize, TSDB_MAX_WAL_SIZE + 128, INT32_MAX, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "qnodeShmSize", tsQnodeShmSize, TSDB_MAX_WAL_SIZE + 128, INT32_MAX, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "snodeShmSize", tsSnodeShmSize, TSDB_MAX_WAL_SIZE + 128, INT32_MAX, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "bnodeShmSize", tsBnodeShmSize, TSDB_MAX_WAL_SIZE + 128, INT32_MAX, 0) != 0) return -1; tsNumOfRpcThreads = tsNumOfCores / 2; tsNumOfRpcThreads = TRANGE(tsNumOfRpcThreads, 1, 4); @@ -458,6 +457,7 @@ static void taosSetClientLogCfg(SConfig *pCfg) { tsLogKeepDays = cfgGetItem(pCfg, "logKeepDays")->i32; cDebugFlag = cfgGetItem(pCfg, "cDebugFlag")->i32; uDebugFlag = cfgGetItem(pCfg, "uDebugFlag")->i32; + qDebugFlag = cfgGetItem(pCfg, "qDebugFlag")->i32; rpcDebugFlag = cfgGetItem(pCfg, "rpcDebugFlag")->i32; tmrDebugFlag = cfgGetItem(pCfg, "tmrDebugFlag")->i32; jniDebugFlag = cfgGetItem(pCfg, "jniDebugFlag")->i32; @@ -533,12 +533,11 @@ static void taosSetSystemCfg(SConfig *pCfg) { static int32_t taosSetServerCfg(SConfig *pCfg) { tsDataSpace.reserved = cfgGetItem(pCfg, "minimalDataDirGB")->fval; - tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32; - tsMaxConnections = cfgGetItem(pCfg, "maxConnections")->i32; tsMaxShellConns = cfgGetItem(pCfg, "maxShellConns")->i32; tsStatusInterval = cfgGetItem(pCfg, "statusInterval")->i32; tsMinSlidingTime = cfgGetItem(pCfg, "minSlidingTime")->i32; tsMinIntervalTime = cfgGetItem(pCfg, "minIntervalTime")->i32; + tsMaxNumOfDistinctResults = cfgGetItem(pCfg, "maxNumOfDistinctRes")->i32; tsMaxStreamComputDelay = cfgGetItem(pCfg, "maxStreamCompDelay")->i32; tsStreamCompStartDelay = cfgGetItem(pCfg, "maxFirstStreamCompDelay")->i32; tsRetryStreamCompDelay = cfgGetItem(pCfg, "retryStreamCompDelay")->i32; diff --git a/source/common/src/tmsgcb.c b/source/common/src/tmsgcb.c index 42612cecb9..78b70c9288 100644 --- a/source/common/src/tmsgcb.c +++ b/source/common/src/tmsgcb.c @@ -19,12 +19,16 @@ static SMsgCb tsDefaultMsgCb; -void tmsgSetDefaultMsgCb(const SMsgCb* pMsgCb) { tsDefaultMsgCb = *pMsgCb; } +void tmsgSetDefaultMsgCb(const SMsgCb* pMsgCb) { + // if (tsDefaultMsgCb.pWrapper == NULL) { + tsDefaultMsgCb = *pMsgCb; + //} +} int32_t tmsgPutToQueue(const SMsgCb* pMsgCb, EQueueType qtype, SRpcMsg* pReq) { PutToQueueFp fp = pMsgCb->queueFps[qtype]; if (fp != NULL) { - return (*fp)(pMsgCb->pWrapper, pReq); + return (*fp)(pMsgCb->pMgmt, pReq); } else { terrno = TSDB_CODE_INVALID_PTR; return -1; @@ -34,7 +38,7 @@ int32_t tmsgPutToQueue(const SMsgCb* pMsgCb, EQueueType qtype, SRpcMsg* pReq) { int32_t tmsgGetQueueSize(const SMsgCb* pMsgCb, int32_t vgId, EQueueType qtype) { GetQueueSizeFp fp = pMsgCb->qsizeFp; if (fp != NULL) { - return (*fp)(pMsgCb->pWrapper, vgId, qtype); + return (*fp)(pMsgCb->pMgmt, vgId, qtype); } else { terrno = TSDB_CODE_INVALID_PTR; return -1; @@ -51,7 +55,7 @@ int32_t tmsgSendReq(const SMsgCb* pMsgCb, const SEpSet* epSet, SRpcMsg* pReq) { } } -void tmsgSendRsp(const SRpcMsg* pRsp) { +void tmsgSendRsp(SRpcMsg* pRsp) { SendRspFp fp = tsDefaultMsgCb.sendRspFp; if (fp != NULL) { return (*fp)(tsDefaultMsgCb.pWrapper, pRsp); @@ -60,7 +64,7 @@ void tmsgSendRsp(const SRpcMsg* pRsp) { } } -void tmsgSendRedirectRsp(const SRpcMsg* pRsp, const SEpSet* pNewEpSet) { +void tmsgSendRedirectRsp(SRpcMsg* pRsp, const SEpSet* pNewEpSet) { SendRedirectRspFp fp = tsDefaultMsgCb.sendRedirectRspFp; if (fp != NULL) { (*fp)(tsDefaultMsgCb.pWrapper, pRsp, pNewEpSet); @@ -69,6 +73,15 @@ void tmsgSendRedirectRsp(const SRpcMsg* pRsp, const SEpSet* pNewEpSet) { } } +void tmsgSendMnodeRecv(SRpcMsg* pReq, SRpcMsg* pRsp) { + SendMnodeRecvFp fp = tsDefaultMsgCb.sendMnodeRecvFp; + if (fp != NULL) { + (*fp)(tsDefaultMsgCb.pWrapper, pReq, pRsp); + } else { + terrno = TSDB_CODE_INVALID_PTR; + } +} + void tmsgRegisterBrokenLinkArg(const SMsgCb* pMsgCb, SRpcMsg* pMsg) { RegisterBrokenLinkArgFp fp = pMsgCb->registerBrokenLinkArgFp; if (fp != NULL) { diff --git a/source/dnode/mgmt/CMakeLists.txt b/source/dnode/mgmt/CMakeLists.txt index 49ea54e928..581686ba90 100644 --- a/source/dnode/mgmt/CMakeLists.txt +++ b/source/dnode/mgmt/CMakeLists.txt @@ -1,16 +1,17 @@ -add_subdirectory(interface) -add_subdirectory(implement) +add_subdirectory(node_mgmt) +add_subdirectory(node_util) add_subdirectory(mgmt_bnode) add_subdirectory(mgmt_mnode) add_subdirectory(mgmt_qnode) add_subdirectory(mgmt_snode) add_subdirectory(mgmt_vnode) +add_subdirectory(mgmt_dnode) add_subdirectory(test) aux_source_directory(exe EXEC_SRC) add_executable(taosd ${EXEC_SRC}) target_include_directories( taosd - PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/implement/inc" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/node_mgmt/inc" ) target_link_libraries(taosd dnode) diff --git a/source/dnode/mgmt/exe/dmMain.c b/source/dnode/mgmt/exe/dmMain.c index 4a2d02d25d..81df34ef4a 100644 --- a/source/dnode/mgmt/exe/dmMain.c +++ b/source/dnode/mgmt/exe/dmMain.c @@ -14,7 +14,7 @@ */ #define _DEFAULT_SOURCE -#include "dmImp.h" +#include "dmMgmt.h" #include "tconfig.h" #define DM_APOLLO_URL "The apollo string to use when configuring the server, such as: -a 'jsonFile:./tests/cfg.json', cfg.json text can be '{\"fqdn\":\"td1\"}'." @@ -163,14 +163,14 @@ static SDnodeOpt dmGetOpt() { static int32_t dmInitLog() { char logName[12] = {0}; - snprintf(logName, sizeof(logName), "%slog", dmLogName(global.ntype)); + snprintf(logName, sizeof(logName), "%slog", dmNodeLogName(global.ntype)); return taosCreateLog(logName, 1, configDir, global.envCmd, global.envFile, global.apolloUrl, global.pArgs, 0); } static void dmSetProcInfo(int32_t argc, char **argv) { taosSetProcPath(argc, argv); if (global.ntype != DNODE && global.ntype != NODE_END) { - const char *name = dmProcName(global.ntype); + const char *name = dmNodeProcName(global.ntype); taosSetProcName(argc, argv, name); } } diff --git a/source/dnode/mgmt/implement/inc/dmImp.h b/source/dnode/mgmt/implement/inc/dmImp.h deleted file mode 100644 index 8a1a116ab3..0000000000 --- a/source/dnode/mgmt/implement/inc/dmImp.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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_DND_IMP_H_ -#define _TD_DND_IMP_H_ - -#include "dmInt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int32_t dmOpenNode(SMgmtWrapper *pWrapper); -void dmCloseNode(SMgmtWrapper *pWrapper); - -// dmTransport.c -int32_t dmInitServer(SDnode *pDnode); -void dmCleanupServer(SDnode *pDnode); -int32_t dmInitClient(SDnode *pDnode); -void dmCleanupClient(SDnode *pDnode); -SProcCfg dmGenProcCfg(SMgmtWrapper *pWrapper); -SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper); -int32_t dmInitMsgHandle(SDnode *pDnode); -void dmSendRecv(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp); -void dmSendToMnodeRecv(SDnode *pDnode, SRpcMsg *pReq, SRpcMsg *pRsp); - -// dmEps.c -int32_t dmReadEps(SDnode *pDnode); -int32_t dmWriteEps(SDnode *pDnode); -void dmUpdateEps(SDnode *pDnode, SArray *pDnodeEps); - -// dmHandle.c -void dmSendStatusReq(SDnode *pDnode); -int32_t dmProcessConfigReq(SDnode *pDnode, SNodeMsg *pMsg); -int32_t dmProcessAuthRsp(SDnode *pDnode, SNodeMsg *pMsg); -int32_t dmProcessGrantRsp(SDnode *pDnode, SNodeMsg *pMsg); -int32_t dmProcessCreateNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); -int32_t dmProcessDropNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); - -// dmMonitor.c -void dmGetVnodeLoads(SDnode *pDnode, SMonVloadInfo *pInfo); -void dmGetMnodeLoads(SDnode *pDnode, SMonMloadInfo *pInfo); -void dmSendMonitorReport(SDnode *pDnode); - -// dmWorker.c -int32_t dmStartStatusThread(SDnode *pDnode); -void dmStopStatusThread(SDnode *pDnode); -int32_t dmStartMonitorThread(SDnode *pDnode); -void dmStopMonitorThread(SDnode *pDnode); -int32_t dmStartWorker(SDnode *pDnode); -void dmStopWorker(SDnode *pDnode); -int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t dmProcessStatusMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); - -// mgmt nodes -void dmSetMgmtFp(SMgmtWrapper *pWrapper); -void bmSetMgmtFp(SMgmtWrapper *pWrapper); -void qmSetMgmtFp(SMgmtWrapper *pWrapper); -void smSetMgmtFp(SMgmtWrapper *pWrapper); -void vmSetMgmtFp(SMgmtWrapper *pWrapper); -void mmSetMgmtFp(SMgmtWrapper *pWrapper); - -void vmGetVnodeLoads(SMgmtWrapper *pWrapper, SMonVloadInfo *pInfo); -void mmGetMnodeLoads(SMgmtWrapper *pWrapper, SMonMloadInfo *pInfo); -void mmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonMmInfo *mmInfo); -void vmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonVmInfo *vmInfo); -void qmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonQmInfo *qmInfo); -void smGetMonitorInfo(SMgmtWrapper *pWrapper, SMonSmInfo *smInfo); -void bmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonBmInfo *bmInfo); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_DND_IMP_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/implement/src/dmHandle.c b/source/dnode/mgmt/implement/src/dmHandle.c deleted file mode 100644 index 097d18679b..0000000000 --- a/source/dnode/mgmt/implement/src/dmHandle.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "dmImp.h" - -static void dmUpdateDnodeCfg(SDnode *pDnode, SDnodeCfg *pCfg) { - if (pDnode->data.dnodeId == 0 || pDnode->data.clusterId == 0) { - dInfo("set dnodeId:%d clusterId:%" PRId64, pCfg->dnodeId, pCfg->clusterId); - taosWLockLatch(&pDnode->data.latch); - pDnode->data.dnodeId = pCfg->dnodeId; - pDnode->data.clusterId = pCfg->clusterId; - dmWriteEps(pDnode); - taosWUnLockLatch(&pDnode->data.latch); - } -} - -static int32_t dmProcessStatusRsp(SDnode *pDnode, SRpcMsg *pRsp) { - if (pRsp->code != TSDB_CODE_SUCCESS) { - if (pRsp->code == TSDB_CODE_MND_DNODE_NOT_EXIST && !pDnode->data.dropped && pDnode->data.dnodeId > 0) { - dInfo("dnode:%d, set to dropped since not exist in mnode", pDnode->data.dnodeId); - pDnode->data.dropped = 1; - dmWriteEps(pDnode); - } - } else { - SStatusRsp statusRsp = {0}; - if (pRsp->pCont != NULL && pRsp->contLen > 0 && - tDeserializeSStatusRsp(pRsp->pCont, pRsp->contLen, &statusRsp) == 0) { - pDnode->data.dnodeVer = statusRsp.dnodeVer; - dmUpdateDnodeCfg(pDnode, &statusRsp.dnodeCfg); - dmUpdateEps(pDnode, statusRsp.pDnodeEps); - } - rpcFreeCont(pRsp->pCont); - tFreeSStatusRsp(&statusRsp); - } - - return TSDB_CODE_SUCCESS; -} - -void dmSendStatusReq(SDnode *pDnode) { - SStatusReq req = {0}; - - taosRLockLatch(&pDnode->data.latch); - req.sver = tsVersion; - req.dnodeVer = pDnode->data.dnodeVer; - req.dnodeId = pDnode->data.dnodeId; - req.clusterId = pDnode->data.clusterId; - if (req.clusterId == 0) req.dnodeId = 0; - req.rebootTime = pDnode->data.rebootTime; - req.updateTime = pDnode->data.updateTime; - req.numOfCores = tsNumOfCores; - req.numOfSupportVnodes = pDnode->data.supportVnodes; - tstrncpy(req.dnodeEp, pDnode->data.localEp, TSDB_EP_LEN); - - req.clusterCfg.statusInterval = tsStatusInterval; - req.clusterCfg.checkTime = 0; - char timestr[32] = "1970-01-01 00:00:00.00"; - (void)taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0); - memcpy(req.clusterCfg.timezone, tsTimezoneStr, TD_TIMEZONE_LEN); - memcpy(req.clusterCfg.locale, tsLocale, TD_LOCALE_LEN); - memcpy(req.clusterCfg.charset, tsCharset, TD_LOCALE_LEN); - taosRUnLockLatch(&pDnode->data.latch); - - SMonVloadInfo vinfo = {0}; - dmGetVnodeLoads(pDnode, &vinfo); - req.pVloads = vinfo.pVloads; - pDnode->data.unsyncedVgId = 0; - pDnode->data.vndState = TAOS_SYNC_STATE_LEADER; - for (int32_t i = 0; i < taosArrayGetSize(req.pVloads); ++i) { - SVnodeLoad *pLoad = taosArrayGet(req.pVloads, i); - if (pLoad->syncState != TAOS_SYNC_STATE_LEADER && pLoad->syncState != TAOS_SYNC_STATE_FOLLOWER) { - pDnode->data.unsyncedVgId = pLoad->vgId; - pDnode->data.vndState = pLoad->syncState; - } - } - - SMonMloadInfo minfo = {0}; - dmGetMnodeLoads(pDnode, &minfo); - pDnode->data.isMnode = minfo.isMnode; - pDnode->data.mndState = minfo.load.syncState; - - int32_t contLen = tSerializeSStatusReq(NULL, 0, &req); - void *pHead = rpcMallocCont(contLen); - tSerializeSStatusReq(pHead, contLen, &req); - tFreeSStatusReq(&req); - - SRpcMsg rpcMsg = {.pCont = pHead, .contLen = contLen, .msgType = TDMT_MND_STATUS, .ahandle = (void *)0x9527}; - SRpcMsg rpcRsp = {0}; - - dTrace("send req:%s to mnode, app:%p", TMSG_INFO(rpcMsg.msgType), rpcMsg.ahandle); - dmSendToMnodeRecv(pDnode, &rpcMsg, &rpcRsp); - dmProcessStatusRsp(pDnode, &rpcRsp); -} - -int32_t dmProcessAuthRsp(SDnode *pDnode, SNodeMsg *pMsg) { - SRpcMsg *pRsp = &pMsg->rpcMsg; - dError("auth rsp is received, but not supported yet"); - return 0; -} - -int32_t dmProcessGrantRsp(SDnode *pDnode, SNodeMsg *pMsg) { - SRpcMsg *pRsp = &pMsg->rpcMsg; - dError("grant rsp is received, but not supported yet"); - return 0; -} - -int32_t dmProcessConfigReq(SDnode *pDnode, SNodeMsg *pMsg) { - SRpcMsg *pReq = &pMsg->rpcMsg; - SDCfgDnodeReq *pCfg = pReq->pCont; - dError("config req is received, but not supported yet"); - return TSDB_CODE_OPS_NOT_SUPPORT; -} - -int32_t dmProcessCreateNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg) { - SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype); - if (pWrapper != NULL) { - dmReleaseWrapper(pWrapper); - terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED; - dError("failed to create node since %s", terrstr()); - return -1; - } - - taosThreadMutexLock(&pDnode->mutex); - pWrapper = &pDnode->wrappers[ntype]; - - if (taosMkDir(pWrapper->path) != 0) { - terrno = TAOS_SYSTEM_ERROR(errno); - dError("failed to create dir:%s since %s", pWrapper->path, terrstr()); - return -1; - } - - int32_t code = (*pWrapper->fp.createFp)(pWrapper, pMsg); - if (code != 0) { - dError("node:%s, failed to create since %s", pWrapper->name, terrstr()); - } else { - dDebug("node:%s, has been created", pWrapper->name); - (void)dmOpenNode(pWrapper); - pWrapper->required = true; - pWrapper->deployed = true; - pWrapper->procType = pDnode->ptype; - } - - taosThreadMutexUnlock(&pDnode->mutex); - return code; -} - -int32_t dmProcessDropNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg) { - SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype); - if (pWrapper == NULL) { - terrno = TSDB_CODE_NODE_NOT_DEPLOYED; - dError("failed to drop node since %s", terrstr()); - return -1; - } - - taosThreadMutexLock(&pDnode->mutex); - - int32_t code = (*pWrapper->fp.dropFp)(pWrapper, pMsg); - if (code != 0) { - dError("node:%s, failed to drop since %s", pWrapper->name, terrstr()); - } else { - dDebug("node:%s, has been dropped", pWrapper->name); - pWrapper->required = false; - pWrapper->deployed = false; - } - - dmReleaseWrapper(pWrapper); - - if (code == 0) { - dmCloseNode(pWrapper); - taosRemoveDir(pWrapper->path); - } - taosThreadMutexUnlock(&pDnode->mutex); - return code; -} - -static void dmSetMgmtMsgHandle(SMgmtWrapper *pWrapper) { - // Requests handled by DNODE - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE, dmProcessMgmtMsg, DEFAULT_HANDLE); - - // Requests handled by MNODE - dmSetMsgHandle(pWrapper, TDMT_MND_GRANT_RSP, dmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_AUTH_RSP, dmProcessMgmtMsg, DEFAULT_HANDLE); -} - -static int32_t dmStartMgmt(SMgmtWrapper *pWrapper) { - if (dmStartStatusThread(pWrapper->pDnode) != 0) { - return -1; - } - if (dmStartMonitorThread(pWrapper->pDnode) != 0) { - return -1; - } - return 0; -} - -static void dmStopMgmt(SMgmtWrapper *pWrapper) { - dmStopMonitorThread(pWrapper->pDnode); - dmStopStatusThread(pWrapper->pDnode); -} - -static int32_t dmInitMgmt(SMgmtWrapper *pWrapper) { - dInfo("dnode-mgmt start to init"); - SDnode *pDnode = pWrapper->pDnode; - - pDnode->data.dnodeHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); - if (pDnode->data.dnodeHash == NULL) { - dError("failed to init dnode hash"); - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - if (dmReadEps(pDnode) != 0) { - dError("failed to read file since %s", terrstr()); - return -1; - } - - if (pDnode->data.dropped) { - dError("dnode will not start since its already dropped"); - return -1; - } - - if (dmStartWorker(pDnode) != 0) { - return -1; - } - - if (dmInitServer(pDnode) != 0) { - dError("failed to init transport since %s", terrstr()); - return -1; - } - dmReportStartup(pDnode, "dnode-transport", "initialized"); - - if (udfStartUdfd(pDnode->data.dnodeId) != 0) { - dError("failed to start udfd"); - } - - dInfo("dnode-mgmt is initialized"); - return 0; -} - -static void dmCleanupMgmt(SMgmtWrapper *pWrapper) { - dInfo("dnode-mgmt start to clean up"); - SDnode *pDnode = pWrapper->pDnode; - - udfStopUdfd(); - - dmStopWorker(pDnode); - - taosWLockLatch(&pDnode->data.latch); - if (pDnode->data.dnodeEps != NULL) { - taosArrayDestroy(pDnode->data.dnodeEps); - pDnode->data.dnodeEps = NULL; - } - if (pDnode->data.dnodeHash != NULL) { - taosHashCleanup(pDnode->data.dnodeHash); - pDnode->data.dnodeHash = NULL; - } - taosWUnLockLatch(&pDnode->data.latch); - - dmCleanupClient(pDnode); - dmCleanupServer(pDnode); - dInfo("dnode-mgmt is cleaned up"); -} - -static int32_t dmRequireMgmt(SMgmtWrapper *pWrapper, bool *required) { - *required = true; - return 0; -} - -void dmSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = dmInitMgmt; - mgmtFp.closeFp = dmCleanupMgmt; - mgmtFp.startFp = dmStartMgmt; - mgmtFp.stopFp = dmStopMgmt; - mgmtFp.requiredFp = dmRequireMgmt; - - dmSetMgmtMsgHandle(pWrapper); - pWrapper->name = "dnode"; - pWrapper->fp = mgmtFp; -} diff --git a/source/dnode/mgmt/implement/src/dmMonitor.c b/source/dnode/mgmt/implement/src/dmMonitor.c deleted file mode 100644 index 8543310eb5..0000000000 --- a/source/dnode/mgmt/implement/src/dmMonitor.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "dmImp.h" - -static void dmGetMonitorBasicInfo(SDnode *pDnode, SMonBasicInfo *pInfo) { - pInfo->protocol = 1; - pInfo->dnode_id = pDnode->data.dnodeId; - pInfo->cluster_id = pDnode->data.clusterId; - tstrncpy(pInfo->dnode_ep, tsLocalEp, TSDB_EP_LEN); -} - -static void dmGetMonitorDnodeInfo(SDnode *pDnode, SMonDnodeInfo *pInfo) { - pInfo->uptime = (taosGetTimestampMs() - pDnode->data.rebootTime) / (86400000.0f); - pInfo->has_mnode = pDnode->wrappers[MNODE].required; - pInfo->has_qnode = pDnode->wrappers[QNODE].required; - pInfo->has_snode = pDnode->wrappers[SNODE].required; - pInfo->has_bnode = pDnode->wrappers[BNODE].required; - tstrncpy(pInfo->logdir.name, tsLogDir, sizeof(pInfo->logdir.name)); - pInfo->logdir.size = tsLogSpace.size; - tstrncpy(pInfo->tempdir.name, tsTempDir, sizeof(pInfo->tempdir.name)); - pInfo->tempdir.size = tsTempSpace.size; -} - -static void dmGetMonitorInfo(SDnode *pDnode, SMonDmInfo *pInfo) { - dmGetMonitorBasicInfo(pDnode, &pInfo->basic); - dmGetMonitorSysInfo(&pInfo->sys); - dmGetMonitorDnodeInfo(pDnode, &pInfo->dnode); -} - -void dmSendMonitorReport(SDnode *pDnode) { - if (!tsEnableMonitor || tsMonitorFqdn[0] == 0 || tsMonitorPort == 0) return; - dTrace("send monitor report to %s:%u", tsMonitorFqdn, tsMonitorPort); - - SMonDmInfo dmInfo = {0}; - SMonMmInfo mmInfo = {0}; - SMonVmInfo vmInfo = {0}; - SMonQmInfo qmInfo = {0}; - SMonSmInfo smInfo = {0}; - SMonBmInfo bmInfo = {0}; - - SRpcMsg req = {0}; - SRpcMsg rsp; - SEpSet epset = {.inUse = 0, .numOfEps = 1}; - tstrncpy(epset.eps[0].fqdn, pDnode->data.localFqdn, TSDB_FQDN_LEN); - epset.eps[0].port = tsServerPort; - - SMgmtWrapper *pWrapper = NULL; - dmGetMonitorInfo(pDnode, &dmInfo); - - bool getFromAPI = !tsMultiProcess; - pWrapper = &pDnode->wrappers[MNODE]; - if (getFromAPI) { - if (dmMarkWrapper(pWrapper) == 0) { - mmGetMonitorInfo(pWrapper, &mmInfo); - dmReleaseWrapper(pWrapper); - } - } else { - if (pWrapper->required) { - req.msgType = TDMT_MON_MM_INFO; - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonMmInfo(rsp.pCont, rsp.contLen, &mmInfo); - } - rpcFreeCont(rsp.pCont); - } - } - - pWrapper = &pDnode->wrappers[VNODE]; - if (getFromAPI) { - if (dmMarkWrapper(pWrapper) == 0) { - vmGetMonitorInfo(pWrapper, &vmInfo); - dmReleaseWrapper(pWrapper); - } - } else { - if (pWrapper->required) { - req.msgType = TDMT_MON_VM_INFO; - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonVmInfo(rsp.pCont, rsp.contLen, &vmInfo); - } - rpcFreeCont(rsp.pCont); - } - } - - pWrapper = &pDnode->wrappers[QNODE]; - if (getFromAPI) { - if (dmMarkWrapper(pWrapper) == 0) { - qmGetMonitorInfo(pWrapper, &qmInfo); - dmReleaseWrapper(pWrapper); - } - } else { - if (pWrapper->required) { - req.msgType = TDMT_MON_QM_INFO; - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonQmInfo(rsp.pCont, rsp.contLen, &qmInfo); - } - rpcFreeCont(rsp.pCont); - } - } - - pWrapper = &pDnode->wrappers[SNODE]; - if (getFromAPI) { - if (dmMarkWrapper(pWrapper) == 0) { - smGetMonitorInfo(pWrapper, &smInfo); - dmReleaseWrapper(pWrapper); - } - } else { - if (pWrapper->required) { - req.msgType = TDMT_MON_SM_INFO; - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonSmInfo(rsp.pCont, rsp.contLen, &smInfo); - } - rpcFreeCont(rsp.pCont); - } - } - - pWrapper = &pDnode->wrappers[BNODE]; - if (getFromAPI) { - if (dmMarkWrapper(pWrapper) == 0) { - bmGetMonitorInfo(pWrapper, &bmInfo); - dmReleaseWrapper(pWrapper); - } - } else { - if (pWrapper->required) { - req.msgType = TDMT_MON_BM_INFO; - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonBmInfo(rsp.pCont, rsp.contLen, &bmInfo); - } - rpcFreeCont(rsp.pCont); - } - } - - monSetDmInfo(&dmInfo); - monSetMmInfo(&mmInfo); - monSetVmInfo(&vmInfo); - monSetQmInfo(&qmInfo); - monSetSmInfo(&smInfo); - monSetBmInfo(&bmInfo); - tFreeSMonMmInfo(&mmInfo); - tFreeSMonVmInfo(&vmInfo); - tFreeSMonQmInfo(&qmInfo); - tFreeSMonSmInfo(&smInfo); - tFreeSMonBmInfo(&bmInfo); - monSendReport(); -} - -void dmGetVnodeLoads(SDnode *pDnode, SMonVloadInfo *pInfo) { - SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, VNODE); - if (pWrapper == NULL) return; - - bool getFromAPI = !tsMultiProcess; - if (getFromAPI) { - vmGetVnodeLoads(pWrapper, pInfo); - } else { - SRpcMsg req = {.msgType = TDMT_MON_VM_LOAD}; - SRpcMsg rsp = {0}; - SEpSet epset = {.inUse = 0, .numOfEps = 1}; - tstrncpy(epset.eps[0].fqdn, pDnode->data.localFqdn, TSDB_FQDN_LEN); - epset.eps[0].port = tsServerPort; - - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonVloadInfo(rsp.pCont, rsp.contLen, pInfo); - } - rpcFreeCont(rsp.pCont); - } - dmReleaseWrapper(pWrapper); -} - -void dmGetMnodeLoads(SDnode *pDnode, SMonMloadInfo *pInfo) { - SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, MNODE); - if (pWrapper == NULL) { - pInfo->isMnode = 0; - return; - } - - bool getFromAPI = !tsMultiProcess; - if (getFromAPI) { - mmGetMnodeLoads(pWrapper, pInfo); - } else { - SRpcMsg req = {.msgType = TDMT_MON_MM_LOAD}; - SRpcMsg rsp = {0}; - SEpSet epset = {.inUse = 0, .numOfEps = 1}; - tstrncpy(epset.eps[0].fqdn, pDnode->data.localFqdn, TSDB_FQDN_LEN); - epset.eps[0].port = tsServerPort; - - dmSendRecv(pDnode, &epset, &req, &rsp); - if (rsp.code == 0 && rsp.contLen > 0) { - tDeserializeSMonMloadInfo(rsp.pCont, rsp.contLen, pInfo); - } - rpcFreeCont(rsp.pCont); - } - dmReleaseWrapper(pWrapper); -} diff --git a/source/dnode/mgmt/implement/src/dmObj.c b/source/dnode/mgmt/implement/src/dmObj.c deleted file mode 100644 index a43439d465..0000000000 --- a/source/dnode/mgmt/implement/src/dmObj.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "dmImp.h" - -static int32_t dmInitVars(SDnode *pDnode, const SDnodeOpt *pOption) { - pDnode->data.dnodeId = 0; - pDnode->data.clusterId = 0; - pDnode->data.dnodeVer = 0; - pDnode->data.updateTime = 0; - pDnode->data.rebootTime = taosGetTimestampMs(); - pDnode->data.dropped = 0; - pDnode->data.localEp = strdup(pOption->localEp); - pDnode->data.localFqdn = strdup(pOption->localFqdn); - pDnode->data.firstEp = strdup(pOption->firstEp); - pDnode->data.secondEp = strdup(pOption->secondEp); - pDnode->data.dataDir = strdup(pOption->dataDir); - pDnode->data.disks = pOption->disks; - pDnode->data.numOfDisks = pOption->numOfDisks; - pDnode->data.supportVnodes = pOption->numOfSupportVnodes; - pDnode->data.serverPort = pOption->serverPort; - pDnode->ntype = pOption->ntype; - - if (pDnode->data.dataDir == NULL || pDnode->data.localEp == NULL || pDnode->data.localFqdn == NULL || - pDnode->data.firstEp == NULL || pDnode->data.secondEp == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - if (!tsMultiProcess || pDnode->ntype == DNODE || pDnode->ntype == NODE_END) { - pDnode->data.lockfile = dmCheckRunning(pDnode->data.dataDir); - if (pDnode->data.lockfile == NULL) { - return -1; - } - } - - taosInitRWLatch(&pDnode->data.latch); - taosThreadMutexInit(&pDnode->mutex, NULL); - return 0; -} - -static void dmClearVars(SDnode *pDnode) { - for (EDndNodeType n = DNODE; n < NODE_END; ++n) { - SMgmtWrapper *pMgmt = &pDnode->wrappers[n]; - taosMemoryFreeClear(pMgmt->path); - } - if (pDnode->data.lockfile != NULL) { - taosUnLockFile(pDnode->data.lockfile); - taosCloseFile(&pDnode->data.lockfile); - pDnode->data.lockfile = NULL; - } - taosMemoryFreeClear(pDnode->data.localEp); - taosMemoryFreeClear(pDnode->data.localFqdn); - taosMemoryFreeClear(pDnode->data.firstEp); - taosMemoryFreeClear(pDnode->data.secondEp); - taosMemoryFreeClear(pDnode->data.dataDir); - taosThreadMutexDestroy(&pDnode->mutex); - memset(&pDnode->mutex, 0, sizeof(pDnode->mutex)); - taosMemoryFree(pDnode); - dDebug("dnode memory is cleared, data:%p", pDnode); -} - -SDnode *dmCreate(const SDnodeOpt *pOption) { - dDebug("start to create dnode"); - int32_t code = -1; - char path[PATH_MAX] = {0}; - SDnode *pDnode = NULL; - - pDnode = taosMemoryCalloc(1, sizeof(SDnode)); - if (pDnode == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - if (dmInitVars(pDnode, pOption) != 0) { - dError("failed to init variables since %s", terrstr()); - goto _OVER; - } - - dmSetStatus(pDnode, DND_STAT_INIT); - dmSetMgmtFp(&pDnode->wrappers[DNODE]); - mmSetMgmtFp(&pDnode->wrappers[MNODE]); - vmSetMgmtFp(&pDnode->wrappers[VNODE]); - qmSetMgmtFp(&pDnode->wrappers[QNODE]); - smSetMgmtFp(&pDnode->wrappers[SNODE]); - bmSetMgmtFp(&pDnode->wrappers[BNODE]); - - for (EDndNodeType n = DNODE; n < NODE_END; ++n) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[n]; - snprintf(path, sizeof(path), "%s%s%s", pDnode->data.dataDir, TD_DIRSEP, pWrapper->name); - pWrapper->path = strdup(path); - pWrapper->procShm.id = -1; - pWrapper->pDnode = pDnode; - pWrapper->ntype = n; - pWrapper->procType = DND_PROC_SINGLE; - taosInitRWLatch(&pWrapper->latch); - - if (pWrapper->path == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - if (n != DNODE && dmReadShmFile(pWrapper) != 0) { - dError("node:%s, failed to read shm file since %s", pWrapper->name, terrstr()); - goto _OVER; - } - } - - if (dmInitMsgHandle(pDnode) != 0) { - dError("failed to init msg handles since %s", terrstr()); - goto _OVER; - } - - dInfo("dnode is created, data:%p", pDnode); - code = 0; - -_OVER: - if (code != 0 && pDnode) { - dmClearVars(pDnode); - pDnode = NULL; - dError("failed to create dnode since %s", terrstr()); - } - - return pDnode; -} - -void dmClose(SDnode *pDnode) { - if (pDnode == NULL) return; - dmClearVars(pDnode); - dInfo("dnode is closed, data:%p", pDnode); -} diff --git a/source/dnode/mgmt/implement/src/dmWorker.c b/source/dnode/mgmt/implement/src/dmWorker.c deleted file mode 100644 index 72b2111591..0000000000 --- a/source/dnode/mgmt/implement/src/dmWorker.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "dmImp.h" - -static void *dmStatusThreadFp(void *param) { - SDnode *pDnode = param; - int64_t lastTime = taosGetTimestampMs(); - - setThreadName("dnode-status"); - - while (1) { - taosThreadTestCancel(); - taosMsleep(200); - - if (pDnode->status != DND_STAT_RUNNING || pDnode->data.dropped) { - continue; - } - - int64_t curTime = taosGetTimestampMs(); - float interval = (curTime - lastTime) / 1000.0f; - if (interval >= tsStatusInterval) { - dmSendStatusReq(pDnode); - lastTime = curTime; - } - } - - return NULL; -} - -static void *dmMonitorThreadFp(void *param) { - SDnode *pDnode = param; - int64_t lastTime = taosGetTimestampMs(); - - setThreadName("dnode-monitor"); - - while (1) { - taosThreadTestCancel(); - taosMsleep(200); - - if (pDnode->status != DND_STAT_RUNNING || pDnode->data.dropped) { - continue; - } - - int64_t curTime = taosGetTimestampMs(); - float interval = (curTime - lastTime) / 1000.0f; - if (interval >= tsMonitorInterval) { - dmSendMonitorReport(pDnode); - lastTime = curTime; - } - } - - return NULL; -} - -int32_t dmStartStatusThread(SDnode *pDnode) { - pDnode->data.statusThreadId = taosCreateThread(dmStatusThreadFp, pDnode); - if (pDnode->data.statusThreadId == NULL) { - dError("failed to init dnode status thread"); - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - dmReportStartup(pDnode, "dnode-status", "initialized"); - return 0; -} - -void dmStopStatusThread(SDnode *pDnode) { - if (pDnode->data.statusThreadId != NULL) { - taosDestoryThread(pDnode->data.statusThreadId); - pDnode->data.statusThreadId = NULL; - } -} - -int32_t dmStartMonitorThread(SDnode *pDnode) { - pDnode->data.monitorThreadId = taosCreateThread(dmMonitorThreadFp, pDnode); - if (pDnode->data.monitorThreadId == NULL) { - dError("failed to init dnode monitor thread"); - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - dmReportStartup(pDnode, "dnode-monitor", "initialized"); - return 0; -} - -void dmStopMonitorThread(SDnode *pDnode) { - if (pDnode->data.monitorThreadId != NULL) { - taosDestoryThread(pDnode->data.monitorThreadId); - pDnode->data.monitorThreadId = NULL; - } -} - -static void dmProcessMgmtQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { - SDnode *pDnode = pInfo->ahandle; - - int32_t code = -1; - tmsg_t msgType = pMsg->rpcMsg.msgType; - dTrace("msg:%p, will be processed in dnode-mgmt queue", pMsg); - - switch (msgType) { - case TDMT_DND_CONFIG_DNODE: - code = dmProcessConfigReq(pDnode, pMsg); - break; - case TDMT_MND_AUTH_RSP: - code = dmProcessAuthRsp(pDnode, pMsg); - break; - case TDMT_MND_GRANT_RSP: - code = dmProcessGrantRsp(pDnode, pMsg); - break; - case TDMT_DND_CREATE_MNODE: - code = dmProcessCreateNodeReq(pDnode, MNODE, pMsg); - break; - case TDMT_DND_DROP_MNODE: - code = dmProcessDropNodeReq(pDnode, MNODE, pMsg); - break; - case TDMT_DND_CREATE_QNODE: - code = dmProcessCreateNodeReq(pDnode, QNODE, pMsg); - break; - case TDMT_DND_DROP_QNODE: - code = dmProcessDropNodeReq(pDnode, QNODE, pMsg); - break; - case TDMT_DND_CREATE_SNODE: - code = dmProcessCreateNodeReq(pDnode, SNODE, pMsg); - break; - case TDMT_DND_DROP_SNODE: - code = dmProcessDropNodeReq(pDnode, SNODE, pMsg); - break; - case TDMT_DND_CREATE_BNODE: - code = dmProcessCreateNodeReq(pDnode, BNODE, pMsg); - break; - case TDMT_DND_DROP_BNODE: - code = dmProcessDropNodeReq(pDnode, BNODE, pMsg); - break; - default: - break; - } - - if (msgType & 1u) { - if (code != 0 && terrno != 0) code = terrno; - SRpcMsg rsp = { - .handle = pMsg->rpcMsg.handle, - .ahandle = pMsg->rpcMsg.ahandle, - .code = code, - .refId = pMsg->rpcMsg.refId, - }; - rpcSendResponse(&rsp); - } - - dTrace("msg:%p, is freed, result:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code)); - rpcFreeCont(pMsg->rpcMsg.pCont); - taosFreeQitem(pMsg); -} - -int32_t dmStartWorker(SDnode *pDnode) { - SSingleWorkerCfg cfg = { - .min = 1, - .max = 1, - .name = "dnode-mgmt", - .fp = (FItem)dmProcessMgmtQueue, - .param = pDnode, - }; - if (tSingleWorkerInit(&pDnode->data.mgmtWorker, &cfg) != 0) { - dError("failed to start dnode-mgmt worker since %s", terrstr()); - return -1; - } - - dDebug("dnode workers are initialized"); - return 0; -} - -void dmStopWorker(SDnode *pDnode) { - tSingleWorkerCleanup(&pDnode->data.mgmtWorker); - dDebug("dnode workers are closed"); -} - -int32_t dmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SSingleWorker *pWorker = &pWrapper->pDnode->data.mgmtWorker; - dTrace("msg:%p, put into worker %s", pMsg, pWorker->name); - taosWriteQitem(pWorker->queue, pMsg); - return 0; -} diff --git a/source/dnode/mgmt/interface/CMakeLists.txt b/source/dnode/mgmt/interface/CMakeLists.txt deleted file mode 100644 index a99fc2703d..0000000000 --- a/source/dnode/mgmt/interface/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -aux_source_directory(src DNODE_INTERFACE) -add_library(dnode_interface STATIC ${DNODE_INTERFACE}) -target_include_directories( - dnode_interface - PUBLIC "${TD_SOURCE_DIR}/include/dnode/mgmt" - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" -) -target_link_libraries( - dnode_interface cjson mnode vnode qnode snode bnode wal sync taos_static tfs monitor -) \ No newline at end of file diff --git a/source/dnode/mgmt/interface/inc/dmDef.h b/source/dnode/mgmt/interface/inc/dmDef.h deleted file mode 100644 index 445e1d42f5..0000000000 --- a/source/dnode/mgmt/interface/inc/dmDef.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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_DM_DEF_H_ -#define _TD_DM_DEF_H_ - -#include "uv.h" -#include "dmLog.h" - -#include "cJSON.h" -#include "tcache.h" -#include "tcrc32c.h" -#include "tdatablock.h" -#include "tglobal.h" -#include "thash.h" -#include "tlockfree.h" -#include "tlog.h" -#include "tmsg.h" -#include "tmsgcb.h" -#include "tprocess.h" -#include "tqueue.h" -#include "trpc.h" -#include "tthread.h" -#include "ttime.h" -#include "tworker.h" - -#include "dnode.h" -#include "mnode.h" -#include "monitor.h" -#include "sync.h" - -#include "libs/function/function.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { DNODE, VNODE, QNODE, SNODE, MNODE, BNODE, NODE_END } EDndNodeType; -typedef enum { DND_STAT_INIT, DND_STAT_RUNNING, DND_STAT_STOPPED } EDndRunStatus; -typedef enum { DND_ENV_INIT, DND_ENV_READY, DND_ENV_CLEANUP } EDndEnvStatus; -typedef enum { DND_PROC_SINGLE, DND_PROC_CHILD, DND_PROC_PARENT } EDndProcType; - -typedef int32_t (*NodeMsgFp)(struct SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -typedef int32_t (*OpenNodeFp)(struct SMgmtWrapper *pWrapper); -typedef void (*CloseNodeFp)(struct SMgmtWrapper *pWrapper); -typedef int32_t (*StartNodeFp)(struct SMgmtWrapper *pWrapper); -typedef void (*StopNodeFp)(struct SMgmtWrapper *pWrapper); -typedef int32_t (*CreateNodeFp)(struct SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -typedef int32_t (*DropNodeFp)(struct SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -typedef int32_t (*RequireNodeFp)(struct SMgmtWrapper *pWrapper, bool *required); - -typedef struct { - SMgmtWrapper *pQndWrapper; - SMgmtWrapper *pMndWrapper; - SMgmtWrapper *pNdWrapper; -} SMsgHandle; - -typedef struct { - OpenNodeFp openFp; - CloseNodeFp closeFp; - StartNodeFp startFp; - StopNodeFp stopFp; - CreateNodeFp createFp; - DropNodeFp dropFp; - RequireNodeFp requiredFp; -} SMgmtFp; - -typedef struct SMgmtWrapper { - SDnode *pDnode; - struct { - const char *name; - char *path; - int32_t refCount; - SRWLatch latch; - EDndNodeType ntype; - bool deployed; - bool required; - SMgmtFp fp; - void *pMgmt; - }; - struct { - EDndProcType procType; - int32_t procId; - SProcObj *procObj; - SShm procShm; - }; - struct { - int8_t msgVgIds[TDMT_MAX]; // Handle the case where the same message type is distributed to qnode or vnode - NodeMsgFp msgFps[TDMT_MAX]; - }; -} SMgmtWrapper; - -typedef struct { - void *serverRpc; - void *clientRpc; - SMsgHandle msgHandles[TDMT_MAX]; -} SDnodeTrans; - -typedef struct { - int32_t dnodeId; - int64_t clusterId; - int64_t dnodeVer; - int64_t updateTime; - int64_t rebootTime; - int32_t unsyncedVgId; - ESyncState vndState; - ESyncState mndState; - bool isMnode; - bool dropped; - SEpSet mnodeEps; - SArray *dnodeEps; - SHashObj *dnodeHash; - TdThread *statusThreadId; - TdThread *monitorThreadId; - SRWLatch latch; - SSingleWorker mgmtWorker; - SMsgCb msgCb; - SDnode *pDnode; - TdFilePtr lockfile; - char *localEp; - char *localFqdn; - char *firstEp; - char *secondEp; - char *dataDir; - SDiskCfg *disks; - int32_t numOfDisks; - int32_t supportVnodes; - uint16_t serverPort; -} SDnodeData; - -typedef struct { - char name[TSDB_STEP_NAME_LEN]; - char desc[TSDB_STEP_DESC_LEN]; -} SStartupInfo; - -typedef struct SUdfdData { - bool startCalled; - bool needCleanUp; - uv_loop_t loop; - uv_thread_t thread; - uv_barrier_t barrier; - uv_process_t process; - int spawnErr; - uv_pipe_t ctrlPipe; - uv_async_t stopAsync; - int32_t stopCalled; - - int32_t dnodeId; -} SUdfdData; - -typedef struct SDnode { - EDndProcType ptype; - EDndNodeType ntype; - EDndRunStatus status; - EDndEvent event; - SStartupInfo startup; - SDnodeTrans trans; - SDnodeData data; - SUdfdData udfdData; - TdThreadMutex mutex; - SMgmtWrapper wrappers[NODE_END]; -} SDnode; - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_DM_DEF_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/interface/inc/dmInt.h b/source/dnode/mgmt/interface/inc/dmInt.h deleted file mode 100644 index b56edd2630..0000000000 --- a/source/dnode/mgmt/interface/inc/dmInt.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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_DM_INT_H_ -#define _TD_DM_INT_H_ - -#include "dmDef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// dmInt.c -SMgmtWrapper *dmAcquireWrapper(SDnode *pDnode, EDndNodeType nType); -int32_t dmMarkWrapper(SMgmtWrapper *pWrapper); -void dmReleaseWrapper(SMgmtWrapper *pWrapper); -const char *dmStatName(EDndRunStatus stat); -const char *dmLogName(EDndNodeType ntype); -const char *dmProcName(EDndNodeType ntype); -const char *dmEventName(EDndEvent ev); - -void dmSetStatus(SDnode *pDnode, EDndRunStatus stat); -void dmSetEvent(SDnode *pDnode, EDndEvent event); -void dmSetMsgHandle(SMgmtWrapper *pWrapper, tmsg_t msgType, NodeMsgFp nodeMsgFp, int8_t vgId); -void dmReportStartup(SDnode *pDnode, const char *pName, const char *pDesc); -void dmReportStartupByWrapper(SMgmtWrapper *pWrapper, const char *pName, const char *pDesc); -void dmProcessServerStatusReq(SDnode *pDnode, SRpcMsg *pMsg); -void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pMsg); -void dmGetMonitorSysInfo(SMonSysInfo *pInfo); - -// dmFile.c -int32_t dmReadFile(SMgmtWrapper *pWrapper, bool *pDeployed); -int32_t dmWriteFile(SMgmtWrapper *pWrapper, bool deployed); -TdFilePtr dmCheckRunning(const char *dataDir); -int32_t dmReadShmFile(SMgmtWrapper *pWrapper); -int32_t dmWriteShmFile(SMgmtWrapper *pWrapper); - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_DM_INT_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/interface/inc/dmLog.h b/source/dnode/mgmt/interface/inc/dmLog.h deleted file mode 100644 index c21933fc01..0000000000 --- a/source/dnode/mgmt/interface/inc/dmLog.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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_DM_LOG_H_ -#define _TD_DM_LOG_H_ - -#include "tlog.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define dFatal(...) { if (dDebugFlag & DEBUG_FATAL) { taosPrintLog("DND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} -#define dError(...) { if (dDebugFlag & DEBUG_ERROR) { taosPrintLog("DND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} -#define dWarn(...) { if (dDebugFlag & DEBUG_WARN) { taosPrintLog("DND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} -#define dInfo(...) { if (dDebugFlag & DEBUG_INFO) { taosPrintLog("DND ", DEBUG_INFO, 255, __VA_ARGS__); }} -#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("DND ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} -#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("DND ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} - -#ifdef __cplusplus -} -#endif - -#endif /*_TD_DM_LOG_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/interface/src/dmInt.c b/source/dnode/mgmt/interface/src/dmInt.c deleted file mode 100644 index f8e23ad262..0000000000 --- a/source/dnode/mgmt/interface/src/dmInt.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "dmInt.h" - -const char *dmStatName(EDndRunStatus status) { - switch (status) { - case DND_STAT_INIT: - return "init"; - case DND_STAT_RUNNING: - return "running"; - case DND_STAT_STOPPED: - return "stopped"; - default: - return "UNKNOWN"; - } -} - -const char *dmLogName(EDndNodeType ntype) { - switch (ntype) { - case VNODE: - return "vnode"; - case QNODE: - return "qnode"; - case SNODE: - return "snode"; - case MNODE: - return "mnode"; - case BNODE: - return "bnode"; - default: - return "taosd"; - } -} - -const char *dmProcName(EDndNodeType ntype) { - switch (ntype) { - case VNODE: - return "taosv"; - case QNODE: - return "taosq"; - case SNODE: - return "taoss"; - case MNODE: - return "taosm"; - case BNODE: - return "taosb"; - default: - return "taosd"; - } -} - -const char *dmEventName(EDndEvent ev) { - switch (ev) { - case DND_EVENT_START: - return "start"; - case DND_EVENT_STOP: - return "stop"; - case DND_EVENT_CHILD: - return "child"; - default: - return "UNKNOWN"; - } -} - -void dmSetStatus(SDnode *pDnode, EDndRunStatus status) { - if (pDnode->status != status) { - dDebug("dnode status set from %s to %s", dmStatName(pDnode->status), dmStatName(status)); - pDnode->status = status; - } -} - -void dmSetEvent(SDnode *pDnode, EDndEvent event) { - if (event == DND_EVENT_STOP) { - pDnode->event = event; - } -} - -void dmSetMsgHandle(SMgmtWrapper *pWrapper, tmsg_t msgType, NodeMsgFp nodeMsgFp, int8_t vgId) { - pWrapper->msgFps[TMSG_INDEX(msgType)] = nodeMsgFp; - pWrapper->msgVgIds[TMSG_INDEX(msgType)] = vgId; -} - -SMgmtWrapper *dmAcquireWrapper(SDnode *pDnode, EDndNodeType ntype) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; - SMgmtWrapper *pRetWrapper = pWrapper; - - taosRLockLatch(&pWrapper->latch); - if (pWrapper->deployed) { - int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1); - dTrace("node:%s, is acquired, refCount:%d", pWrapper->name, refCount); - } else { - terrno = TSDB_CODE_NODE_NOT_DEPLOYED; - pRetWrapper = NULL; - } - taosRUnLockLatch(&pWrapper->latch); - - return pRetWrapper; -} - -int32_t dmMarkWrapper(SMgmtWrapper *pWrapper) { - int32_t code = 0; - - taosRLockLatch(&pWrapper->latch); - if (pWrapper->deployed || (pWrapper->procType == DND_PROC_PARENT && pWrapper->required)) { - int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1); - dTrace("node:%s, is marked, refCount:%d", pWrapper->name, refCount); - } else { - terrno = TSDB_CODE_NODE_NOT_DEPLOYED; - code = -1; - } - taosRUnLockLatch(&pWrapper->latch); - - return code; -} - -void dmReleaseWrapper(SMgmtWrapper *pWrapper) { - if (pWrapper == NULL) return; - - taosRLockLatch(&pWrapper->latch); - int32_t refCount = atomic_sub_fetch_32(&pWrapper->refCount, 1); - taosRUnLockLatch(&pWrapper->latch); - dTrace("node:%s, is released, refCount:%d", pWrapper->name, refCount); -} - -void dmReportStartup(SDnode *pDnode, const char *pName, const char *pDesc) { - SStartupInfo *pStartup = &pDnode->startup; - tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN); - tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN); - dInfo("step:%s, %s", pStartup->name, pStartup->desc); -} - -void dmReportStartupByWrapper(SMgmtWrapper *pWrapper, const char *pName, const char *pDesc) { - dmReportStartup(pWrapper->pDnode, pName, pDesc); -} - -static void dmGetServerStatus(SDnode *pDnode, SServerStatusRsp *pStatus) { - pStatus->details[0] = 0; - - if (pDnode->status == DND_STAT_INIT) { - pStatus->statusCode = TSDB_SRV_STATUS_NETWORK_OK; - snprintf(pStatus->details, sizeof(pStatus->details), "%s: %s", pDnode->startup.name, pDnode->startup.desc); - } else if (pDnode->status == DND_STAT_STOPPED) { - pStatus->statusCode = TSDB_SRV_STATUS_EXTING; - } else { - SDnodeData *pData = &pDnode->data; - if (pData->isMnode && pData->mndState != TAOS_SYNC_STATE_LEADER && pData->mndState == TAOS_SYNC_STATE_FOLLOWER) { - pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_DEGRADED; - snprintf(pStatus->details, sizeof(pStatus->details), "mnode sync state is %s", syncStr(pData->mndState)); - } else if (pData->unsyncedVgId != 0 && pData->vndState != TAOS_SYNC_STATE_LEADER && - pData->vndState != TAOS_SYNC_STATE_FOLLOWER) { - pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_DEGRADED; - snprintf(pStatus->details, sizeof(pStatus->details), "vnode:%d sync state is %s", pData->unsyncedVgId, - syncStr(pData->vndState)); - } else { - pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_OK; - } - } -} - -void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pReq) { - dDebug("net test req is received"); - SRpcMsg rsp = {.handle = pReq->handle, .refId = pReq->refId, .ahandle = pReq->ahandle, .code = 0}; - rsp.pCont = rpcMallocCont(pReq->contLen); - if (rsp.pCont == NULL) { - rsp.code = TSDB_CODE_OUT_OF_MEMORY; - } else { - rsp.contLen = pReq->contLen; - } - rpcSendResponse(&rsp); - rpcFreeCont(pReq->pCont); -} - -void dmProcessServerStatusReq(SDnode *pDnode, SRpcMsg *pReq) { - dDebug("server status req is received"); - - SServerStatusRsp statusRsp = {0}; - dmGetServerStatus(pDnode, &statusRsp); - - SRpcMsg rspMsg = {.handle = pReq->handle, .ahandle = pReq->ahandle, .refId = pReq->refId}; - int32_t rspLen = tSerializeSServerStatusRsp(NULL, 0, &statusRsp); - if (rspLen < 0) { - rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - void *pRsp = rpcMallocCont(rspLen); - if (pRsp == NULL) { - rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; - goto _OVER; - } - - tSerializeSServerStatusRsp(pRsp, rspLen, &statusRsp); - rspMsg.pCont = pRsp; - rspMsg.contLen = rspLen; - -_OVER: - rpcSendResponse(&rspMsg); - rpcFreeCont(pReq->pCont); -} - -void dmGetMonitorSysInfo(SMonSysInfo *pInfo) { - taosGetCpuUsage(&pInfo->cpu_engine, &pInfo->cpu_system); - taosGetCpuCores(&pInfo->cpu_cores); - taosGetProcMemory(&pInfo->mem_engine); - taosGetSysMemory(&pInfo->mem_system); - pInfo->mem_total = tsTotalMemoryKB; - pInfo->disk_engine = 0; - pInfo->disk_used = tsDataSpace.size.used; - pInfo->disk_total = tsDataSpace.size.total; - taosGetCardInfoDelta(&pInfo->net_in, &pInfo->net_out); - taosGetProcIODelta(&pInfo->io_read, &pInfo->io_write, &pInfo->io_read_disk, &pInfo->io_write_disk); -} diff --git a/source/dnode/mgmt/mgmt_bnode/CMakeLists.txt b/source/dnode/mgmt/mgmt_bnode/CMakeLists.txt index 6a447dccf8..0a6cf52fb8 100644 --- a/source/dnode/mgmt/mgmt_bnode/CMakeLists.txt +++ b/source/dnode/mgmt/mgmt_bnode/CMakeLists.txt @@ -5,5 +5,5 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mgmt_bnode dnode_interface + mgmt_bnode node_util ) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_bnode/inc/bmInt.h b/source/dnode/mgmt/mgmt_bnode/inc/bmInt.h index 3adcc1206b..1923d049a5 100644 --- a/source/dnode/mgmt/mgmt_bnode/inc/bmInt.h +++ b/source/dnode/mgmt/mgmt_bnode/inc/bmInt.h @@ -16,7 +16,7 @@ #ifndef _TD_DND_BNODE_INT_H_ #define _TD_DND_BNODE_INT_H_ -#include "dmInt.h" +#include "dmUtil.h" #include "bnode.h" @@ -26,24 +26,25 @@ extern "C" { typedef struct SBnodeMgmt { SBnode *pBnode; - SDnode *pDnode; - SMgmtWrapper *pWrapper; + SMsgCb msgCb; const char *path; + const char *name; + int32_t dnodeId; SMultiWorker writeWorker; SSingleWorker monitorWorker; } SBnodeMgmt; // bmHandle.c -void bmInitMsgHandle(SMgmtWrapper *pWrapper); -int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t bmProcessGetMonBmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); +SArray *bmGetMsgHandles(); +int32_t bmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg); +int32_t bmProcessDropReq(SBnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t bmProcessGetMonBmInfoReq(SBnodeMgmt *pMgmt, SNodeMsg *pReq); // bmWorker.c int32_t bmStartWorker(SBnodeMgmt *pMgmt); void bmStopWorker(SBnodeMgmt *pMgmt); -int32_t bmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t bmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); +int32_t bmPutNodeMsgToWriteQueue(SBnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t bmPutNodeMsgToMonitorQueue(SBnodeMgmt *pMgmt, SNodeMsg *pMsg); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/mgmt_bnode/src/bmHandle.c b/source/dnode/mgmt/mgmt_bnode/src/bmHandle.c index 3b314b1d2b..d87f832262 100644 --- a/source/dnode/mgmt/mgmt_bnode/src/bmHandle.c +++ b/source/dnode/mgmt/mgmt_bnode/src/bmHandle.c @@ -16,12 +16,12 @@ #define _DEFAULT_SOURCE #include "bmInt.h" -void bmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonBmInfo *bmInfo) {} +static void bmGetMonitorInfo(SBnodeMgmt *pMgmt, SMonBmInfo *bmInfo) {} -int32_t bmProcessGetMonBmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t bmProcessGetMonBmInfoReq(SBnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonBmInfo bmInfo = {0}; - bmGetMonitorInfo(pWrapper, &bmInfo); - dmGetMonitorSysInfo(&bmInfo.sys); + bmGetMonitorInfo(pMgmt, &bmInfo); + dmGetMonitorSystemInfo(&bmInfo.sys); monGetLogs(&bmInfo.log); int32_t rspLen = tSerializeSMonBmInfo(NULL, 0, &bmInfo); @@ -43,8 +43,7 @@ int32_t bmProcessGetMonBmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t bmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDCreateBnodeReq createReq = {0}; @@ -53,14 +52,14 @@ int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (pDnode->data.dnodeId != 0 && createReq.dnodeId != pDnode->data.dnodeId) { + if (pInput->dnodeId != 0 && createReq.dnodeId != pInput->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; - dError("failed to create bnode since %s, input:%d cur:%d", terrstr(), createReq.dnodeId, pDnode->data.dnodeId); + dError("failed to create bnode since %s, input:%d cur:%d", terrstr(), createReq.dnodeId, pInput->dnodeId); return -1; } bool deployed = true; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pInput->path, pInput->name, deployed) != 0) { dError("failed to write bnode file since %s", terrstr()); return -1; } @@ -68,8 +67,7 @@ int32_t bmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t bmProcessDropReq(SBnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDDropBnodeReq dropReq = {0}; @@ -78,14 +76,14 @@ int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (dropReq.dnodeId != pDnode->data.dnodeId) { + if (pMgmt->dnodeId != 0 && dropReq.dnodeId != pMgmt->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to drop bnode since %s", terrstr()); return -1; } bool deployed = false; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pMgmt->path, pMgmt->name, deployed) != 0) { dError("failed to write bnode file since %s", terrstr()); return -1; } @@ -93,6 +91,19 @@ int32_t bmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -void bmInitMsgHandle(SMgmtWrapper *pWrapper) { - dmSetMsgHandle(pWrapper, TDMT_MON_BM_INFO, bmProcessMonitorMsg, DEFAULT_HANDLE); +SArray *bmGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(2, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + if (dmSetMgmtHandle(pArray, TDMT_MON_BM_INFO, bmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; + + code = 0; +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } } diff --git a/source/dnode/mgmt/mgmt_bnode/src/bmInt.c b/source/dnode/mgmt/mgmt_bnode/src/bmInt.c index 2920d12eb4..45e0c32193 100644 --- a/source/dnode/mgmt/mgmt_bnode/src/bmInt.c +++ b/source/dnode/mgmt/mgmt_bnode/src/bmInt.c @@ -16,18 +16,13 @@ #define _DEFAULT_SOURCE #include "bmInt.h" -static int32_t bmRequire(SMgmtWrapper *pWrapper, bool *required) { return dmReadFile(pWrapper, required); } - -static void bmInitOption(SBnodeMgmt *pMgmt, SBnodeOpt *pOption) { - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - pOption->msgCb = msgCb; +static int32_t bmRequire(const SMgmtInputOpt *pInput, bool *required) { + return dmReadFile(pInput->path, pInput->name, required); } -static void bmClose(SMgmtWrapper *pWrapper) { - SBnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt == NULL) return; +static void bmInitOption(SBnodeMgmt *pMgmt, SBnodeOpt *pOption) { pOption->msgCb = pMgmt->msgCb; } +static void bmClose(SBnodeMgmt *pMgmt) { dInfo("bnode-mgmt start to cleanup"); if (pMgmt->pBnode != NULL) { bmStopWorker(pMgmt); @@ -35,12 +30,11 @@ static void bmClose(SMgmtWrapper *pWrapper) { pMgmt->pBnode = NULL; } - pWrapper->pMgmt = NULL; taosMemoryFree(pMgmt); dInfo("bnode-mgmt is cleaned up"); } -int32_t bmOpen(SMgmtWrapper *pWrapper) { +int32_t bmOpen(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { dInfo("bnode-mgmt start to init"); SBnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SBnodeMgmt)); if (pMgmt == NULL) { @@ -48,40 +42,42 @@ int32_t bmOpen(SMgmtWrapper *pWrapper) { return -1; } - pMgmt->path = pWrapper->path; - pMgmt->pDnode = pWrapper->pDnode; - pMgmt->pWrapper = pWrapper; - pWrapper->pMgmt = pMgmt; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->dnodeId = pInput->dnodeId; + pMgmt->msgCb = pInput->msgCb; + pMgmt->msgCb.pMgmt = pMgmt; SBnodeOpt option = {0}; bmInitOption(pMgmt, &option); pMgmt->pBnode = bndOpen(pMgmt->path, &option); if (pMgmt->pBnode == NULL) { dError("failed to open bnode since %s", terrstr()); - bmClose(pWrapper); + bmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "bnode-impl", "initialized"); + tmsgReportStartup("bnode-impl", "initialized"); if (bmStartWorker(pMgmt) != 0) { dError("failed to start bnode worker since %s", terrstr()); - bmClose(pWrapper); + bmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "bnode-worker", "initialized"); + tmsgReportStartup("bnode-worker", "initialized"); + pOutput->pMgmt = pMgmt; + dInfo("bnode-mgmt is initialized"); return 0; } -void bmSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = bmOpen; - mgmtFp.closeFp = bmClose; - mgmtFp.createFp = bmProcessCreateReq; - mgmtFp.dropFp = bmProcessDropReq; - mgmtFp.requiredFp = bmRequire; +SMgmtFunc bmGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = bmOpen; + mgmtFunc.closeFp = (NodeCloseFp)bmClose; + mgmtFunc.createFp = (NodeCreateFp)bmProcessCreateReq; + mgmtFunc.dropFp = (NodeDropFp)bmProcessDropReq; + mgmtFunc.requiredFp = bmRequire; + mgmtFunc.getHandlesFp = bmGetMsgHandles; - bmInitMsgHandle(pWrapper); - pWrapper->name = "bnode"; - pWrapper->fp = mgmtFp; + return mgmtFunc; } diff --git a/source/dnode/mgmt/mgmt_bnode/src/bmWorker.c b/source/dnode/mgmt/mgmt_bnode/src/bmWorker.c index d3204039e6..1ab8b5ef34 100644 --- a/source/dnode/mgmt/mgmt_bnode/src/bmWorker.c +++ b/source/dnode/mgmt/mgmt_bnode/src/bmWorker.c @@ -58,7 +58,7 @@ static void bmProcessMonitorQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { int32_t code = -1; if (pMsg->rpcMsg.msgType == TDMT_MON_BM_INFO) { - code = bmProcessGetMonBmInfoReq(pMgmt->pWrapper, pMsg); + code = bmProcessGetMonBmInfoReq(pMgmt, pMsg); } else { terrno = TSDB_CODE_MSG_NOT_PROCESSED; } @@ -106,8 +106,7 @@ static void bmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO taosArrayDestroy(pArray); } -int32_t bmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SBnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t bmPutNodeMsgToWriteQueue(SBnodeMgmt *pMgmt, SNodeMsg *pMsg) { SMultiWorker *pWorker = &pMgmt->writeWorker; dTrace("msg:%p, put into worker:%s", pMsg, pWorker->name); @@ -115,8 +114,7 @@ int32_t bmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t bmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SBnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t bmPutNodeMsgToMonitorQueue(SBnodeMgmt *pMgmt, SNodeMsg *pMsg) { SSingleWorker *pWorker = &pMgmt->monitorWorker; dTrace("msg:%p, put into worker:%s", pMsg, pWorker->name); @@ -136,18 +134,16 @@ int32_t bmStartWorker(SBnodeMgmt *pMgmt) { return -1; } - if (tsMultiProcess) { - SSingleWorkerCfg mCfg = { - .min = 1, - .max = 1, - .name = "bnode-monitor", - .fp = (FItem)bmProcessMonitorQueue, - .param = pMgmt, - }; - if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { - dError("failed to start bnode-monitor worker since %s", terrstr()); - return -1; - } + SSingleWorkerCfg mCfg = { + .min = 1, + .max = 1, + .name = "bnode-monitor", + .fp = (FItem)bmProcessMonitorQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { + dError("failed to start bnode-monitor worker since %s", terrstr()); + return -1; } dDebug("bnode workers are initialized"); diff --git a/source/dnode/mgmt/mgmt_dnode/CMakeLists.txt b/source/dnode/mgmt/mgmt_dnode/CMakeLists.txt new file mode 100644 index 0000000000..a4268fc9f0 --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/CMakeLists.txt @@ -0,0 +1,9 @@ +aux_source_directory(src MGMT_DNODE) +add_library(mgmt_dnode STATIC ${MGMT_DNODE}) +target_include_directories( + mgmt_dnode + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) +target_link_libraries( + mgmt_dnode node_util +) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h new file mode 100644 index 0000000000..5ef2706f1e --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/inc/dmInt.h @@ -0,0 +1,70 @@ +/* + * 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_DND_QNODE_INT_H_ +#define _TD_DND_QNODE_INT_H_ + +#include "dmUtil.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDnodeMgmt { + struct SDnode *pDnode; + SMsgCb msgCb; + const char *path; + const char *name; + TdThread statusThread; + TdThread monitorThread; + SSingleWorker mgmtWorker; + ProcessCreateNodeFp processCreateNodeFp; + ProcessDropNodeFp processDropNodeFp; + IsNodeDeployedFp isNodeDeployedFp; + SDnodeData data; +} SDnodeMgmt; + +// dmEps.c +int32_t dmReadEps(SDnodeMgmt *pMgmt); +int32_t dmWriteEps(SDnodeMgmt *pMgmt); +void dmUpdateEps(SDnodeMgmt *pMgmt, SArray *pDnodeEps); + +// dmHandle.c +SArray *dmGetMsgHandles(); +void dmSendStatusReq(SDnodeMgmt *pMgmt); +int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t dmProcessGrantRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t dmProcessServerRunStatus(SDnodeMgmt *pMgmt, SNodeMsg *pMsg); + +// dmMonitor.c +void dmGetVnodeLoads(SDnodeMgmt *pMgmt, SMonVloadInfo *pInfo); +void dmGetMnodeLoads(SDnodeMgmt *pMgmt, SMonMloadInfo *pInfo); +void dmSendMonitorReport(SDnodeMgmt *pMgmt); + +// dmWorker.c +int32_t dmPutNodeMsgToMgmtQueue(SDnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t dmStartStatusThread(SDnodeMgmt *pMgmt); +void dmStopStatusThread(SDnodeMgmt *pMgmt); +int32_t dmStartMonitorThread(SDnodeMgmt *pMgmt); +void dmStopMonitorThread(SDnodeMgmt *pMgmt); +int32_t dmStartWorker(SDnodeMgmt *pMgmt); +void dmStopWorker(SDnodeMgmt *pMgmt); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_DND_QNODE_INT_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/implement/src/dmEps.c b/source/dnode/mgmt/mgmt_dnode/src/dmEps.c similarity index 69% rename from source/dnode/mgmt/implement/src/dmEps.c rename to source/dnode/mgmt/mgmt_dnode/src/dmEps.c index f5c9a1d91b..9ebb02b964 100644 --- a/source/dnode/mgmt/implement/src/dmEps.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmEps.c @@ -14,16 +14,16 @@ */ #define _DEFAULT_SOURCE -#include "dmImp.h" +#include "dmInt.h" -static void dmPrintEps(SDnode *pDnode); -static bool dmIsEpChanged(SDnode *pDnode, int32_t dnodeId, const char *ep); -static void dmResetEps(SDnode *pDnode, SArray *dnodeEps); +static void dmPrintEps(SDnodeMgmt *pMgmt); +static bool dmIsEpChanged(SDnodeMgmt *pMgmt, int32_t dnodeId, const char *ep); +static void dmResetEps(SDnodeMgmt *pMgmt, SArray *dnodeEps); -static void dmGetDnodeEp(SDnode *pDnode, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort) { - taosRLockLatch(&pDnode->data.latch); +static void dmGetDnodeEp(SDnodeMgmt *pMgmt, int32_t dnodeId, char *pEp, char *pFqdn, uint16_t *pPort) { + taosRLockLatch(&pMgmt->data.latch); - SDnodeEp *pDnodeEp = taosHashGet(pDnode->data.dnodeHash, &dnodeId, sizeof(int32_t)); + SDnodeEp *pDnodeEp = taosHashGet(pMgmt->data.dnodeHash, &dnodeId, sizeof(int32_t)); if (pDnodeEp != NULL) { if (pPort != NULL) { *pPort = pDnodeEp->ep.port; @@ -36,10 +36,10 @@ static void dmGetDnodeEp(SDnode *pDnode, int32_t dnodeId, char *pEp, char *pFqdn } } - taosRUnLockLatch(&pDnode->data.latch); + taosRUnLockLatch(&pMgmt->data.latch); } -int32_t dmReadEps(SDnode *pDnode) { +int32_t dmReadEps(SDnodeMgmt *pMgmt) { int32_t code = TSDB_CODE_INVALID_JSON_FORMAT; int32_t len = 0; int32_t maxLen = 256 * 1024; @@ -48,16 +48,15 @@ int32_t dmReadEps(SDnode *pDnode) { char file[PATH_MAX] = {0}; TdFilePtr pFile = NULL; - pDnode->data.dnodeEps = taosArrayInit(1, sizeof(SDnodeEp)); - if (pDnode->data.dnodeEps == NULL) { + pMgmt->data.dnodeEps = taosArrayInit(1, sizeof(SDnodeEp)); + if (pMgmt->data.dnodeEps == NULL) { dError("failed to calloc dnodeEp array since %s", strerror(errno)); goto _OVER; } - snprintf(file, sizeof(file), "%s%sdnode.json", pDnode->wrappers[DNODE].path, TD_DIRSEP); + snprintf(file, sizeof(file), "%s%sdnode.json", pMgmt->path, TD_DIRSEP); pFile = taosOpenFile(file, TD_FILE_READ); if (pFile == NULL) { - // dDebug("file %s not exist", file); code = 0; goto _OVER; } @@ -80,21 +79,21 @@ int32_t dmReadEps(SDnode *pDnode) { dError("failed to read %s since dnodeId not found", file); goto _OVER; } - pDnode->data.dnodeId = dnodeId->valueint; + pMgmt->data.dnodeId = dnodeId->valueint; cJSON *clusterId = cJSON_GetObjectItem(root, "clusterId"); if (!clusterId || clusterId->type != cJSON_String) { dError("failed to read %s since clusterId not found", file); goto _OVER; } - pDnode->data.clusterId = atoll(clusterId->valuestring); + pMgmt->data.clusterId = atoll(clusterId->valuestring); cJSON *dropped = cJSON_GetObjectItem(root, "dropped"); if (!dropped || dropped->type != cJSON_Number) { dError("failed to read %s since dropped not found", file); goto _OVER; } - pDnode->data.dropped = dropped->valueint; + pMgmt->data.dropped = dropped->valueint; cJSON *dnodes = cJSON_GetObjectItem(root, "dnodes"); if (!dnodes || dnodes->type != cJSON_Array) { @@ -144,29 +143,29 @@ int32_t dmReadEps(SDnode *pDnode) { } dnodeEp.isMnode = isMnode->valueint; - taosArrayPush(pDnode->data.dnodeEps, &dnodeEp); + taosArrayPush(pMgmt->data.dnodeEps, &dnodeEp); } code = 0; dDebug("succcessed to read file %s", file); - dmPrintEps(pDnode); + dmPrintEps(pMgmt); _OVER: if (content != NULL) taosMemoryFree(content); if (root != NULL) cJSON_Delete(root); if (pFile != NULL) taosCloseFile(&pFile); - if (taosArrayGetSize(pDnode->data.dnodeEps) == 0) { + if (taosArrayGetSize(pMgmt->data.dnodeEps) == 0) { SDnodeEp dnodeEp = {0}; dnodeEp.isMnode = 1; - taosGetFqdnPortFromEp(pDnode->data.firstEp, &dnodeEp.ep); - taosArrayPush(pDnode->data.dnodeEps, &dnodeEp); + taosGetFqdnPortFromEp(pMgmt->data.firstEp, &dnodeEp.ep); + taosArrayPush(pMgmt->data.dnodeEps, &dnodeEp); } - dmResetEps(pDnode, pDnode->data.dnodeEps); + dmResetEps(pMgmt, pMgmt->data.dnodeEps); - if (dmIsEpChanged(pDnode, pDnode->data.dnodeId, pDnode->data.localEp)) { - dError("localEp %s different with %s and need reconfigured", pDnode->data.localEp, file); + if (dmIsEpChanged(pMgmt, pMgmt->data.dnodeId, pMgmt->data.localEp)) { + dError("localEp %s different with %s and need reconfigured", pMgmt->data.localEp, file); return -1; } @@ -174,11 +173,11 @@ _OVER: return code; } -int32_t dmWriteEps(SDnode *pDnode) { +int32_t dmWriteEps(SDnodeMgmt *pMgmt) { char file[PATH_MAX] = {0}; char realfile[PATH_MAX] = {0}; - snprintf(file, sizeof(file), "%s%sdnode.json.bak", pDnode->wrappers[DNODE].path, TD_DIRSEP); - snprintf(realfile, sizeof(realfile), "%s%sdnode.json", pDnode->wrappers[DNODE].path, TD_DIRSEP); + snprintf(file, sizeof(file), "%s%sdnode.json.bak", pMgmt->path, TD_DIRSEP); + snprintf(realfile, sizeof(realfile), "%s%sdnode.json", pMgmt->path, TD_DIRSEP); TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC); if (pFile == NULL) { @@ -192,14 +191,14 @@ int32_t dmWriteEps(SDnode *pDnode) { char *content = taosMemoryCalloc(1, maxLen + 1); len += snprintf(content + len, maxLen - len, "{\n"); - len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", pDnode->data.dnodeId); - len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%" PRId64 "\",\n", pDnode->data.clusterId); - len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pDnode->data.dropped); + len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", pMgmt->data.dnodeId); + len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%" PRId64 "\",\n", pMgmt->data.clusterId); + len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pMgmt->data.dropped); len += snprintf(content + len, maxLen - len, " \"dnodes\": [{\n"); - int32_t numOfEps = (int32_t)taosArrayGetSize(pDnode->data.dnodeEps); + int32_t numOfEps = (int32_t)taosArrayGetSize(pMgmt->data.dnodeEps); for (int32_t i = 0; i < numOfEps; ++i) { - SDnodeEp *pDnodeEp = taosArrayGet(pDnode->data.dnodeEps, i); + SDnodeEp *pDnodeEp = taosArrayGet(pMgmt->data.dnodeEps, i); len += snprintf(content + len, maxLen - len, " \"id\": %d,\n", pDnodeEp->id); len += snprintf(content + len, maxLen - len, " \"fqdn\": \"%s\",\n", pDnodeEp->ep.fqdn); len += snprintf(content + len, maxLen - len, " \"port\": %u,\n", pDnodeEp->ep.port); @@ -223,41 +222,41 @@ int32_t dmWriteEps(SDnode *pDnode) { return -1; } - pDnode->data.updateTime = taosGetTimestampMs(); + pMgmt->data.updateTime = taosGetTimestampMs(); dDebug("successed to write %s", realfile); return 0; } -void dmUpdateEps(SDnode *pDnode, SArray *eps) { +void dmUpdateEps(SDnodeMgmt *pMgmt, SArray *eps) { int32_t numOfEps = taosArrayGetSize(eps); if (numOfEps <= 0) return; - taosWLockLatch(&pDnode->data.latch); + taosWLockLatch(&pMgmt->data.latch); - int32_t numOfEpsOld = (int32_t)taosArrayGetSize(pDnode->data.dnodeEps); + int32_t numOfEpsOld = (int32_t)taosArrayGetSize(pMgmt->data.dnodeEps); if (numOfEps != numOfEpsOld) { - dmResetEps(pDnode, eps); - dmWriteEps(pDnode); + dmResetEps(pMgmt, eps); + dmWriteEps(pMgmt); } else { int32_t size = numOfEps * sizeof(SDnodeEp); - if (memcmp(pDnode->data.dnodeEps->pData, eps->pData, size) != 0) { - dmResetEps(pDnode, eps); - dmWriteEps(pDnode); + if (memcmp(pMgmt->data.dnodeEps->pData, eps->pData, size) != 0) { + dmResetEps(pMgmt, eps); + dmWriteEps(pMgmt); } } - taosWUnLockLatch(&pDnode->data.latch); + taosWUnLockLatch(&pMgmt->data.latch); } -static void dmResetEps(SDnode *pDnode, SArray *dnodeEps) { - if (pDnode->data.dnodeEps != dnodeEps) { - SArray *tmp = pDnode->data.dnodeEps; - pDnode->data.dnodeEps = taosArrayDup(dnodeEps); +static void dmResetEps(SDnodeMgmt *pMgmt, SArray *dnodeEps) { + if (pMgmt->data.dnodeEps != dnodeEps) { + SArray *tmp = pMgmt->data.dnodeEps; + pMgmt->data.dnodeEps = taosArrayDup(dnodeEps); taosArrayDestroy(tmp); } - pDnode->data.mnodeEps.inUse = 0; - pDnode->data.mnodeEps.numOfEps = 0; + pMgmt->data.mnodeEps.inUse = 0; + pMgmt->data.mnodeEps.numOfEps = 0; int32_t mIndex = 0; int32_t numOfEps = (int32_t)taosArrayGetSize(dnodeEps); @@ -266,35 +265,35 @@ static void dmResetEps(SDnode *pDnode, SArray *dnodeEps) { SDnodeEp *pDnodeEp = taosArrayGet(dnodeEps, i); if (!pDnodeEp->isMnode) continue; if (mIndex >= TSDB_MAX_REPLICA) continue; - pDnode->data.mnodeEps.numOfEps++; + pMgmt->data.mnodeEps.numOfEps++; - pDnode->data.mnodeEps.eps[mIndex] = pDnodeEp->ep; + pMgmt->data.mnodeEps.eps[mIndex] = pDnodeEp->ep; mIndex++; } for (int32_t i = 0; i < numOfEps; i++) { SDnodeEp *pDnodeEp = taosArrayGet(dnodeEps, i); - taosHashPut(pDnode->data.dnodeHash, &pDnodeEp->id, sizeof(int32_t), pDnodeEp, sizeof(SDnodeEp)); + taosHashPut(pMgmt->data.dnodeHash, &pDnodeEp->id, sizeof(int32_t), pDnodeEp, sizeof(SDnodeEp)); } - dmPrintEps(pDnode); + dmPrintEps(pMgmt); } -static void dmPrintEps(SDnode *pDnode) { - int32_t numOfEps = (int32_t)taosArrayGetSize(pDnode->data.dnodeEps); +static void dmPrintEps(SDnodeMgmt *pMgmt) { + int32_t numOfEps = (int32_t)taosArrayGetSize(pMgmt->data.dnodeEps); dDebug("print dnode ep list, num:%d", numOfEps); for (int32_t i = 0; i < numOfEps; i++) { - SDnodeEp *pEp = taosArrayGet(pDnode->data.dnodeEps, i); + SDnodeEp *pEp = taosArrayGet(pMgmt->data.dnodeEps, i); dDebug("dnode:%d, fqdn:%s port:%u isMnode:%d", pEp->id, pEp->ep.fqdn, pEp->ep.port, pEp->isMnode); } } -static bool dmIsEpChanged(SDnode *pDnode, int32_t dnodeId, const char *ep) { +static bool dmIsEpChanged(SDnodeMgmt *pMgmt, int32_t dnodeId, const char *ep) { bool changed = false; if (dnodeId == 0) return changed; - taosRLockLatch(&pDnode->data.latch); + taosRLockLatch(&pMgmt->data.latch); - SDnodeEp *pDnodeEp = taosHashGet(pDnode->data.dnodeHash, &dnodeId, sizeof(int32_t)); + SDnodeEp *pDnodeEp = taosHashGet(pMgmt->data.dnodeHash, &dnodeId, sizeof(int32_t)); if (pDnodeEp != NULL) { char epstr[TSDB_EP_LEN + 1] = {0}; snprintf(epstr, TSDB_EP_LEN, "%s:%u", pDnodeEp->ep.fqdn, pDnodeEp->ep.port); @@ -304,6 +303,6 @@ static bool dmIsEpChanged(SDnode *pDnode, int32_t dnodeId, const char *ep) { } } - taosRUnLockLatch(&pDnode->data.latch); + taosRUnLockLatch(&pMgmt->data.latch); return changed; } diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c new file mode 100644 index 0000000000..38f97d3600 --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c @@ -0,0 +1,206 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmInt.h" + +static void dmUpdateDnodeCfg(SDnodeMgmt *pMgmt, SDnodeCfg *pCfg) { + if (pMgmt->data.dnodeId == 0 || pMgmt->data.clusterId == 0) { + dInfo("set dnodeId:%d clusterId:%" PRId64, pCfg->dnodeId, pCfg->clusterId); + taosWLockLatch(&pMgmt->data.latch); + pMgmt->data.dnodeId = pCfg->dnodeId; + pMgmt->data.clusterId = pCfg->clusterId; + dmWriteEps(pMgmt); + taosWUnLockLatch(&pMgmt->data.latch); + } +} + +static void dmProcessStatusRsp(SDnodeMgmt *pMgmt, SRpcMsg *pRsp) { + if (pRsp->code != 0) { + if (pRsp->code == TSDB_CODE_MND_DNODE_NOT_EXIST && !pMgmt->data.dropped && pMgmt->data.dnodeId > 0) { + dInfo("dnode:%d, set to dropped since not exist in mnode", pMgmt->data.dnodeId); + pMgmt->data.dropped = 1; + dmWriteEps(pMgmt); + } + } else { + SStatusRsp statusRsp = {0}; + if (pRsp->pCont != NULL && pRsp->contLen > 0 && + tDeserializeSStatusRsp(pRsp->pCont, pRsp->contLen, &statusRsp) == 0) { + pMgmt->data.dnodeVer = statusRsp.dnodeVer; + dmUpdateDnodeCfg(pMgmt, &statusRsp.dnodeCfg); + dmUpdateEps(pMgmt, statusRsp.pDnodeEps); + } + rpcFreeCont(pRsp->pCont); + tFreeSStatusRsp(&statusRsp); + } +} + +void dmSendStatusReq(SDnodeMgmt *pMgmt) { + SStatusReq req = {0}; + + taosRLockLatch(&pMgmt->data.latch); + req.sver = tsVersion; + req.dnodeVer = pMgmt->data.dnodeVer; + req.dnodeId = pMgmt->data.dnodeId; + req.clusterId = pMgmt->data.clusterId; + if (req.clusterId == 0) req.dnodeId = 0; + req.rebootTime = pMgmt->data.rebootTime; + req.updateTime = pMgmt->data.updateTime; + req.numOfCores = tsNumOfCores; + req.numOfSupportVnodes = pMgmt->data.supportVnodes; + tstrncpy(req.dnodeEp, pMgmt->data.localEp, TSDB_EP_LEN); + + req.clusterCfg.statusInterval = tsStatusInterval; + req.clusterCfg.checkTime = 0; + char timestr[32] = "1970-01-01 00:00:00.00"; + (void)taosParseTime(timestr, &req.clusterCfg.checkTime, (int32_t)strlen(timestr), TSDB_TIME_PRECISION_MILLI, 0); + memcpy(req.clusterCfg.timezone, tsTimezoneStr, TD_TIMEZONE_LEN); + memcpy(req.clusterCfg.locale, tsLocale, TD_LOCALE_LEN); + memcpy(req.clusterCfg.charset, tsCharset, TD_LOCALE_LEN); + taosRUnLockLatch(&pMgmt->data.latch); + + SMonVloadInfo vinfo = {0}; + dmGetVnodeLoads(pMgmt, &vinfo); + req.pVloads = vinfo.pVloads; + pMgmt->data.unsyncedVgId = 0; + pMgmt->data.vndState = TAOS_SYNC_STATE_LEADER; + for (int32_t i = 0; i < taosArrayGetSize(req.pVloads); ++i) { + SVnodeLoad *pLoad = taosArrayGet(req.pVloads, i); + if (pLoad->syncState != TAOS_SYNC_STATE_LEADER && pLoad->syncState != TAOS_SYNC_STATE_FOLLOWER) { + pMgmt->data.unsyncedVgId = pLoad->vgId; + pMgmt->data.vndState = pLoad->syncState; + } + } + + SMonMloadInfo minfo = {0}; + dmGetMnodeLoads(pMgmt, &minfo); + pMgmt->data.mndState = minfo.load.syncState; + + int32_t contLen = tSerializeSStatusReq(NULL, 0, &req); + void *pHead = rpcMallocCont(contLen); + tSerializeSStatusReq(pHead, contLen, &req); + tFreeSStatusReq(&req); + + SRpcMsg rpcMsg = {.pCont = pHead, .contLen = contLen, .msgType = TDMT_MND_STATUS, .ahandle = (void *)0x9527}; + SRpcMsg rpcRsp = {0}; + + dTrace("send req:%s to mnode, app:%p", TMSG_INFO(rpcMsg.msgType), rpcMsg.ahandle); + tmsgSendMnodeRecv(&rpcMsg, &rpcRsp); + dmProcessStatusRsp(pMgmt, &rpcRsp); +} + +int32_t dmProcessAuthRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) { + SRpcMsg *pRsp = &pMsg->rpcMsg; + dError("auth rsp is received, but not supported yet"); + return 0; +} + +int32_t dmProcessGrantRsp(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) { + SRpcMsg *pRsp = &pMsg->rpcMsg; + dError("grant rsp is received, but not supported yet"); + return 0; +} + +int32_t dmProcessConfigReq(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) { + SRpcMsg *pReq = &pMsg->rpcMsg; + SDCfgDnodeReq *pCfg = pReq->pCont; + dError("config req is received, but not supported yet"); + return TSDB_CODE_OPS_NOT_SUPPORT; +} + +static void dmGetServerRunStatus(SDnodeMgmt *pMgmt, SServerStatusRsp *pStatus) { + pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_OK; + pStatus->details[0] = 0; + + SServerStatusRsp statusRsp = {0}; + SMonMloadInfo minfo = {0}; + dmGetMnodeLoads(pMgmt, &minfo); + if (minfo.isMnode && minfo.load.syncState != TAOS_SYNC_STATE_LEADER && + minfo.load.syncState != TAOS_SYNC_STATE_CANDIDATE) { + pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_DEGRADED; + snprintf(pStatus->details, sizeof(pStatus->details), "mnode sync state is %s", syncStr(minfo.load.syncState)); + return; + } + + SMonVloadInfo vinfo = {0}; + dmGetVnodeLoads(pMgmt, &vinfo); + for (int32_t i = 0; i < taosArrayGetSize(vinfo.pVloads); ++i) { + SVnodeLoad *pLoad = taosArrayGet(vinfo.pVloads, i); + if (pLoad->syncState != TAOS_SYNC_STATE_LEADER && pLoad->syncState != TAOS_SYNC_STATE_FOLLOWER) { + pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_DEGRADED; + snprintf(pStatus->details, sizeof(pStatus->details), "vnode:%d sync state is %s", pLoad->vgId, + syncStr(pLoad->syncState)); + break; + } + } + + taosArrayDestroy(vinfo.pVloads); +} + +int32_t dmProcessServerRunStatus(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) { + dDebug("server run status req is received"); + SServerStatusRsp statusRsp = {0}; + dmGetServerRunStatus(pMgmt, &statusRsp); + + SRpcMsg rspMsg = {.handle = pMsg->rpcMsg.handle, .ahandle = pMsg->rpcMsg.ahandle, .refId = pMsg->rpcMsg.refId}; + int32_t rspLen = tSerializeSServerStatusRsp(NULL, 0, &statusRsp); + if (rspLen < 0) { + rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + void *pRsp = rpcMallocCont(rspLen); + if (pRsp == NULL) { + rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + tSerializeSServerStatusRsp(pRsp, rspLen, &statusRsp); + pMsg->pRsp = pRsp; + pMsg->rspLen = rspLen; + return 0; +} + +SArray *dmGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(16, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + // Requests handled by DNODE + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_MNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_MNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_QNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_QNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_SNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_SNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_BNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_BNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_SERVER_STATUS, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + + // Requests handled by MNODE + if (dmSetMgmtHandle(pArray, TDMT_MND_GRANT_RSP, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_AUTH_RSP, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + + code = 0; + +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } +} diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmInt.c b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c new file mode 100644 index 0000000000..9e40b3d022 --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/src/dmInt.c @@ -0,0 +1,129 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmInt.h" + +static int32_t dmStartMgmt(SDnodeMgmt *pMgmt) { + if (dmStartStatusThread(pMgmt) != 0) { + return -1; + } + if (dmStartMonitorThread(pMgmt) != 0) { + return -1; + } + return 0; +} + +static void dmStopMgmt(SDnodeMgmt *pMgmt) { + pMgmt->data.stopped = true; + dmStopMonitorThread(pMgmt); + dmStopStatusThread(pMgmt); +} + +static int32_t dmOpenMgmt(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { + dInfo("dnode-mgmt start to init"); + SDnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SDnodeMgmt)); + if (pMgmt == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + pMgmt->data.dnodeId = 0; + pMgmt->data.clusterId = 0; + pMgmt->data.dnodeVer = 0; + pMgmt->data.updateTime = 0; + pMgmt->data.rebootTime = taosGetTimestampMs(); + pMgmt->data.dropped = 0; + pMgmt->data.localEp = pInput->localEp; + pMgmt->data.localFqdn = pInput->localFqdn; + pMgmt->data.firstEp = pInput->firstEp; + pMgmt->data.secondEp = pInput->secondEp; + pMgmt->data.supportVnodes = pInput->supportVnodes; + pMgmt->data.serverPort = pInput->serverPort; + pMgmt->pDnode = pInput->pDnode; + pMgmt->msgCb = pInput->msgCb; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->processCreateNodeFp = pInput->processCreateNodeFp; + pMgmt->processDropNodeFp = pInput->processDropNodeFp; + pMgmt->isNodeDeployedFp = pInput->isNodeDeployedFp; + taosInitRWLatch(&pMgmt->data.latch); + + pMgmt->data.dnodeHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); + if (pMgmt->data.dnodeHash == NULL) { + dError("failed to init dnode hash"); + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + if (dmReadEps(pMgmt) != 0) { + dError("failed to read file since %s", terrstr()); + return -1; + } + + if (pMgmt->data.dropped) { + dError("dnode will not start since its already dropped"); + return -1; + } + + if (dmStartWorker(pMgmt) != 0) { + return -1; + } + + if (udfStartUdfd(pMgmt->data.dnodeId) != 0) { + dError("failed to start udfd"); + } + + pOutput->pMgmt = pMgmt; + pOutput->mnodeEps = pMgmt->data.mnodeEps; + dInfo("dnode-mgmt is initialized"); + return 0; +} + +static void dmCloseMgmt(SDnodeMgmt *pMgmt) { + dInfo("dnode-mgmt start to clean up"); + dmStopWorker(pMgmt); + + taosWLockLatch(&pMgmt->data.latch); + if (pMgmt->data.dnodeEps != NULL) { + taosArrayDestroy(pMgmt->data.dnodeEps); + pMgmt->data.dnodeEps = NULL; + } + if (pMgmt->data.dnodeHash != NULL) { + taosHashCleanup(pMgmt->data.dnodeHash); + pMgmt->data.dnodeHash = NULL; + } + taosWUnLockLatch(&pMgmt->data.latch); + taosMemoryFree(pMgmt); + + dInfo("dnode-mgmt is cleaned up"); +} + +static int32_t dmRequireMgmt(const SMgmtInputOpt *pInput, bool *required) { + *required = true; + return 0; +} + +SMgmtFunc dmGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = dmOpenMgmt; + mgmtFunc.closeFp = (NodeCloseFp)dmCloseMgmt; + mgmtFunc.startFp = (NodeStartFp)dmStartMgmt; + mgmtFunc.stopFp = (NodeStopFp)dmStopMgmt; + mgmtFunc.requiredFp = dmRequireMgmt; + mgmtFunc.getHandlesFp = dmGetMsgHandles; + + return mgmtFunc; +} diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmMonitor.c b/source/dnode/mgmt/mgmt_dnode/src/dmMonitor.c new file mode 100644 index 0000000000..d2f16c3ad0 --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/src/dmMonitor.c @@ -0,0 +1,105 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmInt.h" + +#define dmSendLocalRecv(pMgmt, mtype, func, pInfo) \ + if (!tsMultiProcess) { \ + SRpcMsg rsp = {0}; \ + SRpcMsg req = {.msgType = mtype}; \ + SEpSet epset = {.inUse = 0, .numOfEps = 1}; \ + tstrncpy(epset.eps[0].fqdn, pMgmt->data.localFqdn, TSDB_FQDN_LEN); \ + epset.eps[0].port = pMgmt->data.serverPort; \ + \ + rpcSendRecv(pMgmt->msgCb.clientRpc, &epset, &req, &rsp); \ + if (rsp.code == 0 && rsp.contLen > 0) { \ + func(rsp.pCont, rsp.contLen, pInfo); \ + } \ + rpcFreeCont(rsp.pCont); \ + } + +static void dmGetMonitorBasicInfo(SDnodeMgmt *pMgmt, SMonBasicInfo *pInfo) { + pInfo->protocol = 1; + pInfo->dnode_id = pMgmt->data.dnodeId; + pInfo->cluster_id = pMgmt->data.clusterId; + tstrncpy(pInfo->dnode_ep, tsLocalEp, TSDB_EP_LEN); +} + +static void dmGetMonitorDnodeInfo(SDnodeMgmt *pMgmt, SMonDnodeInfo *pInfo) { + pInfo->uptime = (taosGetTimestampMs() - pMgmt->data.rebootTime) / (86400000.0f); + pInfo->has_mnode = (*pMgmt->isNodeDeployedFp)(pMgmt->pDnode, MNODE); + pInfo->has_qnode = (*pMgmt->isNodeDeployedFp)(pMgmt->pDnode, QNODE); + pInfo->has_snode = (*pMgmt->isNodeDeployedFp)(pMgmt->pDnode, SNODE); + pInfo->has_bnode = (*pMgmt->isNodeDeployedFp)(pMgmt->pDnode, BNODE); + tstrncpy(pInfo->logdir.name, tsLogDir, sizeof(pInfo->logdir.name)); + pInfo->logdir.size = tsLogSpace.size; + tstrncpy(pInfo->tempdir.name, tsTempDir, sizeof(pInfo->tempdir.name)); + pInfo->tempdir.size = tsTempSpace.size; +} + +static void dmGetMonitorInfo(SDnodeMgmt *pMgmt, SMonDmInfo *pInfo) { + dmGetMonitorBasicInfo(pMgmt, &pInfo->basic); + dmGetMonitorDnodeInfo(pMgmt, &pInfo->dnode); + dmGetMonitorSystemInfo(&pInfo->sys); +} + +void dmSendMonitorReport(SDnodeMgmt *pMgmt) { + if (!tsEnableMonitor || tsMonitorFqdn[0] == 0 || tsMonitorPort == 0) return; + dTrace("send monitor report to %s:%u", tsMonitorFqdn, tsMonitorPort); + + SMonDmInfo dmInfo = {0}; + SMonMmInfo mmInfo = {0}; + SMonVmInfo vmInfo = {0}; + SMonQmInfo qmInfo = {0}; + SMonSmInfo smInfo = {0}; + SMonBmInfo bmInfo = {0}; + + dmGetMonitorInfo(pMgmt, &dmInfo); + dmSendLocalRecv(pMgmt, TDMT_MON_VM_INFO, tDeserializeSMonVmInfo, &vmInfo); + if (dmInfo.dnode.has_mnode) { + dmSendLocalRecv(pMgmt, TDMT_MON_MM_INFO, tDeserializeSMonMmInfo, &mmInfo); + } + if (dmInfo.dnode.has_qnode) { + dmSendLocalRecv(pMgmt, TDMT_MON_QM_INFO, tDeserializeSMonQmInfo, &qmInfo); + } + if (dmInfo.dnode.has_snode) { + dmSendLocalRecv(pMgmt, TDMT_MON_SM_INFO, tDeserializeSMonSmInfo, &smInfo); + } + if (dmInfo.dnode.has_bnode) { + dmSendLocalRecv(pMgmt, TDMT_MON_BM_INFO, tDeserializeSMonBmInfo, &bmInfo); + } + + monSetDmInfo(&dmInfo); + monSetMmInfo(&mmInfo); + monSetVmInfo(&vmInfo); + monSetQmInfo(&qmInfo); + monSetSmInfo(&smInfo); + monSetBmInfo(&bmInfo); + tFreeSMonMmInfo(&mmInfo); + tFreeSMonVmInfo(&vmInfo); + tFreeSMonQmInfo(&qmInfo); + tFreeSMonSmInfo(&smInfo); + tFreeSMonBmInfo(&bmInfo); + monSendReport(); +} + +void dmGetVnodeLoads(SDnodeMgmt *pMgmt, SMonVloadInfo *pInfo) { + dmSendLocalRecv(pMgmt, TDMT_MON_VM_LOAD, tDeserializeSMonVloadInfo, pInfo); +} + +void dmGetMnodeLoads(SDnodeMgmt *pMgmt, SMonMloadInfo *pInfo) { + dmSendLocalRecv(pMgmt, TDMT_MON_MM_LOAD, tDeserializeSMonMloadInfo, pInfo); +} diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c new file mode 100644 index 0000000000..af02e56f05 --- /dev/null +++ b/source/dnode/mgmt/mgmt_dnode/src/dmWorker.c @@ -0,0 +1,195 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmInt.h" + +static void *dmStatusThreadFp(void *param) { + SDnodeMgmt *pMgmt = param; + int64_t lastTime = taosGetTimestampMs(); + + setThreadName("dnode-status"); + + while (1) { + taosMsleep(200); + if (pMgmt->data.dropped || pMgmt->data.stopped) break; + + int64_t curTime = taosGetTimestampMs(); + float interval = (curTime - lastTime) / 1000.0f; + if (interval >= tsStatusInterval) { + dmSendStatusReq(pMgmt); + lastTime = curTime; + } + } + + return NULL; +} + +static void *dmMonitorThreadFp(void *param) { + SDnodeMgmt *pMgmt = param; + int64_t lastTime = taosGetTimestampMs(); + + setThreadName("dnode-monitor"); + + while (1) { + taosMsleep(200); + if (pMgmt->data.dropped || pMgmt->data.stopped) break; + + int64_t curTime = taosGetTimestampMs(); + float interval = (curTime - lastTime) / 1000.0f; + if (interval >= tsMonitorInterval) { + dmSendMonitorReport(pMgmt); + lastTime = curTime; + } + } + + return NULL; +} + +int32_t dmStartStatusThread(SDnodeMgmt *pMgmt) { + TdThreadAttr thAttr; + taosThreadAttrInit(&thAttr); + taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_JOINABLE); + if (taosThreadCreate(&pMgmt->statusThread, &thAttr, dmStatusThreadFp, pMgmt) != 0) { + dError("failed to create status thread since %s", strerror(errno)); + return -1; + } + + taosThreadAttrDestroy(&thAttr); + tmsgReportStartup("dnode-status", "initialized"); + return 0; +} + +void dmStopStatusThread(SDnodeMgmt *pMgmt) { + if (taosCheckPthreadValid(pMgmt->statusThread)) { + taosThreadJoin(pMgmt->statusThread, NULL); + } +} + +int32_t dmStartMonitorThread(SDnodeMgmt *pMgmt) { + TdThreadAttr thAttr; + taosThreadAttrInit(&thAttr); + taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_JOINABLE); + if (taosThreadCreate(&pMgmt->monitorThread, &thAttr, dmMonitorThreadFp, pMgmt) != 0) { + dError("failed to create monitor thread since %s", strerror(errno)); + return -1; + } + + taosThreadAttrDestroy(&thAttr); + tmsgReportStartup("dnode-monitor", "initialized"); + return 0; +} + +void dmStopMonitorThread(SDnodeMgmt *pMgmt) { + if (taosCheckPthreadValid(pMgmt->monitorThread)) { + taosThreadJoin(pMgmt->monitorThread, NULL); + } +} + +static void dmProcessMgmtQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { + SDnodeMgmt *pMgmt = pInfo->ahandle; + int32_t code = -1; + tmsg_t msgType = pMsg->rpcMsg.msgType; + bool isRequest = msgType & 1u; + dTrace("msg:%p, will be processed in dnode-mgmt queue, type:%s", pMsg, TMSG_INFO(msgType)); + + switch (msgType) { + case TDMT_DND_CONFIG_DNODE: + code = dmProcessConfigReq(pMgmt, pMsg); + break; + case TDMT_MND_AUTH_RSP: + code = dmProcessAuthRsp(pMgmt, pMsg); + break; + case TDMT_MND_GRANT_RSP: + code = dmProcessGrantRsp(pMgmt, pMsg); + break; + case TDMT_DND_CREATE_MNODE: + code = (*pMgmt->processCreateNodeFp)(pMgmt->pDnode, MNODE, pMsg); + break; + case TDMT_DND_DROP_MNODE: + code = (*pMgmt->processDropNodeFp)(pMgmt->pDnode, MNODE, pMsg); + break; + case TDMT_DND_CREATE_QNODE: + code = (*pMgmt->processCreateNodeFp)(pMgmt->pDnode, QNODE, pMsg); + break; + case TDMT_DND_DROP_QNODE: + code = (*pMgmt->processDropNodeFp)(pMgmt->pDnode, QNODE, pMsg); + break; + case TDMT_DND_CREATE_SNODE: + code = (*pMgmt->processCreateNodeFp)(pMgmt->pDnode, SNODE, pMsg); + break; + case TDMT_DND_DROP_SNODE: + code = (*pMgmt->processDropNodeFp)(pMgmt->pDnode, SNODE, pMsg); + break; + case TDMT_DND_CREATE_BNODE: + code = (*pMgmt->processCreateNodeFp)(pMgmt->pDnode, BNODE, pMsg); + break; + case TDMT_DND_DROP_BNODE: + code = (*pMgmt->processDropNodeFp)(pMgmt->pDnode, BNODE, pMsg); + break; + case TDMT_DND_SERVER_STATUS: + code = dmProcessServerRunStatus(pMgmt, pMsg); + break; + default: + terrno = TSDB_CODE_MSG_NOT_PROCESSED; + break; + } + + if (isRequest) { + if (code != 0 && terrno != 0) code = terrno; + SRpcMsg rsp = { + .handle = pMsg->rpcMsg.handle, + .ahandle = pMsg->rpcMsg.ahandle, + .code = code, + .refId = pMsg->rpcMsg.refId, + .pCont = pMsg->pRsp, + .contLen = pMsg->rspLen, + }; + rpcSendResponse(&rsp); + } + + dTrace("msg:%p, is freed, result:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code)); + rpcFreeCont(pMsg->rpcMsg.pCont); + taosFreeQitem(pMsg); +} + +int32_t dmStartWorker(SDnodeMgmt *pMgmt) { + SSingleWorkerCfg cfg = { + .min = 1, + .max = 1, + .name = "dnode-mgmt", + .fp = (FItem)dmProcessMgmtQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->mgmtWorker, &cfg) != 0) { + dError("failed to start dnode-mgmt worker since %s", terrstr()); + return -1; + } + + dDebug("dnode workers are initialized"); + return 0; +} + +void dmStopWorker(SDnodeMgmt *pMgmt) { + tSingleWorkerCleanup(&pMgmt->mgmtWorker); + dDebug("dnode workers are closed"); +} + +int32_t dmPutNodeMsgToMgmtQueue(SDnodeMgmt *pMgmt, SNodeMsg *pMsg) { + SSingleWorker *pWorker = &pMgmt->mgmtWorker; + dTrace("msg:%p, put into worker %s", pMsg, pWorker->name); + taosWriteQitem(pWorker->queue, pMsg); + return 0; +} diff --git a/source/dnode/mgmt/mgmt_mnode/CMakeLists.txt b/source/dnode/mgmt/mgmt_mnode/CMakeLists.txt index 5ca9af5628..04118590a2 100644 --- a/source/dnode/mgmt/mgmt_mnode/CMakeLists.txt +++ b/source/dnode/mgmt/mgmt_mnode/CMakeLists.txt @@ -5,5 +5,5 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mgmt_mnode dnode_interface + mgmt_mnode node_util ) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_mnode/inc/mmInt.h b/source/dnode/mgmt/mgmt_mnode/inc/mmInt.h index 4d40d1fa28..87dbe702be 100644 --- a/source/dnode/mgmt/mgmt_mnode/inc/mmInt.h +++ b/source/dnode/mgmt/mgmt_mnode/inc/mmInt.h @@ -16,8 +16,7 @@ #ifndef _TD_DND_MNODE_INT_H_ #define _TD_DND_MNODE_INT_H_ -#include "dmInt.h" - +#include "dmUtil.h" #include "mnode.h" #ifdef __cplusplus @@ -26,9 +25,10 @@ extern "C" { typedef struct SMnodeMgmt { SMnode *pMnode; - SDnode *pDnode; - SMgmtWrapper *pWrapper; + SMsgCb msgCb; const char *path; + const char *name; + int32_t dnodeId; SSingleWorker queryWorker; SSingleWorker readWorker; SSingleWorker writeWorker; @@ -41,33 +41,31 @@ typedef struct SMnodeMgmt { // mmFile.c int32_t mmReadFile(SMnodeMgmt *pMgmt, bool *pDeployed); -int32_t mmWriteFile(SMgmtWrapper *pWrapper, SDCreateMnodeReq *pReq, bool deployed); +int32_t mmWriteFile(SMnodeMgmt *pMgmt, SDCreateMnodeReq *pReq, bool deployed); // mmInt.c int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pReq); // mmHandle.c -void mmInitMsgHandle(SMgmtWrapper *pWrapper); -int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); +SArray *mmGetMsgHandles(); +int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg); +int32_t mmProcessDropReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); -int32_t mmProcessGetMonMmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); -int32_t mmProcessGetMnodeLoadsReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); -void mmGetMnodeLoads(SMgmtWrapper *pWrapper, SMonMloadInfo *pInfo); +int32_t mmProcessGetMonitorInfoReq(SMnodeMgmt *pMgmt, SNodeMsg *pReq); +int32_t mmProcessGetLoadsReq(SMnodeMgmt *pMgmt, SNodeMsg *pReq); // mmWorker.c int32_t mmStartWorker(SMnodeMgmt *pMgmt); void mmStopWorker(SMnodeMgmt *pMgmt); -int32_t mmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t mmProcessSyncMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t mmProcessReadMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t mmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t mmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); - -int32_t mmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc); -int32_t mmPutMsgToReadQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc); -int32_t mmPutMsgToWriteQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc); -int32_t mmPutMsgToSyncQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc); +int32_t mmPutNodeMsgToWriteQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t mmPutNodeMsgToSyncQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t mmPutNodeMsgToReadQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t mmPutNodeMsgToQueryQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t mmPutNodeMsgToMonitorQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t mmPutRpcMsgToQueryQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc); +int32_t mmPutRpcMsgToReadQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc); +int32_t mmPutRpcMsgToWriteQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc); +int32_t mmPutRpcMsgToSyncQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c index 83c832a41e..df377fefe7 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmFile.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmFile.c @@ -28,7 +28,6 @@ int32_t mmReadFile(SMnodeMgmt *pMgmt, bool *pDeployed) { snprintf(file, sizeof(file), "%s%smnode.json", pMgmt->path, TD_DIRSEP); pFile = taosOpenFile(file, TD_FILE_READ); if (pFile == NULL) { - // dDebug("file %s not exist", file); code = 0; goto _OVER; } @@ -105,11 +104,11 @@ _OVER: return code; } -int32_t mmWriteFile(SMgmtWrapper *pWrapper, SDCreateMnodeReq *pReq, bool deployed) { +int32_t mmWriteFile(SMnodeMgmt *pMgmt, SDCreateMnodeReq *pReq, bool deployed) { char file[PATH_MAX] = {0}; char realfile[PATH_MAX] = {0}; - snprintf(file, sizeof(file), "%s%smnode.json.bak", pWrapper->path, TD_DIRSEP); - snprintf(realfile, sizeof(realfile), "%s%smnode.json", pWrapper->path, TD_DIRSEP); + snprintf(file, sizeof(file), "%s%smnode.json.bak", pMgmt->path, TD_DIRSEP); + snprintf(realfile, sizeof(realfile), "%s%smnode.json", pMgmt->path, TD_DIRSEP); TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC); if (pFile == NULL) { @@ -125,22 +124,19 @@ int32_t mmWriteFile(SMgmtWrapper *pWrapper, SDCreateMnodeReq *pReq, bool deploye len += snprintf(content + len, maxLen - len, "{\n"); len += snprintf(content + len, maxLen - len, " \"mnodes\": [{\n"); - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pReq != NULL || pMgmt != NULL) { - int8_t replica = (pReq != NULL ? pReq->replica : pMgmt->replica); - for (int32_t i = 0; i < replica; ++i) { - SReplica *pReplica = &pMgmt->replicas[i]; - if (pReq != NULL) { - pReplica = &pReq->replicas[i]; - } - len += snprintf(content + len, maxLen - len, " \"id\": %d,\n", pReplica->id); - len += snprintf(content + len, maxLen - len, " \"fqdn\": \"%s\",\n", pReplica->fqdn); - len += snprintf(content + len, maxLen - len, " \"port\": %u\n", pReplica->port); - if (i < replica - 1) { - len += snprintf(content + len, maxLen - len, " },{\n"); - } else { - len += snprintf(content + len, maxLen - len, " }],\n"); - } + int8_t replica = (pReq != NULL ? pReq->replica : pMgmt->replica); + for (int32_t i = 0; i < replica; ++i) { + SReplica *pReplica = &pMgmt->replicas[i]; + if (pReq != NULL) { + pReplica = &pReq->replicas[i]; + } + len += snprintf(content + len, maxLen - len, " \"id\": %d,\n", pReplica->id); + len += snprintf(content + len, maxLen - len, " \"fqdn\": \"%s\",\n", pReplica->fqdn); + len += snprintf(content + len, maxLen - len, " \"port\": %u\n", pReplica->port); + if (i < replica - 1) { + len += snprintf(content + len, maxLen - len, " },{\n"); + } else { + len += snprintf(content + len, maxLen - len, " }],\n"); } } diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c index ed9384a869..5548a23c55 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmHandle.c @@ -16,15 +16,14 @@ #define _DEFAULT_SOURCE #include "mmInt.h" -void mmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonMmInfo *mmInfo) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; +static void mmGetMonitorInfo(SMnodeMgmt *pMgmt, SMonMmInfo *mmInfo) { mndGetMonitorInfo(pMgmt->pMnode, &mmInfo->cluster, &mmInfo->vgroup, &mmInfo->grant); } -int32_t mmProcessGetMonMmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t mmProcessGetMonitorInfoReq(SMnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonMmInfo mmInfo = {0}; - mmGetMonitorInfo(pWrapper, &mmInfo); - dmGetMonitorSysInfo(&mmInfo.sys); + mmGetMonitorInfo(pMgmt, &mmInfo); + dmGetMonitorSystemInfo(&mmInfo.sys); monGetLogs(&mmInfo.log); int32_t rspLen = tSerializeSMonMmInfo(NULL, 0, &mmInfo); @@ -46,15 +45,14 @@ int32_t mmProcessGetMonMmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -void mmGetMnodeLoads(SMgmtWrapper *pWrapper, SMonMloadInfo *pInfo) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; +static void mmGetMnodeLoads(SMnodeMgmt *pMgmt, SMonMloadInfo *pInfo) { pInfo->isMnode = 1; mndGetLoad(pMgmt->pMnode, &pInfo->load); } -int32_t mmProcessGetMnodeLoadsReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t mmProcessGetLoadsReq(SMnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonMloadInfo mloads = {0}; - mmGetMnodeLoads(pWrapper, &mloads); + mmGetMnodeLoads(pMgmt, &mloads); int32_t rspLen = tSerializeSMonMloadInfo(NULL, 0, &mloads); if (rspLen < 0) { @@ -74,8 +72,7 @@ int32_t mmProcessGetMnodeLoadsReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t mmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDCreateMnodeReq createReq = {0}; @@ -84,14 +81,18 @@ int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (createReq.replica <= 1 || createReq.dnodeId != pDnode->data.dnodeId) { + if (createReq.replica <= 1 || (createReq.dnodeId != pInput->dnodeId && pInput->dnodeId != 0)) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to create mnode since %s", terrstr()); return -1; } bool deployed = true; - if (mmWriteFile(pWrapper, &createReq, deployed) != 0) { + + SMnodeMgmt mgmt = {0}; + mgmt.path = pInput->path; + mgmt.name = pInput->name; + if (mmWriteFile(&mgmt, &createReq, deployed) != 0) { dError("failed to write mnode file since %s", terrstr()); return -1; } @@ -99,8 +100,7 @@ int32_t mmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t mmProcessDropReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDDropMnodeReq dropReq = {0}; @@ -109,14 +109,14 @@ int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (dropReq.dnodeId != pDnode->data.dnodeId) { + if (pMgmt->dnodeId != 0 && dropReq.dnodeId != pMgmt->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to drop mnode since %s", terrstr()); return -1; } bool deployed = false; - if (mmWriteFile(pWrapper, NULL, deployed) != 0) { + if (mmWriteFile(pMgmt, NULL, deployed) != 0) { dError("failed to write mnode file since %s", terrstr()); return -1; } @@ -125,7 +125,6 @@ int32_t mmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { } int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { - SDnode *pDnode = pMgmt->pDnode; SRpcMsg *pReq = &pMsg->rpcMsg; SDAlterMnodeReq alterReq = {0}; @@ -134,104 +133,118 @@ int32_t mmProcessAlterReq(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { return -1; } - if (pDnode->data.dnodeId != 0 && alterReq.dnodeId != pDnode->data.dnodeId) { + if (pMgmt->dnodeId != 0 && alterReq.dnodeId != pMgmt->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; - dError("failed to alter mnode since %s, input:%d cur:%d", terrstr(), alterReq.dnodeId, pDnode->data.dnodeId); + dError("failed to alter mnode since %s, input:%d cur:%d", terrstr(), alterReq.dnodeId, pMgmt->dnodeId); return -1; } else { return mmAlter(pMgmt, &alterReq); } } -void mmInitMsgHandle(SMgmtWrapper *pWrapper) { - dmSetMsgHandle(pWrapper, TDMT_MON_MM_INFO, mmProcessMonitorMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MON_MM_LOAD, mmProcessMonitorMsg, DEFAULT_HANDLE); +SArray *mmGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(64, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + if (dmSetMgmtHandle(pArray, TDMT_MON_MM_INFO, mmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MON_MM_LOAD, mmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; // Requests handled by DNODE - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_MNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_QNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_QNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_SNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_SNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_BNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_BNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CONFIG_DNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_MNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_MNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_QNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_QNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_SNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_SNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_BNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_BNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; // Requests handled by MNODE - dmSetMsgHandle(pWrapper, TDMT_MND_CONNECT, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_ALTER_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_ACCT, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_USER, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_ALTER_USER, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_USER, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_GET_USER_AUTH, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CONFIG_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_DNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_QNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_QNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_QNODE_LIST, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_SNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_SNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_BNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_BNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_DB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_DB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_USE_DB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_ALTER_DB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_COMPACT_DB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_RETRIEVE_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_FUNC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_STB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_ALTER_STB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_STB, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_SMA, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_SMA, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_TABLE_META, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_VGROUP_LIST, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_KILL_QUERY, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_KILL_CONN, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_HEARTBEAT, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_SYSTABLE_RETRIEVE, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_STATUS, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_KILL_TRANS, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_GRANT, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_AUTH, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_ALTER_MNODE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_ALTER_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_DROP_TOPIC, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_SUBSCRIBE, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_MQ_COMMIT_OFFSET, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_MQ_ASK_EP, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_VG_CHANGE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_CREATE_STREAM, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_GET_DB_CFG, mmProcessReadMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MND_GET_INDEX, mmProcessReadMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_MND_CONNECT, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ACCT, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_ACCT, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_ACCT, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_USER, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_USER, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_USER, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_GET_USER_AUTH, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CONFIG_DNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_MNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_MNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_QNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_QNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_QNODE_LIST, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_SNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_SNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_BNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_BNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_DB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_DB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_USE_DB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_DB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_COMPACT_DB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_FUNC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_FUNC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_FUNC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_STB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_STB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_STB, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_SMA, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_SMA, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_TABLE_META, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_VGROUP_LIST, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_QUERY, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_CONN, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_HEARTBEAT, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_SYSTABLE_RETRIEVE, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_STATUS, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_KILL_TRANS, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_GRANT, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_AUTH, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_TOPIC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_TOPIC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_DROP_TOPIC, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_SUBSCRIBE, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_COMMIT_OFFSET, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_MQ_ASK_EP, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_VG_CHANGE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_STREAM, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_DEPLOY_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_GET_DB_CFG, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MND_GET_INDEX, mmPutNodeMsgToReadQueue, 0) == NULL) goto _OVER; // Requests handled by VNODE - dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_STB_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_STB_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_STB_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_STB_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_SMA_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_SMA_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY, mmProcessQueryMsg, MNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, mmProcessQueryMsg, MNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_FETCH, mmProcessQueryMsg, MNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, mmProcessQueryMsg, MNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, mmProcessQueryMsg, MNODE_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_CONTINUE, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_HEARTBEAT, mmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; - dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_COMPACT_VNODE_RSP, mmProcessWriteMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_VNODE_RSP, mmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + + code = 0; + +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } } diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmInt.c b/source/dnode/mgmt/mgmt_mnode/src/mmInt.c index 0bf846b7fc..8815af2f22 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmInt.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmInt.c @@ -17,45 +17,35 @@ #include "mmInt.h" #include "wal.h" -static bool mmDeployRequired(SDnode *pDnode) { - if (pDnode->data.dnodeId > 0) return false; - if (pDnode->data.clusterId > 0) return false; - if (strcmp(pDnode->data.localEp, pDnode->data.firstEp) != 0) return false; +static bool mmDeployRequired(const SMgmtInputOpt *pInput) { + if (pInput->dnodeId > 0) return false; + if (pInput->clusterId > 0) return false; + if (strcmp(pInput->localEp, pInput->firstEp) != 0) return false; return true; } -static int32_t mmRequire(SMgmtWrapper *pWrapper, bool *required) { +static int32_t mmRequire(const SMgmtInputOpt *pInput, bool *required) { SMnodeMgmt mgmt = {0}; - mgmt.path = pWrapper->path; + mgmt.path = pInput->path; if (mmReadFile(&mgmt, required) != 0) { return -1; } if (!(*required)) { - *required = mmDeployRequired(pWrapper->pDnode); + *required = mmDeployRequired(pInput); } return 0; } -static void mmInitOption(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - msgCb.queueFps[QUERY_QUEUE] = mmPutMsgToQueryQueue; - msgCb.queueFps[READ_QUEUE] = mmPutMsgToReadQueue; - msgCb.queueFps[WRITE_QUEUE] = mmPutMsgToWriteQueue; - msgCb.queueFps[SYNC_QUEUE] = mmPutMsgToWriteQueue; - pOption->msgCb = msgCb; -} - -static void mmBuildOptionForDeploy(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { - mmInitOption(pMgmt, pOption); +static void mmBuildOptionForDeploy(SMnodeMgmt *pMgmt, const SMgmtInputOpt *pInput, SMnodeOpt *pOption) { + pOption->msgCb = pMgmt->msgCb; pOption->replica = 1; pOption->selfIndex = 0; SReplica *pReplica = &pOption->replicas[0]; pReplica->id = 1; - pReplica->port = pMgmt->pDnode->data.serverPort; - tstrncpy(pReplica->fqdn, pMgmt->pDnode->data.localFqdn, TSDB_FQDN_LEN); + pReplica->port = pInput->serverPort; + tstrncpy(pReplica->fqdn, pInput->localFqdn, TSDB_FQDN_LEN); pOption->deploy = true; pMgmt->selfIndex = pOption->selfIndex; @@ -64,7 +54,7 @@ static void mmBuildOptionForDeploy(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { } static void mmBuildOptionForOpen(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { - mmInitOption(pMgmt, pOption); + pOption->msgCb = pMgmt->msgCb; pOption->selfIndex = pMgmt->selfIndex; pOption->replica = pMgmt->replica; memcpy(&pOption->replicas, pMgmt->replicas, sizeof(SReplica) * TSDB_MAX_REPLICA); @@ -72,8 +62,7 @@ static void mmBuildOptionForOpen(SMnodeMgmt *pMgmt, SMnodeOpt *pOption) { } static int32_t mmBuildOptionFromReq(SMnodeMgmt *pMgmt, SMnodeOpt *pOption, SDCreateMnodeReq *pCreate) { - mmInitOption(pMgmt, pOption); - + pOption->msgCb = pMgmt->msgCb; pOption->replica = pCreate->replica; pOption->selfIndex = -1; for (int32_t i = 0; i < pCreate->replica; ++i) { @@ -81,7 +70,7 @@ static int32_t mmBuildOptionFromReq(SMnodeMgmt *pMgmt, SMnodeOpt *pOption, SDCre pReplica->id = pCreate->replicas[i].id; pReplica->port = pCreate->replicas[i].port; memcpy(pReplica->fqdn, pCreate->replicas[i].fqdn, TSDB_FQDN_LEN); - if (pReplica->id == pMgmt->pDnode->data.dnodeId) { + if (pReplica->id == pMgmt->dnodeId) { pOption->selfIndex = i; } } @@ -109,7 +98,7 @@ int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pReq) { } bool deployed = true; - if (mmWriteFile(pMgmt->pWrapper, pReq, deployed) != 0) { + if (mmWriteFile(pMgmt, pReq, deployed) != 0) { dError("failed to write mnode file since %s", terrstr()); return -1; } @@ -117,10 +106,7 @@ int32_t mmAlter(SMnodeMgmt *pMgmt, SDAlterMnodeReq *pReq) { return 0; } -static void mmClose(SMgmtWrapper *pWrapper) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt == NULL) return; - +static void mmClose(SMnodeMgmt *pMgmt) { dInfo("mnode-mgmt start to cleanup"); if (pMgmt->pMnode != NULL) { mmStopWorker(pMgmt); @@ -128,12 +114,11 @@ static void mmClose(SMgmtWrapper *pWrapper) { pMgmt->pMnode = NULL; } - pWrapper->pMgmt = NULL; taosMemoryFree(pMgmt); dInfo("mnode-mgmt is cleaned up"); } -static int32_t mmOpen(SMgmtWrapper *pWrapper) { +static int32_t mmOpen(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { dInfo("mnode-mgmt start to init"); if (walInit() != 0) { dError("failed to init wal since %s", terrstr()); @@ -146,23 +131,28 @@ static int32_t mmOpen(SMgmtWrapper *pWrapper) { return -1; } - pMgmt->path = pWrapper->path; - pMgmt->pDnode = pWrapper->pDnode; - pMgmt->pWrapper = pWrapper; - pWrapper->pMgmt = pMgmt; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->dnodeId = pInput->dnodeId; + pMgmt->msgCb = pInput->msgCb; + pMgmt->msgCb.queueFps[QUERY_QUEUE] = (PutToQueueFp)mmPutRpcMsgToQueryQueue; + pMgmt->msgCb.queueFps[READ_QUEUE] = (PutToQueueFp)mmPutRpcMsgToReadQueue; + pMgmt->msgCb.queueFps[WRITE_QUEUE] = (PutToQueueFp)mmPutRpcMsgToWriteQueue; + pMgmt->msgCb.queueFps[SYNC_QUEUE] = (PutToQueueFp)mmPutRpcMsgToWriteQueue; + pMgmt->msgCb.pMgmt = pMgmt; bool deployed = false; if (mmReadFile(pMgmt, &deployed) != 0) { dError("failed to read file since %s", terrstr()); - mmClose(pWrapper); + mmClose(pMgmt); return -1; } SMnodeOpt option = {0}; if (!deployed) { dInfo("mnode start to deploy"); - pWrapper->pDnode->data.dnodeId = 1; - mmBuildOptionForDeploy(pMgmt, &option); + pMgmt->dnodeId = 1; + mmBuildOptionForDeploy(pMgmt, pInput, &option); } else { dInfo("mnode start to open"); mmBuildOptionForOpen(pMgmt, &option); @@ -171,55 +161,52 @@ static int32_t mmOpen(SMgmtWrapper *pWrapper) { pMgmt->pMnode = mndOpen(pMgmt->path, &option); if (pMgmt->pMnode == NULL) { dError("failed to open mnode since %s", terrstr()); - mmClose(pWrapper); + mmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "mnode-impl", "initialized"); + tmsgReportStartup("mnode-impl", "initialized"); if (mmStartWorker(pMgmt) != 0) { dError("failed to start mnode worker since %s", terrstr()); - mmClose(pWrapper); + mmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "mnode-worker", "initialized"); + tmsgReportStartup("mnode-worker", "initialized"); if (!deployed) { deployed = true; - if (mmWriteFile(pWrapper, NULL, deployed) != 0) { + if (mmWriteFile(pMgmt, NULL, deployed) != 0) { dError("failed to write mnode file since %s", terrstr()); return -1; } } + pOutput->dnodeId = pMgmt->dnodeId; + pOutput->pMgmt = pMgmt; dInfo("mnode-mgmt is initialized"); return 0; } -static int32_t mmStart(SMgmtWrapper *pWrapper) { +static int32_t mmStart(SMnodeMgmt *pMgmt) { dDebug("mnode-mgmt start to run"); - SMnodeMgmt *pMgmt = pWrapper->pMgmt; return mndStart(pMgmt->pMnode); } -static void mmStop(SMgmtWrapper *pWrapper) { +static void mmStop(SMnodeMgmt *pMgmt) { dDebug("mnode-mgmt start to stop"); - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt != NULL) { - mndStop(pMgmt->pMnode); - } + mndStop(pMgmt->pMnode); } -void mmSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = mmOpen; - mgmtFp.closeFp = mmClose; - mgmtFp.startFp = mmStart; - mgmtFp.stopFp = mmStop; - mgmtFp.createFp = mmProcessCreateReq; - mgmtFp.dropFp = mmProcessDropReq; - mgmtFp.requiredFp = mmRequire; +SMgmtFunc mmGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = mmOpen; + mgmtFunc.closeFp = (NodeCloseFp)mmClose; + mgmtFunc.startFp = (NodeStartFp)mmStart; + mgmtFunc.stopFp = (NodeStopFp)mmStop; + mgmtFunc.createFp = (NodeCreateFp)mmProcessCreateReq; + mgmtFunc.dropFp = (NodeDropFp)mmProcessDropReq; + mgmtFunc.requiredFp = mmRequire; + mgmtFunc.getHandlesFp = mmGetMsgHandles; - mmInitMsgHandle(pWrapper); - pWrapper->name = "mnode"; - pWrapper->fp = mgmtFp; + return mgmtFunc; } diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c index aac5bbc16a..f55e02e50a 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c @@ -30,27 +30,27 @@ static inline void mmSendRsp(SNodeMsg *pMsg, int32_t code) { static void mmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { SMnodeMgmt *pMgmt = pInfo->ahandle; - - int32_t code = -1; - tmsg_t msgType = pMsg->rpcMsg.msgType; - dTrace("msg:%p, get from mnode queue", pMsg); + int32_t code = -1; + tmsg_t msgType = pMsg->rpcMsg.msgType; + bool isRequest = msgType & 1U; + dTrace("msg:%p, get from mnode queue, type:%s", pMsg, TMSG_INFO(msgType)); switch (msgType) { case TDMT_DND_ALTER_MNODE: code = mmProcessAlterReq(pMgmt, pMsg); break; case TDMT_MON_MM_INFO: - code = mmProcessGetMonMmInfoReq(pMgmt->pWrapper, pMsg); + code = mmProcessGetMonitorInfoReq(pMgmt, pMsg); break; case TDMT_MON_MM_LOAD: - code = mmProcessGetMnodeLoadsReq(pMgmt->pWrapper, pMsg); + code = mmProcessGetLoadsReq(pMgmt, pMsg); break; default: pMsg->pNode = pMgmt->pMnode; code = mndProcessMsg(pMsg); } - if (msgType & 1U) { + if (isRequest) { if (pMsg->rpcMsg.handle != NULL && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { if (code != 0 && terrno != 0) code = terrno; mmSendRsp(pMsg, code); @@ -64,62 +64,46 @@ static void mmProcessQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { static void mmProcessQueryQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { SMnodeMgmt *pMgmt = pInfo->ahandle; - + int32_t code = -1; + tmsg_t msgType = pMsg->rpcMsg.msgType; + bool isRequest = msgType & 1U; dTrace("msg:%p, get from mnode-query queue", pMsg); - SRpcMsg *pRpc = &pMsg->rpcMsg; - int32_t code = -1; pMsg->pNode = pMgmt->pMnode; code = mndProcessMsg(pMsg); - if (pRpc->msgType & 1U) { - if (pRpc->handle != NULL && code != 0) { - dError("msg:%p, failed to process since %s", pMsg, terrstr()); + if (isRequest) { + if (pMsg->rpcMsg.handle != NULL && code != 0) { + if (code != 0 && terrno != 0) code = terrno; mmSendRsp(pMsg, code); } } dTrace("msg:%p, is freed, result:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code)); - rpcFreeCont(pRpc->pCont); + rpcFreeCont(pMsg->rpcMsg.pCont); taosFreeQitem(pMsg); } -static void mmPutNodeMsgToWorker(SSingleWorker *pWorker, SNodeMsg *pMsg) { - dTrace("msg:%p, put into worker %s", pMsg, pWorker->name); +static int32_t mmPutNodeMsgToWorker(SSingleWorker *pWorker, SNodeMsg *pMsg) { + dTrace("msg:%p, put into worker %s, type:%s", pMsg, pWorker->name, TMSG_INFO(pMsg->rpcMsg.msgType)); taosWriteQitem(pWorker->queue, pMsg); -} - -int32_t mmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - mmPutNodeMsgToWorker(&pMgmt->writeWorker, pMsg); return 0; } -int32_t mmProcessSyncMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - mmPutNodeMsgToWorker(&pMgmt->syncWorker, pMsg); - return 0; +int32_t mmPutNodeMsgToWriteQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { return mmPutNodeMsgToWorker(&pMgmt->writeWorker, pMsg); } + +int32_t mmPutNodeMsgToSyncQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { return mmPutNodeMsgToWorker(&pMgmt->syncWorker, pMsg); } + +int32_t mmPutNodeMsgToReadQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { return mmPutNodeMsgToWorker(&pMgmt->readWorker, pMsg); } + +int32_t mmPutNodeMsgToQueryQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { return mmPutNodeMsgToWorker(&pMgmt->queryWorker, pMsg); } -int32_t mmProcessReadMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - mmPutNodeMsgToWorker(&pMgmt->readWorker, pMsg); - return 0; +int32_t mmPutNodeMsgToMonitorQueue(SMnodeMgmt *pMgmt, SNodeMsg *pMsg) { + return mmPutNodeMsgToWorker(&pMgmt->monitorWorker, pMsg); } -int32_t mmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - mmPutNodeMsgToWorker(&pMgmt->queryWorker, pMsg); - return 0; -} - -int32_t mmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - mmPutNodeMsgToWorker(&pMgmt->monitorWorker, pMsg); - return 0; -} - -static int32_t mmPutRpcMsgToWorker(SSingleWorker *pWorker, SRpcMsg *pRpc) { +static inline int32_t mmPutRpcMsgToWorker(SSingleWorker *pWorker, SRpcMsg *pRpc) { SNodeMsg *pMsg = taosAllocateQitem(sizeof(SNodeMsg)); if (pMsg == NULL) return -1; @@ -129,25 +113,19 @@ static int32_t mmPutRpcMsgToWorker(SSingleWorker *pWorker, SRpcMsg *pRpc) { return 0; } -int32_t mmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t mmPutRpcMsgToQueryQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc) { return mmPutRpcMsgToWorker(&pMgmt->queryWorker, pRpc); } -int32_t mmPutMsgToWriteQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t mmPutRpcMsgToWriteQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc) { return mmPutRpcMsgToWorker(&pMgmt->writeWorker, pRpc); } -int32_t mmPutMsgToReadQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t mmPutRpcMsgToReadQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc) { return mmPutRpcMsgToWorker(&pMgmt->readWorker, pRpc); } -int32_t mmPutMsgToSyncQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SMnodeMgmt *pMgmt = pWrapper->pMgmt; - return mmPutRpcMsgToWorker(&pMgmt->syncWorker, pRpc); -} +int32_t mmPutMsgToSyncQueue(SMnodeMgmt *pMgmt, SRpcMsg *pRpc) { return mmPutRpcMsgToWorker(&pMgmt->syncWorker, pRpc); } int32_t mmStartWorker(SMnodeMgmt *pMgmt) { SSingleWorkerCfg qCfg = { @@ -198,18 +176,16 @@ int32_t mmStartWorker(SMnodeMgmt *pMgmt) { return -1; } - if (tsMultiProcess) { - SSingleWorkerCfg mCfg = { - .min = 1, - .max = 1, - .name = "mnode-monitor", - .fp = (FItem)mmProcessQueue, - .param = pMgmt, - }; - if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { - dError("failed to start mnode mnode-monitor worker since %s", terrstr()); - return -1; - } + SSingleWorkerCfg mCfg = { + .min = 1, + .max = 1, + .name = "mnode-monitor", + .fp = (FItem)mmProcessQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { + dError("failed to start mnode mnode-monitor worker since %s", terrstr()); + return -1; } dDebug("mnode workers are initialized"); diff --git a/source/dnode/mgmt/mgmt_qnode/CMakeLists.txt b/source/dnode/mgmt/mgmt_qnode/CMakeLists.txt index bf31b2afc3..64f8a45ac4 100644 --- a/source/dnode/mgmt/mgmt_qnode/CMakeLists.txt +++ b/source/dnode/mgmt/mgmt_qnode/CMakeLists.txt @@ -5,5 +5,5 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mgmt_qnode dnode_interface + mgmt_qnode node_util ) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_qnode/inc/qmInt.h b/source/dnode/mgmt/mgmt_qnode/inc/qmInt.h index d52fbff683..8b48113dd3 100644 --- a/source/dnode/mgmt/mgmt_qnode/inc/qmInt.h +++ b/source/dnode/mgmt/mgmt_qnode/inc/qmInt.h @@ -16,7 +16,7 @@ #ifndef _TD_DND_QNODE_INT_H_ #define _TD_DND_QNODE_INT_H_ -#include "dmInt.h" +#include "dmUtil.h" #include "qnode.h" @@ -26,30 +26,31 @@ extern "C" { typedef struct SQnodeMgmt { SQnode *pQnode; - SDnode *pDnode; - SMgmtWrapper *pWrapper; + SMsgCb msgCb; const char *path; + const char *name; + int32_t dnodeId; SSingleWorker queryWorker; SSingleWorker fetchWorker; SSingleWorker monitorWorker; } SQnodeMgmt; // qmHandle.c -void qmInitMsgHandle(SMgmtWrapper *pWrapper); -int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t qmProcessGetMonQmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); +SArray *qmGetMsgHandles(); +int32_t qmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg); +int32_t qmProcessDropReq(SQnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t qmProcessGetMonitorInfoReq(SQnodeMgmt *pMgmt, SNodeMsg *pReq); // qmWorker.c -int32_t qmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t qmPutMsgToFetchQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t qmGetQueueSize(SMgmtWrapper *pWrapper, int32_t vgId, EQueueType qtype); +int32_t qmPutRpcMsgToQueryQueue(SQnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t qmPutRpcMsgToFetchQueue(SQnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t qmGetQueueSize(SQnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype); int32_t qmStartWorker(SQnodeMgmt *pMgmt); void qmStopWorker(SQnodeMgmt *pMgmt); -int32_t qmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t qmProcessFetchMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t qmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); +int32_t qmPutNodeMsgToQueryQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t qmPutNodeMsgToFetchQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t qmPutNodeMsgToMonitorQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c b/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c index 11b91f0568..c500176b15 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmHandle.c @@ -16,12 +16,12 @@ #define _DEFAULT_SOURCE #include "qmInt.h" -void qmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonQmInfo *qmInfo) {} +static void qmGetMonitorInfo(SQnodeMgmt *pMgmt, SMonQmInfo *qmInfo) {} -int32_t qmProcessGetMonQmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t qmProcessGetMonitorInfoReq(SQnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonQmInfo qmInfo = {0}; - qmGetMonitorInfo(pWrapper, &qmInfo); - dmGetMonitorSysInfo(&qmInfo.sys); + qmGetMonitorInfo(pMgmt, &qmInfo); + dmGetMonitorSystemInfo(&qmInfo.sys); monGetLogs(&qmInfo.log); int32_t rspLen = tSerializeSMonQmInfo(NULL, 0, &qmInfo); @@ -43,8 +43,7 @@ int32_t qmProcessGetMonQmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t qmProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDCreateQnodeReq createReq = {0}; @@ -53,14 +52,14 @@ int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (createReq.dnodeId != pDnode->data.dnodeId) { + if (pInput->dnodeId != 0 && createReq.dnodeId != pInput->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to create qnode since %s", terrstr()); return -1; } bool deployed = true; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pInput->path, pInput->name, deployed) != 0) { dError("failed to write qnode file since %s", terrstr()); return -1; } @@ -68,8 +67,7 @@ int32_t qmProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t qmProcessDropReq(SQnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDDropQnodeReq dropReq = {0}; @@ -78,14 +76,14 @@ int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (dropReq.dnodeId != pDnode->data.dnodeId) { + if (pMgmt->dnodeId != 0 && dropReq.dnodeId != pMgmt->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to drop qnode since %s", terrstr()); return -1; } bool deployed = false; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pMgmt->path, pMgmt->name, deployed) != 0) { dError("failed to write qnode file since %s", terrstr()); return -1; } @@ -93,18 +91,31 @@ int32_t qmProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -void qmInitMsgHandle(SMgmtWrapper *pWrapper) { - dmSetMsgHandle(pWrapper, TDMT_MON_QM_INFO, qmProcessMonitorMsg, DEFAULT_HANDLE); +SArray *qmGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(16, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + if (dmSetMgmtHandle(pArray, TDMT_MON_QM_INFO, qmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; // Requests handled by VNODE - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY, qmProcessQueryMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, qmProcessQueryMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_FETCH, qmProcessFetchMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_FETCH_RSP, qmProcessFetchMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, qmProcessFetchMsg, QNODE_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY, qmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_CONTINUE, qmPutNodeMsgToQueryQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_RSP, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_HEARTBEAT, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; - dmSetMsgHandle(pWrapper, TDMT_VND_RES_READY, qmProcessFetchMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, qmProcessFetchMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, qmProcessFetchMsg, QNODE_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, qmProcessFetchMsg, QNODE_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_RES_READY, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASKS_STATUS, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CANCEL_TASK, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, qmPutNodeMsgToFetchQueue, 1) == NULL) goto _OVER; + + code = 0; +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } } diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c index d03f001a8d..5e86a30732 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmInt.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmInt.c @@ -16,21 +16,13 @@ #define _DEFAULT_SOURCE #include "qmInt.h" -static int32_t qmRequire(SMgmtWrapper *pWrapper, bool *required) { return dmReadFile(pWrapper, required); } - -static void qmInitOption(SQnodeMgmt *pMgmt, SQnodeOpt *pOption) { - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - msgCb.queueFps[QUERY_QUEUE] = qmPutMsgToQueryQueue; - msgCb.queueFps[FETCH_QUEUE] = qmPutMsgToFetchQueue; - msgCb.qsizeFp = qmGetQueueSize; - pOption->msgCb = msgCb; +static int32_t qmRequire(const SMgmtInputOpt *pInput, bool *required) { + return dmReadFile(pInput->path, pInput->name, required); } -static void qmClose(SMgmtWrapper *pWrapper) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt == NULL) return; +static void qmInitOption(SQnodeMgmt *pMgmt, SQnodeOpt *pOption) { pOption->msgCb = pMgmt->msgCb; } +static void qmClose(SQnodeMgmt *pMgmt) { dInfo("qnode-mgmt start to cleanup"); if (pMgmt->pQnode != NULL) { qmStopWorker(pMgmt); @@ -38,12 +30,11 @@ static void qmClose(SMgmtWrapper *pWrapper) { pMgmt->pQnode = NULL; } - pWrapper->pMgmt = NULL; taosMemoryFree(pMgmt); dInfo("qnode-mgmt is cleaned up"); } -static int32_t qmOpen(SMgmtWrapper *pWrapper) { +static int32_t qmOpen(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { dInfo("qnode-mgmt start to init"); SQnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SQnodeMgmt)); if (pMgmt == NULL) { @@ -51,41 +42,51 @@ static int32_t qmOpen(SMgmtWrapper *pWrapper) { return -1; } - pMgmt->path = pWrapper->path; - pMgmt->pDnode = pWrapper->pDnode; - pMgmt->pWrapper = pWrapper; - pWrapper->pMgmt = pMgmt; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->dnodeId = pInput->dnodeId; + pMgmt->msgCb = pInput->msgCb; + pMgmt->msgCb.queueFps[QUERY_QUEUE] = (PutToQueueFp)qmPutRpcMsgToQueryQueue; + pMgmt->msgCb.queueFps[FETCH_QUEUE] = (PutToQueueFp)qmPutRpcMsgToFetchQueue; + pMgmt->msgCb.qsizeFp = (GetQueueSizeFp)qmGetQueueSize; + pMgmt->msgCb.pMgmt = pMgmt; SQnodeOpt option = {0}; qmInitOption(pMgmt, &option); pMgmt->pQnode = qndOpen(&option); if (pMgmt->pQnode == NULL) { dError("failed to open qnode since %s", terrstr()); - qmClose(pWrapper); + qmClose(pMgmt); + return -1; + } + tmsgReportStartup("qnode-impl", "initialized"); + + if (udfcOpen() != 0) { + dError("qnode can not open udfc"); + qmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "qnode-impl", "initialized"); if (qmStartWorker(pMgmt) != 0) { dError("failed to start qnode worker since %s", terrstr()); - qmClose(pWrapper); + qmClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "qnode-worker", "initialized"); + tmsgReportStartup("qnode-worker", "initialized"); + pOutput->pMgmt = pMgmt; dInfo("qnode-mgmt is initialized"); return 0; } -void qmSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = qmOpen; - mgmtFp.closeFp = qmClose; - mgmtFp.createFp = qmProcessCreateReq; - mgmtFp.dropFp = qmProcessDropReq; - mgmtFp.requiredFp = qmRequire; +SMgmtFunc qmGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = qmOpen; + mgmtFunc.closeFp = (NodeCloseFp)qmClose; + mgmtFunc.createFp = (NodeCreateFp)qmProcessCreateReq; + mgmtFunc.dropFp = (NodeDropFp)qmProcessDropReq; + mgmtFunc.requiredFp = qmRequire; + mgmtFunc.getHandlesFp = qmGetMsgHandles; - qmInitMsgHandle(pWrapper); - pWrapper->name = "qnode"; - pWrapper->fp = mgmtFp; + return mgmtFunc; } diff --git a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c index 965d35cb3e..c95a4e8292 100644 --- a/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c +++ b/source/dnode/mgmt/mgmt_qnode/src/qmWorker.c @@ -36,7 +36,7 @@ static void qmProcessMonitorQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { int32_t code = -1; if (pMsg->rpcMsg.msgType == TDMT_MON_QM_INFO) { - code = qmProcessGetMonQmInfoReq(pMgmt->pWrapper, pMsg); + code = qmProcessGetMonitorInfoReq(pMgmt, pMsg); } else { terrno = TSDB_CODE_MSG_NOT_PROCESSED; } @@ -83,27 +83,22 @@ static void qmProcessFetchQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { taosFreeQitem(pMsg); } -static void qmPutMsgToWorker(SSingleWorker *pWorker, SNodeMsg *pMsg) { +static int32_t qmPutNodeMsgToWorker(SSingleWorker *pWorker, SNodeMsg *pMsg) { dTrace("msg:%p, put into worker %s", pMsg, pWorker->name); taosWriteQitem(pWorker->queue, pMsg); -} - -int32_t qmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; - qmPutMsgToWorker(&pMgmt->queryWorker, pMsg); return 0; } -int32_t qmProcessFetchMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; - qmPutMsgToWorker(&pMgmt->fetchWorker, pMsg); - return 0; +int32_t qmPutNodeMsgToQueryQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg) { + return qmPutNodeMsgToWorker(&pMgmt->queryWorker, pMsg); } -int32_t qmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; - qmPutMsgToWorker(&pMgmt->monitorWorker, pMsg); - return 0; +int32_t qmPutNodeMsgToFetchQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg) { + return qmPutNodeMsgToWorker(&pMgmt->fetchWorker, pMsg); +} + +int32_t qmPutNodeMsgToMonitorQueue(SQnodeMgmt *pMgmt, SNodeMsg *pMsg) { + return qmPutNodeMsgToWorker(&pMgmt->monitorWorker, pMsg); } static int32_t qmPutRpcMsgToWorker(SQnodeMgmt *pMgmt, SSingleWorker *pWorker, SRpcMsg *pRpc) { @@ -118,19 +113,16 @@ static int32_t qmPutRpcMsgToWorker(SQnodeMgmt *pMgmt, SSingleWorker *pWorker, SR return 0; } -int32_t qmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t qmPutRpcMsgToQueryQueue(SQnodeMgmt *pMgmt, SRpcMsg *pRpc) { return qmPutRpcMsgToWorker(pMgmt, &pMgmt->queryWorker, pRpc); } -int32_t qmPutMsgToFetchQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - SQnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t qmPutRpcMsgToFetchQueue(SQnodeMgmt *pMgmt, SRpcMsg *pRpc) { return qmPutRpcMsgToWorker(pMgmt, &pMgmt->fetchWorker, pRpc); } -int32_t qmGetQueueSize(SMgmtWrapper *pWrapper, int32_t vgId, EQueueType qtype) { - int32_t size = -1; - SQnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t qmGetQueueSize(SQnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype) { + int32_t size = -1; switch (qtype) { case QUERY_QUEUE: @@ -173,18 +165,16 @@ int32_t qmStartWorker(SQnodeMgmt *pMgmt) { return -1; } - if (tsMultiProcess) { - SSingleWorkerCfg mCfg = { - .min = 1, - .max = 1, - .name = "qnode-monitor", - .fp = (FItem)qmProcessMonitorQueue, - .param = pMgmt, - }; - if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { - dError("failed to start qnode-monitor worker since %s", terrstr()); - return -1; - } + SSingleWorkerCfg mCfg = { + .min = 1, + .max = 1, + .name = "qnode-monitor", + .fp = (FItem)qmProcessMonitorQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { + dError("failed to start qnode-monitor worker since %s", terrstr()); + return -1; } dDebug("qnode workers are initialized"); diff --git a/source/dnode/mgmt/mgmt_snode/CMakeLists.txt b/source/dnode/mgmt/mgmt_snode/CMakeLists.txt index b8a99c9d4d..62dc41a0ae 100644 --- a/source/dnode/mgmt/mgmt_snode/CMakeLists.txt +++ b/source/dnode/mgmt/mgmt_snode/CMakeLists.txt @@ -5,5 +5,5 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mgmt_snode dnode_interface + mgmt_snode node_util ) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_snode/inc/smInt.h b/source/dnode/mgmt/mgmt_snode/inc/smInt.h index 9eb48af733..a1ab9ba077 100644 --- a/source/dnode/mgmt/mgmt_snode/inc/smInt.h +++ b/source/dnode/mgmt/mgmt_snode/inc/smInt.h @@ -16,7 +16,7 @@ #ifndef _TD_DND_SNODE_INT_H_ #define _TD_DND_SNODE_INT_H_ -#include "dmInt.h" +#include "dmUtil.h" #include "snode.h" @@ -26,9 +26,10 @@ extern "C" { typedef struct SSnodeMgmt { SSnode *pSnode; - SDnode *pDnode; - SMgmtWrapper *pWrapper; + SMsgCb msgCb; const char *path; + const char *name; + int32_t dnodeId; SRWLatch latch; int8_t uniqueWorkerInUse; SArray *uniqueWorkers; // SArray @@ -37,19 +38,19 @@ typedef struct SSnodeMgmt { } SSnodeMgmt; // smHandle.c -void smInitMsgHandle(SMgmtWrapper *pWrapper); -int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessGetMonSmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); +SArray *smGetMsgHandles(); +int32_t smProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg); +int32_t smProcessDropReq(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t smProcessGetMonitorInfoReq(SSnodeMgmt *pMgmt, SNodeMsg *pReq); // smWorker.c int32_t smStartWorker(SSnodeMgmt *pMgmt); void smStopWorker(SSnodeMgmt *pMgmt); -int32_t smProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessUniqueMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessSharedMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessExecMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t smProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); +int32_t smPutNodeMsgToMgmtQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t smPutNodeMsgToUniqueQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t smPutNodeMsgToSharedQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t smPutNodeMsgToExecQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t smPutNodeMsgToMonitorQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/mgmt_snode/src/smHandle.c b/source/dnode/mgmt/mgmt_snode/src/smHandle.c index defc5ab136..b0f0b73cbc 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smHandle.c +++ b/source/dnode/mgmt/mgmt_snode/src/smHandle.c @@ -16,12 +16,12 @@ #define _DEFAULT_SOURCE #include "smInt.h" -void smGetMonitorInfo(SMgmtWrapper *pWrapper, SMonSmInfo *smInfo) {} +static void smGetMonitorInfo(SSnodeMgmt *pMgmt, SMonSmInfo *smInfo) {} -int32_t smProcessGetMonSmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t smProcessGetMonitorInfoReq(SSnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonSmInfo smInfo = {0}; - smGetMonitorInfo(pWrapper, &smInfo); - dmGetMonitorSysInfo(&smInfo.sys); + smGetMonitorInfo(pMgmt, &smInfo); + dmGetMonitorSystemInfo(&smInfo.sys); monGetLogs(&smInfo.log); int32_t rspLen = tSerializeSMonSmInfo(NULL, 0, &smInfo); @@ -43,8 +43,7 @@ int32_t smProcessGetMonSmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t smProcessCreateReq(const SMgmtInputOpt *pInput, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDCreateSnodeReq createReq = {0}; @@ -53,14 +52,14 @@ int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (createReq.dnodeId != pDnode->data.dnodeId) { + if (pInput->dnodeId != 0 && createReq.dnodeId != pInput->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to create snode since %s", terrstr()); return -1; } bool deployed = true; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pInput->path, pInput->name, deployed) != 0) { dError("failed to write snode file since %s", terrstr()); return -1; } @@ -68,8 +67,7 @@ int32_t smProcessCreateReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SDnode *pDnode = pWrapper->pDnode; +int32_t smProcessDropReq(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDDropSnodeReq dropReq = {0}; @@ -78,14 +76,14 @@ int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return -1; } - if (dropReq.dnodeId != pDnode->data.dnodeId) { + if (pMgmt->dnodeId != 0 && dropReq.dnodeId != pMgmt->dnodeId) { terrno = TSDB_CODE_INVALID_OPTION; dError("failed to drop snode since %s", terrstr()); return -1; } bool deployed = false; - if (dmWriteFile(pWrapper, deployed) != 0) { + if (dmWriteFile(pMgmt->path, pMgmt->name, deployed) != 0) { dError("failed to write snode file since %s", terrstr()); return -1; } @@ -93,10 +91,23 @@ int32_t smProcessDropReq(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -void smInitMsgHandle(SMgmtWrapper *pWrapper) { - dmSetMsgHandle(pWrapper, TDMT_MON_SM_INFO, smProcessMonitorMsg, DEFAULT_HANDLE); +SArray *smGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(4, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + if (dmSetMgmtHandle(pArray, TDMT_MON_SM_INFO, smPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; // Requests handled by SNODE - dmSetMsgHandle(pWrapper, TDMT_SND_TASK_DEPLOY, smProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_SND_TASK_EXEC, smProcessExecMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_SND_TASK_DEPLOY, smPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_SND_TASK_EXEC, smPutNodeMsgToExecQueue, 0) == NULL) goto _OVER; + + code = 0; +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } } diff --git a/source/dnode/mgmt/mgmt_snode/src/smInt.c b/source/dnode/mgmt/mgmt_snode/src/smInt.c index 26300a9fe3..5b9f2fc7f7 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smInt.c +++ b/source/dnode/mgmt/mgmt_snode/src/smInt.c @@ -17,34 +17,25 @@ #include "smInt.h" #include "libs/function/function.h" -static int32_t smRequire(SMgmtWrapper *pWrapper, bool *required) { return dmReadFile(pWrapper, required); } - -static void smInitOption(SSnodeMgmt *pMgmt, SSnodeOpt *pOption) { - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - pOption->msgCb = msgCb; +static int32_t smRequire(const SMgmtInputOpt *pInput, bool *required) { + return dmReadFile(pInput->path, pInput->name, required); } -static void smClose(SMgmtWrapper *pWrapper) { - SSnodeMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt == NULL) return; +static void smInitOption(SSnodeMgmt *pMgmt, SSnodeOpt *pOption) { pOption->msgCb = pMgmt->msgCb; } +static void smClose(SSnodeMgmt *pMgmt) { dInfo("snode-mgmt start to cleanup"); - - udfcClose(); - if (pMgmt->pSnode != NULL) { smStopWorker(pMgmt); sndClose(pMgmt->pSnode); pMgmt->pSnode = NULL; } - pWrapper->pMgmt = NULL; taosMemoryFree(pMgmt); dInfo("snode-mgmt is cleaned up"); } -int32_t smOpen(SMgmtWrapper *pWrapper) { +int32_t smOpen(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { dInfo("snode-mgmt start to init"); SSnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SSnodeMgmt)); if (pMgmt == NULL) { @@ -52,42 +43,47 @@ int32_t smOpen(SMgmtWrapper *pWrapper) { return -1; } - pMgmt->path = pWrapper->path; - pMgmt->pDnode = pWrapper->pDnode; - pMgmt->pWrapper = pWrapper; - pWrapper->pMgmt = pMgmt; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->dnodeId = pInput->dnodeId; + pMgmt->msgCb = pInput->msgCb; + pMgmt->msgCb.pMgmt = pMgmt; SSnodeOpt option = {0}; smInitOption(pMgmt, &option); pMgmt->pSnode = sndOpen(pMgmt->path, &option); if (pMgmt->pSnode == NULL) { dError("failed to open snode since %s", terrstr()); + smClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "snode-impl", "initialized"); + tmsgReportStartup("snode-impl", "initialized"); if (smStartWorker(pMgmt) != 0) { dError("failed to start snode worker since %s", terrstr()); + smClose(pMgmt); return -1; } - dmReportStartup(pWrapper->pDnode, "snode-worker", "initialized"); + tmsgReportStartup("snode-worker", "initialized"); if (udfcOpen() != 0) { dError("failed to open udfc in snode"); + smClose(pMgmt); + return -1; } + pOutput->pMgmt = pMgmt; return 0; } -void smSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = smOpen; - mgmtFp.closeFp = smClose; - mgmtFp.createFp = smProcessCreateReq; - mgmtFp.dropFp = smProcessDropReq; - mgmtFp.requiredFp = smRequire; +SMgmtFunc smGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = smOpen; + mgmtFunc.closeFp = (NodeCloseFp)smClose; + mgmtFunc.createFp = (NodeCreateFp)smProcessCreateReq; + mgmtFunc.dropFp = (NodeDropFp)smProcessDropReq; + mgmtFunc.requiredFp = smRequire; + mgmtFunc.getHandlesFp = smGetMsgHandles; - smInitMsgHandle(pWrapper); - pWrapper->name = "snode"; - pWrapper->fp = mgmtFp; + return mgmtFunc; } diff --git a/source/dnode/mgmt/mgmt_snode/src/smWorker.c b/source/dnode/mgmt/mgmt_snode/src/smWorker.c index 2ae439bbd6..90e20f5fc5 100644 --- a/source/dnode/mgmt/mgmt_snode/src/smWorker.c +++ b/source/dnode/mgmt/mgmt_snode/src/smWorker.c @@ -36,7 +36,7 @@ static void smProcessMonitorQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { int32_t code = -1; if (pMsg->rpcMsg.msgType == TDMT_MON_SM_INFO) { - code = smProcessGetMonSmInfoReq(pMgmt->pWrapper, pMsg); + code = smProcessGetMonitorInfoReq(pMgmt, pMsg); } else { terrno = TSDB_CODE_MSG_NOT_PROCESSED; } @@ -121,18 +121,16 @@ int32_t smStartWorker(SSnodeMgmt *pMgmt) { return -1; } - if (tsMultiProcess) { - SSingleWorkerCfg mCfg = { - .min = 1, - .max = 1, - .name = "snode-monitor", - .fp = (FItem)smProcessMonitorQueue, - .param = pMgmt, - }; - if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { - dError("failed to start snode-monitor worker since %s", terrstr()); - return -1; - } + SSingleWorkerCfg mCfg = { + .min = 1, + .max = 1, + .name = "snode-monitor", + .fp = (FItem)smProcessMonitorQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { + dError("failed to start snode-monitor worker since %s", terrstr()); + return -1; } dDebug("snode workers are initialized"); @@ -163,8 +161,7 @@ static FORCE_INLINE int32_t smGetSWTypeFromMsg(SRpcMsg *pMsg) { return 0; } -int32_t smProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SSnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t smPutNodeMsgToMgmtQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { SMultiWorker *pWorker = taosArrayGetP(pMgmt->uniqueWorkers, 0); if (pWorker == NULL) { terrno = TSDB_CODE_INVALID_MSG; @@ -176,8 +173,7 @@ int32_t smProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t smProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SSnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t smPutNodeMsgToMonitorQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { SSingleWorker *pWorker = &pMgmt->monitorWorker; dTrace("msg:%p, put into worker:%s", pMsg, pWorker->name); @@ -185,8 +181,7 @@ int32_t smProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t smProcessUniqueMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SSnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t smPutNodeMsgToUniqueQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { int32_t index = smGetSWIdFromMsg(&pMsg->rpcMsg); SMultiWorker *pWorker = taosArrayGetP(pMgmt->uniqueWorkers, index); if (pWorker == NULL) { @@ -199,8 +194,7 @@ int32_t smProcessUniqueMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t smProcessSharedMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SSnodeMgmt *pMgmt = pWrapper->pMgmt; +int32_t smPutNodeMsgToSharedQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { SSingleWorker *pWorker = &pMgmt->sharedWorker; dTrace("msg:%p, put into worker:%s", pMsg, pWorker->name); @@ -208,11 +202,11 @@ int32_t smProcessSharedMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -int32_t smProcessExecMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { +int32_t smPutNodeMsgToExecQueue(SSnodeMgmt *pMgmt, SNodeMsg *pMsg) { int32_t workerType = smGetSWTypeFromMsg(&pMsg->rpcMsg); if (workerType == SND_WORKER_TYPE__SHARED) { - return smProcessSharedMsg(pWrapper, pMsg); + return smPutNodeMsgToSharedQueue(pMgmt, pMsg); } else { - return smProcessUniqueMsg(pWrapper, pMsg); + return smPutNodeMsgToUniqueQueue(pMgmt, pMsg); } } diff --git a/source/dnode/mgmt/mgmt_vnode/CMakeLists.txt b/source/dnode/mgmt/mgmt_vnode/CMakeLists.txt index 55a76cf772..15b822ad92 100644 --- a/source/dnode/mgmt/mgmt_vnode/CMakeLists.txt +++ b/source/dnode/mgmt/mgmt_vnode/CMakeLists.txt @@ -5,5 +5,5 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mgmt_vnode dnode_interface + mgmt_vnode node_util ) \ No newline at end of file diff --git a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h index 51b3860461..ca43ef8c22 100644 --- a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h +++ b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h @@ -16,7 +16,7 @@ #ifndef _TD_DND_VNODES_INT_H_ #define _TD_DND_VNODES_INT_H_ -#include "dmInt.h" +#include "dmUtil.h" #include "sync.h" #include "vnode.h" @@ -25,14 +25,11 @@ extern "C" { #endif -typedef struct SVnodesMgmt { - SHashObj *hash; - SRWLatch latch; - SVnodesStat state; +typedef struct SVnodeMgmt { + SMsgCb msgCb; const char *path; - SDnode *pDnode; - SMgmtWrapper *pWrapper; - STfs *pTfs; + const char *name; + int32_t dnodeId; SQWorkerPool queryPool; SQWorkerPool fetchPool; SWWorkerPool syncPool; @@ -40,14 +37,16 @@ typedef struct SVnodesMgmt { SWWorkerPool mergePool; SSingleWorker mgmtWorker; SSingleWorker monitorWorker; -} SVnodesMgmt; + SHashObj *hash; + SRWLatch latch; + SVnodesStat state; + STfs *pTfs; +} SVnodeMgmt; typedef struct { int32_t vgId; int32_t vgVersion; int8_t dropped; - uint64_t dbUid; - char db[TSDB_DB_FNAME_LEN]; char path[PATH_MAX + 20]; } SWrapperCfg; @@ -57,8 +56,6 @@ typedef struct { int32_t vgVersion; int8_t dropped; int8_t accessState; - uint64_t dbUid; - char *db; char *path; SVnode *pImpl; STaosQueue *pWriteQ; @@ -67,7 +64,6 @@ typedef struct { STaosQueue *pQueryQ; STaosQueue *pFetchQ; STaosQueue *pMergeQ; - SMgmtWrapper *pWrapper; } SVnodeObj; typedef struct { @@ -76,50 +72,49 @@ typedef struct { int32_t failed; int32_t threadIndex; TdThread thread; - SVnodesMgmt *pMgmt; + SVnodeMgmt *pMgmt; SWrapperCfg *pCfgs; } SVnodeThread; // vmInt.c -SVnodeObj *vmAcquireVnode(SVnodesMgmt *pMgmt, int32_t vgId); -void vmReleaseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode); -int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl); -void vmCloseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode); +SVnodeObj *vmAcquireVnode(SVnodeMgmt *pMgmt, int32_t vgId); +void vmReleaseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode); +int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl); +void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode); // vmHandle.c -void vmInitMsgHandle(SMgmtWrapper *pWrapper); -int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq); -int32_t vmProcessDropVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pReq); -int32_t vmProcessGetMonVmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); -int32_t vmProcessGetVnodeLoadsReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq); -void vmGetVnodeLoads(SMgmtWrapper *pWrapper, SMonVloadInfo *pInfo); +SArray *vmGetMsgHandles(); +int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq); +int32_t vmProcessDropVnodeReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq); +int32_t vmProcessGetMonitorInfoReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq); +int32_t vmProcessGetLoadsReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq); // vmFile.c -int32_t vmGetVnodeListFromFile(SVnodesMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes); -int32_t vmWriteVnodeListToFile(SVnodesMgmt *pMgmt); -SVnodeObj **vmGetVnodeListFromHash(SVnodesMgmt *pMgmt, int32_t *numOfVnodes); +int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes); +int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt); +SVnodeObj **vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes); // vmWorker.c -int32_t vmStartWorker(SVnodesMgmt *pMgmt); -void vmStopWorker(SVnodesMgmt *pMgmt); -int32_t vmAllocQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode); -void vmFreeQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode); +int32_t vmStartWorker(SVnodeMgmt *pMgmt); +void vmStopWorker(SVnodeMgmt *pMgmt); +int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode); +void vmFreeQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode); -int32_t vmPutMsgToWriteQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmPutMsgToSyncQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmPutMsgToApplyQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmPutMsgToFetchQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmPutMsgToMergeQueue(SMgmtWrapper *pWrapper, SRpcMsg *pMsg); -int32_t vmGetQueueSize(SMgmtWrapper *pWrapper, int32_t vgId, EQueueType qtype); +int32_t vmPutRpcMsgToWriteQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutRpcMsgToSyncQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutRpcMsgToApplyQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutRpcMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutRpcMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutRpcMsgToMergeQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmGetQueueSize(SVnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype); -int32_t vmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t vmProcessSyncMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t vmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t vmProcessFetchMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t vmProcessMergeMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); -int32_t vmProcessMgmtMsg(SMgmtWrapper *pWrappert, SNodeMsg *pMsg); -int32_t vmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToWriteQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToSyncQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToQueryQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToFetchQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToMergeQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToMgmtQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); +int32_t vmPutNodeMsgToMonitorQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg); #ifdef __cplusplus } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c index f251dd120e..f6c7bb33e6 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmFile.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmFile.c @@ -16,7 +16,7 @@ #define _DEFAULT_SOURCE #include "vmInt.h" -SVnodeObj **vmGetVnodeListFromHash(SVnodesMgmt *pMgmt, int32_t *numOfVnodes) { +SVnodeObj **vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes) { taosRLockLatch(&pMgmt->latch); int32_t num = 0; @@ -44,10 +44,10 @@ SVnodeObj **vmGetVnodeListFromHash(SVnodesMgmt *pMgmt, int32_t *numOfVnodes) { return pVnodes; } -int32_t vmGetVnodeListFromFile(SVnodesMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) { +int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) { int32_t code = TSDB_CODE_INVALID_JSON_FORMAT; int32_t len = 0; - int32_t maxLen = 30000; + int32_t maxLen = 1024 * 1024; char *content = taosMemoryCalloc(1, maxLen + 1); cJSON *root = NULL; FILE *fp = NULL; @@ -64,6 +64,11 @@ int32_t vmGetVnodeListFromFile(SVnodesMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t goto _OVER; } + if (content == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + len = (int32_t)taosReadFile(pFile, content, maxLen); if (len <= 0) { dError("failed to read %s since content is null", file); @@ -116,20 +121,6 @@ int32_t vmGetVnodeListFromFile(SVnodesMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t goto _OVER; } pCfg->vgVersion = vgVersion->valueint; - - cJSON *dbUid = cJSON_GetObjectItem(vnode, "dbUid"); - if (!dbUid || dbUid->type != cJSON_String) { - dError("failed to read %s since dbUid not found", file); - goto _OVER; - } - pCfg->dbUid = atoll(dbUid->valuestring); - - cJSON *db = cJSON_GetObjectItem(vnode, "db"); - if (!db || db->type != cJSON_String) { - dError("failed to read %s since db not found", file); - goto _OVER; - } - tstrncpy(pCfg->db, db->valuestring, TSDB_DB_FNAME_LEN); } *ppCfgs = pCfgs; @@ -148,9 +139,9 @@ _OVER: return code; } -int32_t vmWriteVnodeListToFile(SVnodesMgmt *pMgmt) { - char file[PATH_MAX]; - char realfile[PATH_MAX]; +int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) { + char file[PATH_MAX] = {0}; + char realfile[PATH_MAX] = {0}; snprintf(file, sizeof(file), "%s%svnodes.json.bak", pMgmt->path, TD_DIRSEP); snprintf(realfile, sizeof(file), "%s%svnodes.json", pMgmt->path, TD_DIRSEP); @@ -165,8 +156,12 @@ int32_t vmWriteVnodeListToFile(SVnodesMgmt *pMgmt) { SVnodeObj **pVnodes = vmGetVnodeListFromHash(pMgmt, &numOfVnodes); int32_t len = 0; - int32_t maxLen = 65536; + int32_t maxLen = 1024 * 1024; char *content = taosMemoryCalloc(1, maxLen + 1); + if (content == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } len += snprintf(content + len, maxLen - len, "{\n"); len += snprintf(content + len, maxLen - len, " \"vnodes\": [\n"); @@ -175,9 +170,7 @@ int32_t vmWriteVnodeListToFile(SVnodesMgmt *pMgmt) { len += snprintf(content + len, maxLen - len, " {\n"); len += snprintf(content + len, maxLen - len, " \"vgId\": %d,\n", pVnode->vgId); len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pVnode->dropped); - len += snprintf(content + len, maxLen - len, " \"vgVersion\": %d,\n", pVnode->vgVersion); - len += snprintf(content + len, maxLen - len, " \"dbUid\": \"%" PRIu64 "\",\n", pVnode->dbUid); - len += snprintf(content + len, maxLen - len, " \"db\": \"%s\"\n", pVnode->db); + len += snprintf(content + len, maxLen - len, " \"vgVersion\": %d\n", pVnode->vgVersion); if (i < numOfVnodes - 1) { len += snprintf(content + len, maxLen - len, " },\n"); } else { diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index 914acce2ea..0814568b73 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -16,9 +16,7 @@ #define _DEFAULT_SOURCE #include "vmInt.h" -void vmGetVnodeLoads(SMgmtWrapper *pWrapper, SMonVloadInfo *pInfo) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; - +static void vmGetVnodeLoads(SVnodeMgmt *pMgmt, SMonVloadInfo *pInfo) { pInfo->pVloads = taosArrayInit(pMgmt->state.totalVnodes, sizeof(SVnodeLoad)); if (pInfo->pVloads == NULL) return; @@ -39,11 +37,9 @@ void vmGetVnodeLoads(SMgmtWrapper *pWrapper, SMonVloadInfo *pInfo) { taosRUnLockLatch(&pMgmt->latch); } -void vmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonVmInfo *pInfo) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; - +static void vmGetMonitorInfo(SVnodeMgmt *pMgmt, SMonVmInfo *pInfo) { SMonVloadInfo vloads = {0}; - vmGetVnodeLoads(pWrapper, &vloads); + vmGetVnodeLoads(pMgmt, &vloads); SArray *pVloads = vloads.pVloads; if (pVloads == NULL) return; @@ -86,10 +82,10 @@ void vmGetMonitorInfo(SMgmtWrapper *pWrapper, SMonVmInfo *pInfo) { taosArrayDestroy(pVloads); } -int32_t vmProcessGetMonVmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t vmProcessGetMonitorInfoReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonVmInfo vmInfo = {0}; - vmGetMonitorInfo(pWrapper, &vmInfo); - dmGetMonitorSysInfo(&vmInfo.sys); + vmGetMonitorInfo(pMgmt, &vmInfo); + dmGetMonitorSystemInfo(&vmInfo.sys); monGetLogs(&vmInfo.log); int32_t rspLen = tSerializeSMonVmInfo(NULL, 0, &vmInfo); @@ -111,9 +107,9 @@ int32_t vmProcessGetMonVmInfoReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { return 0; } -int32_t vmProcessGetVnodeLoadsReq(SMgmtWrapper *pWrapper, SNodeMsg *pReq) { +int32_t vmProcessGetLoadsReq(SVnodeMgmt *pMgmt, SNodeMsg *pReq) { SMonVloadInfo vloads = {0}; - vmGetVnodeLoads(pWrapper, &vloads); + vmGetVnodeLoads(pMgmt, &vloads); int32_t rspLen = tSerializeSMonVloadInfo(NULL, 0, &vloads); if (rspLen < 0) { @@ -170,16 +166,14 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) { } } -static void vmGenerateWrapperCfg(SVnodesMgmt *pMgmt, SCreateVnodeReq *pCreate, SWrapperCfg *pCfg) { +static void vmGenerateWrapperCfg(SVnodeMgmt *pMgmt, SCreateVnodeReq *pCreate, SWrapperCfg *pCfg) { pCfg->vgId = pCreate->vgId; pCfg->vgVersion = pCreate->vgVersion; pCfg->dropped = 0; - pCfg->dbUid = pCreate->dbUid; - tstrncpy(pCfg->db, pCreate->db, TSDB_DB_FNAME_LEN); snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCreate->vgId); } -int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) { +int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SCreateVnodeReq createReq = {0}; int32_t code = -1; @@ -214,19 +208,10 @@ int32_t vmProcessCreateVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) { return -1; } - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - msgCb.queueFps[WRITE_QUEUE] = vmPutMsgToWriteQueue; - msgCb.queueFps[SYNC_QUEUE] = vmPutMsgToSyncQueue; - msgCb.queueFps[APPLY_QUEUE] = vmPutMsgToApplyQueue; - msgCb.queueFps[QUERY_QUEUE] = vmPutMsgToQueryQueue; - msgCb.queueFps[FETCH_QUEUE] = vmPutMsgToFetchQueue; - msgCb.queueFps[MERGE_QUEUE] = vmPutMsgToMergeQueue; - msgCb.qsizeFp = vmGetQueueSize; - - SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, msgCb); + SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb); if (pImpl == NULL) { dError("vgId:%d, failed to create vnode since %s", createReq.vgId, terrstr()); + code = terrno; goto _OVER; } @@ -256,7 +241,7 @@ _OVER: return code; } -int32_t vmProcessDropVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) { +int32_t vmProcessDropVnodeReq(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { SRpcMsg *pReq = &pMsg->rpcMsg; SDropVnodeReq dropReq = {0}; if (tDeserializeSDropVnodeReq(pReq->pCont, pReq->contLen, &dropReq) != 0) { @@ -287,57 +272,71 @@ int32_t vmProcessDropVnodeReq(SVnodesMgmt *pMgmt, SNodeMsg *pMsg) { return 0; } -void vmInitMsgHandle(SMgmtWrapper *pWrapper) { - dmSetMsgHandle(pWrapper, TDMT_MON_VM_INFO, vmProcessMonitorMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_MON_VM_LOAD, vmProcessMonitorMsg, DEFAULT_HANDLE); +SArray *vmGetMsgHandles() { + int32_t code = -1; + SArray *pArray = taosArrayInit(32, sizeof(SMgmtHandle)); + if (pArray == NULL) goto _OVER; + + if (dmSetMgmtHandle(pArray, TDMT_MON_VM_INFO, vmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_MON_VM_LOAD, vmPutNodeMsgToMonitorQueue, 0) == NULL) goto _OVER; // Requests handled by VNODE - dmSetMsgHandle(pWrapper, TDMT_VND_SUBMIT, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY, vmProcessQueryMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_CONTINUE, vmProcessQueryMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_FETCH, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_TABLE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_UPDATE_TAG_VAL, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TABLE_META, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TABLES_META, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_CONSUME, vmProcessQueryMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_QUERY, vmProcessQueryMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_CONNECT, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_DISCONNECT, vmProcessWriteMsg, DEFAULT_HANDLE); - // dmSetMsgHandle(pWrapper, TDMT_VND_MQ_SET_CUR, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_RES_READY, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASKS_STATUS, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CANCEL_TASK, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_TASK, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_STB, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_STB, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_STB, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_TABLE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_TABLE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CREATE_SMA, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CANCEL_SMA, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_DROP_SMA, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SUBMIT_RSMA, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_MQ_VG_CHANGE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_CONSUME, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASK_DEPLOY, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_QUERY_HEARTBEAT, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASK_PIPE_EXEC, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASK_MERGE_EXEC, vmProcessMergeMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_TASK_WRITE_EXEC, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_STREAM_TRIGGER, vmProcessFetchMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_ALTER_VNODE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_COMPACT_VNODE, vmProcessWriteMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_CREATE_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_DND_DROP_VNODE, vmProcessMgmtMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_SUBMIT, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY, vmPutNodeMsgToQueryQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_CONTINUE, vmPutNodeMsgToQueryQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_TABLE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_UPDATE_TAG_VAL, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TABLE_META, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TABLES_META, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_CONSUME, vmPutNodeMsgToQueryQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_QUERY, vmPutNodeMsgToQueryQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_CONNECT, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_DISCONNECT, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + // if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_SET_CUR, vmPutNodeMsgToWriteQueue, 0)== NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_RES_READY, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASKS_STATUS, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CANCEL_TASK, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TASK, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_STB, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_STB, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_STB, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_TABLE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CREATE_SMA, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CANCEL_SMA, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_SMA, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SUBMIT_RSMA, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_MQ_VG_CHANGE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_CONSUME, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_DEPLOY, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_HEARTBEAT, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_PIPE_EXEC, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_MERGE_EXEC, vmPutNodeMsgToMergeQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_TASK_WRITE_EXEC, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutNodeMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_VNODE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_COMPACT_VNODE, vmPutNodeMsgToWriteQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE, vmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE, vmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER; - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_TIMEOUT, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_PING, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_PING_REPLY, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_CLIENT_REQUEST, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_CLIENT_REQUEST_REPLY, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_REQUEST_VOTE, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_REQUEST_VOTE_REPLY, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_APPEND_ENTRIES, vmProcessSyncMsg, DEFAULT_HANDLE); - dmSetMsgHandle(pWrapper, TDMT_VND_SYNC_APPEND_ENTRIES_REPLY, vmProcessSyncMsg, DEFAULT_HANDLE); + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_TIMEOUT, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_PING, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_PING_REPLY, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_CLIENT_REQUEST, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_CLIENT_REQUEST_REPLY, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_REQUEST_VOTE, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_REQUEST_VOTE_REPLY, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_APPEND_ENTRIES, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_SYNC_APPEND_ENTRIES_REPLY, vmPutNodeMsgToSyncQueue, 0) == NULL) goto _OVER; + + code = 0; + +_OVER: + if (code != 0) { + taosArrayDestroy(pArray); + return NULL; + } else { + return pArray; + } } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index af439fcc03..635467559e 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -16,7 +16,7 @@ #define _DEFAULT_SOURCE #include "vmInt.h" -SVnodeObj *vmAcquireVnode(SVnodesMgmt *pMgmt, int32_t vgId) { +SVnodeObj *vmAcquireVnode(SVnodeMgmt *pMgmt, int32_t vgId) { SVnodeObj *pVnode = NULL; int32_t refCount = 0; @@ -36,7 +36,7 @@ SVnodeObj *vmAcquireVnode(SVnodesMgmt *pMgmt, int32_t vgId) { return pVnode; } -void vmReleaseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { +void vmReleaseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { if (pVnode == NULL) return; taosRLockLatch(&pMgmt->latch); @@ -45,7 +45,7 @@ void vmReleaseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { dTrace("vgId:%d, release vnode, refCount:%d", pVnode->vgId, refCount); } -int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) { +int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) { SVnodeObj *pVnode = taosMemoryCalloc(1, sizeof(SVnodeObj)); if (pVnode == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -57,13 +57,10 @@ int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) { pVnode->vgVersion = pCfg->vgVersion; pVnode->dropped = 0; pVnode->accessState = TSDB_VN_ALL_ACCCESS; - pVnode->dbUid = pCfg->dbUid; - pVnode->db = tstrdup(pCfg->db); pVnode->path = tstrdup(pCfg->path); pVnode->pImpl = pImpl; - pVnode->pWrapper = pMgmt->pWrapper; - if (pVnode->path == NULL || pVnode->db == NULL) { + if (pVnode->path == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -80,7 +77,7 @@ int32_t vmOpenVnode(SVnodesMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) { return code; } -void vmCloseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { +void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { char path[TSDB_FILENAME_LEN] = {0}; taosWLockLatch(&pMgmt->latch); @@ -109,14 +106,12 @@ void vmCloseVnode(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { } taosMemoryFree(pVnode->path); - taosMemoryFree(pVnode->db); taosMemoryFree(pVnode); } static void *vmOpenVnodeInThread(void *param) { SVnodeThread *pThread = param; - SVnodesMgmt *pMgmt = pThread->pMgmt; - SDnode *pDnode = pMgmt->pDnode; + SVnodeMgmt *pMgmt = pThread->pMgmt; char path[TSDB_FILENAME_LEN]; dDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum); @@ -128,19 +123,10 @@ static void *vmOpenVnodeInThread(void *param) { char stepDesc[TSDB_STEP_DESC_LEN] = {0}; snprintf(stepDesc, TSDB_STEP_DESC_LEN, "vgId:%d, start to restore, %d of %d have been opened", pCfg->vgId, pMgmt->state.openVnodes, pMgmt->state.totalVnodes); - dmReportStartup(pDnode, "vnode-open", stepDesc); + tmsgReportStartup("vnode-open", stepDesc); - SMsgCb msgCb = pMgmt->pDnode->data.msgCb; - msgCb.pWrapper = pMgmt->pWrapper; - msgCb.queueFps[WRITE_QUEUE] = vmPutMsgToWriteQueue; - msgCb.queueFps[SYNC_QUEUE] = vmPutMsgToSyncQueue; - msgCb.queueFps[APPLY_QUEUE] = vmPutMsgToApplyQueue; - msgCb.queueFps[QUERY_QUEUE] = vmPutMsgToQueryQueue; - msgCb.queueFps[FETCH_QUEUE] = vmPutMsgToFetchQueue; - msgCb.queueFps[MERGE_QUEUE] = vmPutMsgToMergeQueue; - msgCb.qsizeFp = vmGetQueueSize; snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, pCfg->vgId); - SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, msgCb); + SVnode *pImpl = vnodeOpen(path, pMgmt->pTfs, pMgmt->msgCb); if (pImpl == NULL) { dError("vgId:%d, failed to open vnode by thread:%d", pCfg->vgId, pThread->threadIndex); pThread->failed++; @@ -157,9 +143,7 @@ static void *vmOpenVnodeInThread(void *param) { return NULL; } -static int32_t vmOpenVnodes(SVnodesMgmt *pMgmt) { - SDnode *pDnode = pMgmt->pDnode; - +static int32_t vmOpenVnodes(SVnodeMgmt *pMgmt) { pMgmt->hash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); if (pMgmt->hash == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -227,7 +211,7 @@ static int32_t vmOpenVnodes(SVnodesMgmt *pMgmt) { } } -static void vmCloseVnodes(SVnodesMgmt *pMgmt) { +static void vmCloseVnodes(SVnodeMgmt *pMgmt) { dInfo("start to close all vnodes"); int32_t numOfVnodes = 0; @@ -249,40 +233,44 @@ static void vmCloseVnodes(SVnodesMgmt *pMgmt) { dInfo("total vnodes:%d are all closed", numOfVnodes); } -static void vmCleanup(SMgmtWrapper *pWrapper) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; - if (pMgmt == NULL) return; - +static void vmCleanup(SVnodeMgmt *pMgmt) { dInfo("vnode-mgmt start to cleanup"); vmCloseVnodes(pMgmt); vmStopWorker(pMgmt); vnodeCleanup(); tfsClose(pMgmt->pTfs); taosMemoryFree(pMgmt); - pWrapper->pMgmt = NULL; dInfo("vnode-mgmt is cleaned up"); } -static int32_t vmInit(SMgmtWrapper *pWrapper) { - SDnode *pDnode = pWrapper->pDnode; - SVnodesMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SVnodesMgmt)); - int32_t code = -1; - +static int32_t vmInit(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput) { dInfo("vnode-mgmt start to init"); + int32_t code = -1; + + SVnodeMgmt *pMgmt = taosMemoryCalloc(1, sizeof(SVnodeMgmt)); if (pMgmt == NULL) goto _OVER; - pMgmt->path = pWrapper->path; - pMgmt->pDnode = pWrapper->pDnode; - pMgmt->pWrapper = pWrapper; + pMgmt->path = pInput->path; + pMgmt->name = pInput->name; + pMgmt->dnodeId = pInput->dnodeId; + pMgmt->msgCb = pInput->msgCb; + pMgmt->msgCb.queueFps[WRITE_QUEUE] = (PutToQueueFp)vmPutRpcMsgToWriteQueue; + pMgmt->msgCb.queueFps[SYNC_QUEUE] = (PutToQueueFp)vmPutRpcMsgToSyncQueue; + pMgmt->msgCb.queueFps[APPLY_QUEUE] = (PutToQueueFp)vmPutRpcMsgToApplyQueue; + pMgmt->msgCb.queueFps[QUERY_QUEUE] = (PutToQueueFp)vmPutRpcMsgToQueryQueue; + pMgmt->msgCb.queueFps[FETCH_QUEUE] = (PutToQueueFp)vmPutRpcMsgToFetchQueue; + pMgmt->msgCb.queueFps[MERGE_QUEUE] = (PutToQueueFp)vmPutRpcMsgToMergeQueue; + pMgmt->msgCb.qsizeFp = (GetQueueSizeFp)vmGetQueueSize; + pMgmt->msgCb.pMgmt = pMgmt; taosInitRWLatch(&pMgmt->latch); SDiskCfg dCfg = {0}; - tstrncpy(dCfg.dir, pDnode->data.dataDir, TSDB_FILENAME_LEN); + tstrncpy(dCfg.dir, pInput->dataDir, TSDB_FILENAME_LEN); dCfg.level = 0; dCfg.primary = 1; - SDiskCfg *pDisks = pDnode->data.disks; - int32_t numOfDisks = pDnode->data.numOfDisks; + SDiskCfg *pDisks = pInput->disks; + int32_t numOfDisks = pInput->numOfDisks; if (numOfDisks <= 0 || pDisks == NULL) { pDisks = &dCfg; numOfDisks = 1; @@ -293,64 +281,64 @@ static int32_t vmInit(SMgmtWrapper *pWrapper) { dError("failed to init tfs since %s", terrstr()); goto _OVER; } - dmReportStartup(pDnode, "vnode-tfs", "initialized"); + tmsgReportStartup("vnode-tfs", "initialized"); if (walInit() != 0) { dError("failed to init wal since %s", terrstr()); goto _OVER; } - dmReportStartup(pDnode, "vnode-wal", "initialized"); + tmsgReportStartup("vnode-wal", "initialized"); if (syncInit() != 0) { dError("failed to open sync since %s", terrstr()); - return -1; + goto _OVER; } + tmsgReportStartup("vnode-sync", "initialized"); if (vnodeInit(tsNumOfCommitThreads) != 0) { dError("failed to init vnode since %s", terrstr()); goto _OVER; } - dmReportStartup(pDnode, "vnode-commit", "initialized"); + tmsgReportStartup("vnode-commit", "initialized"); if (vmStartWorker(pMgmt) != 0) { - dError("failed to init workers since %s", terrstr()) goto _OVER; + dError("failed to init workers since %s", terrstr()); + goto _OVER; } - dmReportStartup(pDnode, "vnode-worker", "initialized"); + tmsgReportStartup("vnode-worker", "initialized"); if (vmOpenVnodes(pMgmt) != 0) { dError("failed to open vnode since %s", terrstr()); - return -1; + goto _OVER; } - dmReportStartup(pDnode, "vnode-vnodes", "initialized"); + tmsgReportStartup("vnode-vnodes", "initialized"); if (udfcOpen() != 0) { dError("failed to open udfc in vnode"); + goto _OVER; } code = 0; _OVER: if (code == 0) { - pWrapper->pMgmt = pMgmt; + pOutput->pMgmt = pMgmt; dInfo("vnodes-mgmt is initialized"); } else { dError("failed to init vnodes-mgmt since %s", terrstr()); - vmCleanup(pWrapper); + vmCleanup(pMgmt); } + return code; +} + +static int32_t vmRequire(const SMgmtInputOpt *pInput, bool *required) { + *required = pInput->supportVnodes > 0; return 0; } -static int32_t vmRequire(SMgmtWrapper *pWrapper, bool *required) { - SDnode *pDnode = pWrapper->pDnode; - *required = pDnode->data.supportVnodes > 0; - return 0; -} - -static int32_t vmStart(SMgmtWrapper *pWrapper) { +static int32_t vmStart(SVnodeMgmt *pMgmt) { dDebug("vnode-mgmt start to run"); - SVnodesMgmt *pMgmt = pWrapper->pMgmt; - taosRLockLatch(&pMgmt->latch); void *pIter = taosHashIterate(pMgmt->hash, NULL); @@ -367,20 +355,18 @@ static int32_t vmStart(SMgmtWrapper *pWrapper) { return 0; } -static void vmStop(SMgmtWrapper *pWrapper) { +static void vmStop(SVnodeMgmt *pMgmt) { // process inside the vnode } -void vmSetMgmtFp(SMgmtWrapper *pWrapper) { - SMgmtFp mgmtFp = {0}; - mgmtFp.openFp = vmInit; - mgmtFp.closeFp = vmCleanup; - mgmtFp.startFp = vmStart; - mgmtFp.stopFp = vmStop; - mgmtFp.requiredFp = vmRequire; +SMgmtFunc vmGetMgmtFunc() { + SMgmtFunc mgmtFunc = {0}; + mgmtFunc.openFp = vmInit; + mgmtFunc.closeFp = (NodeCloseFp)vmCleanup; + mgmtFunc.startFp = (NodeStartFp)vmStart; + mgmtFunc.stopFp = (NodeStopFp)vmStop; + mgmtFunc.requiredFp = vmRequire; + mgmtFunc.getHandlesFp = vmGetMsgHandles; - vmInitMsgHandle(pWrapper); - pWrapper->name = "vnode"; - pWrapper->fp = mgmtFp; + return mgmtFunc; } - diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c index 2baa8b8942..cf8f4d5010 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -32,7 +32,7 @@ static inline void vmSendRsp(SNodeMsg *pMsg, int32_t code) { } static void vmProcessMgmtMonitorQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pInfo->ahandle; + SVnodeMgmt *pMgmt = pInfo->ahandle; int32_t code = -1; tmsg_t msgType = pMsg->rpcMsg.msgType; @@ -40,10 +40,10 @@ static void vmProcessMgmtMonitorQueue(SQueueInfo *pInfo, SNodeMsg *pMsg) { switch (msgType) { case TDMT_MON_VM_INFO: - code = vmProcessGetMonVmInfoReq(pMgmt->pWrapper, pMsg); + code = vmProcessGetMonitorInfoReq(pMgmt, pMsg); break; case TDMT_MON_VM_LOAD: - code = vmProcessGetVnodeLoadsReq(pMgmt->pWrapper, pMsg); + code = vmProcessGetLoadsReq(pMgmt, pMsg); break; case TDMT_DND_CREATE_VNODE: code = vmProcessCreateVnodeReq(pMgmt, pMsg); @@ -240,7 +240,7 @@ static void vmProcessMergeQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO } } -static int32_t vmPutNodeMsgToQueue(SVnodesMgmt *pMgmt, SNodeMsg *pMsg, EQueueType qtype) { +static int32_t vmPutNodeMsgToQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg, EQueueType qtype) { SRpcMsg *pRpc = &pMsg->rpcMsg; SMsgHead *pHead = pRpc->pCont; int32_t code = 0; @@ -285,41 +285,34 @@ static int32_t vmPutNodeMsgToQueue(SVnodesMgmt *pMgmt, SNodeMsg *pMsg, EQueueTyp return code; } -int32_t vmProcessSyncMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToSyncQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { return vmPutNodeMsgToQueue(pMgmt, pMsg, SYNC_QUEUE); } -int32_t vmProcessWriteMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToWriteQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { return vmPutNodeMsgToQueue(pMgmt, pMsg, WRITE_QUEUE); } -int32_t vmProcessQueryMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToQueryQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { return vmPutNodeMsgToQueue(pMgmt, pMsg, QUERY_QUEUE); } -int32_t vmProcessFetchMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToFetchQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { return vmPutNodeMsgToQueue(pMgmt, pMsg, FETCH_QUEUE); } -int32_t vmProcessMergeMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToMergeQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { return vmPutNodeMsgToQueue(pMgmt, pMsg, MERGE_QUEUE); } -int32_t vmProcessMgmtMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToMgmtQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { SSingleWorker *pWorker = &pMgmt->mgmtWorker; dTrace("msg:%p, will be put into vnode-mgmt queue, worker:%s", pMsg, pWorker->name); taosWriteQitem(pWorker->queue, pMsg); return 0; } -int32_t vmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; +int32_t vmPutNodeMsgToMonitorQueue(SVnodeMgmt *pMgmt, SNodeMsg *pMsg) { SSingleWorker *pWorker = &pMgmt->monitorWorker; dTrace("msg:%p, will be put into vnode-monitor queue, worker:%s", pMsg, pWorker->name); @@ -327,9 +320,8 @@ int32_t vmProcessMonitorMsg(SMgmtWrapper *pWrapper, SNodeMsg *pMsg) { return 0; } -static int32_t vmPutRpcMsgToQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, EQueueType qtype) { - SVnodesMgmt *pMgmt = pWrapper->pMgmt; - SMsgHead *pHead = pRpc->pCont; +static int32_t vmPutRpcMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc, EQueueType qtype) { + SMsgHead *pHead = pRpc->pCont; SVnodeObj *pVnode = vmAcquireVnode(pMgmt, pHead->vgId); if (pVnode == NULL) return -1; @@ -377,33 +369,31 @@ static int32_t vmPutRpcMsgToQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, EQueueT return code; } -int32_t vmPutMsgToWriteQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, WRITE_QUEUE); +int32_t vmPutRpcMsgToWriteQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { + return vmPutRpcMsgToQueue(pMgmt, pRpc, WRITE_QUEUE); } -int32_t vmPutMsgToSyncQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, SYNC_QUEUE); +int32_t vmPutRpcMsgToSyncQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { return vmPutRpcMsgToQueue(pMgmt, pRpc, SYNC_QUEUE); } + +int32_t vmPutRpcMsgToApplyQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { + return vmPutRpcMsgToQueue(pMgmt, pRpc, APPLY_QUEUE); } -int32_t vmPutMsgToApplyQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, APPLY_QUEUE); +int32_t vmPutRpcMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { + return vmPutRpcMsgToQueue(pMgmt, pRpc, QUERY_QUEUE); } -int32_t vmPutMsgToQueryQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, QUERY_QUEUE); +int32_t vmPutRpcMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { + return vmPutRpcMsgToQueue(pMgmt, pRpc, FETCH_QUEUE); } -int32_t vmPutMsgToFetchQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, FETCH_QUEUE); +int32_t vmPutRpcMsgToMergeQueue(SVnodeMgmt *pMgmt, SRpcMsg *pRpc) { + return vmPutRpcMsgToQueue(pMgmt, pRpc, MERGE_QUEUE); } -int32_t vmPutMsgToMergeQueue(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { - return vmPutRpcMsgToQueue(pWrapper, pRpc, MERGE_QUEUE); -} - -int32_t vmGetQueueSize(SMgmtWrapper *pWrapper, int32_t vgId, EQueueType qtype) { +int32_t vmGetQueueSize(SVnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype) { int32_t size = -1; - SVnodeObj *pVnode = vmAcquireVnode(pWrapper->pMgmt, vgId); + SVnodeObj *pVnode = vmAcquireVnode(pMgmt, vgId); if (pVnode != NULL) { switch (qtype) { case WRITE_QUEUE: @@ -428,11 +418,11 @@ int32_t vmGetQueueSize(SMgmtWrapper *pWrapper, int32_t vgId, EQueueType qtype) { break; } } - vmReleaseVnode(pWrapper->pMgmt, pVnode); + vmReleaseVnode(pMgmt, pVnode); return size; } -int32_t vmAllocQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { +int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { pVnode->pWriteQ = tWWorkerAllocQueue(&pMgmt->writePool, pVnode, (FItems)vmProcessWriteQueue); pVnode->pSyncQ = tWWorkerAllocQueue(&pMgmt->syncPool, pVnode, (FItems)vmProcessSyncQueue); pVnode->pApplyQ = tWWorkerAllocQueue(&pMgmt->writePool, pVnode, (FItems)vmProcessApplyQueue); @@ -450,7 +440,7 @@ int32_t vmAllocQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { return 0; } -void vmFreeQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { +void vmFreeQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { tWWorkerFreeQueue(&pMgmt->writePool, pVnode->pWriteQ); tWWorkerFreeQueue(&pMgmt->syncPool, pVnode->pSyncQ); tWWorkerFreeQueue(&pMgmt->writePool, pVnode->pApplyQ); @@ -466,7 +456,7 @@ void vmFreeQueue(SVnodesMgmt *pMgmt, SVnodeObj *pVnode) { dDebug("vgId:%d, vnode queue is freed", pVnode->vgId); } -int32_t vmStartWorker(SVnodesMgmt *pMgmt) { +int32_t vmStartWorker(SVnodeMgmt *pMgmt) { SQWorkerPool *pQPool = &pMgmt->queryPool; pQPool->name = "vnode-query"; pQPool->min = tsNumOfVnodeQueryThreads; @@ -506,25 +496,23 @@ int32_t vmStartWorker(SVnodesMgmt *pMgmt) { return -1; } - if (tsMultiProcess) { - SSingleWorkerCfg mCfg = { - .min = 1, - .max = 1, - .name = "vnode-monitor", - .fp = (FItem)vmProcessMgmtMonitorQueue, - .param = pMgmt, - }; - if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { - dError("failed to start mnode vnode-monitor worker since %s", terrstr()); - return -1; - } + SSingleWorkerCfg mCfg = { + .min = 1, + .max = 1, + .name = "vnode-monitor", + .fp = (FItem)vmProcessMgmtMonitorQueue, + .param = pMgmt, + }; + if (tSingleWorkerInit(&pMgmt->monitorWorker, &mCfg) != 0) { + dError("failed to start mnode vnode-monitor worker since %s", terrstr()); + return -1; } dDebug("vnode workers are initialized"); return 0; } -void vmStopWorker(SVnodesMgmt *pMgmt) { +void vmStopWorker(SVnodeMgmt *pMgmt) { tSingleWorkerCleanup(&pMgmt->monitorWorker); tSingleWorkerCleanup(&pMgmt->mgmtWorker); tWWorkerCleanup(&pMgmt->writePool); diff --git a/source/dnode/mgmt/implement/CMakeLists.txt b/source/dnode/mgmt/node_mgmt/CMakeLists.txt similarity index 94% rename from source/dnode/mgmt/implement/CMakeLists.txt rename to source/dnode/mgmt/node_mgmt/CMakeLists.txt index fbe7530395..98027d80d4 100644 --- a/source/dnode/mgmt/implement/CMakeLists.txt +++ b/source/dnode/mgmt/node_mgmt/CMakeLists.txt @@ -1,9 +1,9 @@ aux_source_directory(src IMPLEMENT_SRC) add_library(dnode STATIC ${IMPLEMENT_SRC}) target_link_libraries( - dnode mgmt_bnode mgmt_mnode mgmt_qnode mgmt_snode mgmt_vnode + dnode mgmt_bnode mgmt_mnode mgmt_qnode mgmt_snode mgmt_vnode mgmt_dnode ) target_include_directories( dnode PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" -) \ No newline at end of file +) diff --git a/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h b/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h new file mode 100644 index 0000000000..d717408fc6 --- /dev/null +++ b/source/dnode/mgmt/node_mgmt/inc/dmMgmt.h @@ -0,0 +1,133 @@ +/* + * 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_DND_IMP_H_ +#define _TD_DND_IMP_H_ + +// tobe deleted +#include "uv.h" + +#include "dmUtil.h" +#include "dmInt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SMgmtWrapper { + SDnode *pDnode; + SMgmtFunc func; + void *pMgmt; + const char *name; + char *path; + int32_t refCount; + SRWLatch latch; + EDndNodeType nodeType; + bool deployed; + bool required; + EDndProcType procType; + int32_t procId; + SProcObj *procObj; + SShm procShm; + NodeMsgFp msgFps[TDMT_MAX]; +} SMgmtWrapper; + +typedef struct { + EDndNodeType defaultNtype; + bool needCheckVgId; +} SMsgHandle; + +typedef struct { + void *serverRpc; + void *clientRpc; + SMsgHandle msgHandles[TDMT_MAX]; +} SDnodeTrans; + +typedef struct { + char name[TSDB_STEP_NAME_LEN]; + char desc[TSDB_STEP_DESC_LEN]; +} SStartupInfo; + +typedef struct SUdfdData { + bool startCalled; + bool needCleanUp; + uv_loop_t loop; + uv_thread_t thread; + uv_barrier_t barrier; + uv_process_t process; + int spawnErr; + uv_pipe_t ctrlPipe; + uv_async_t stopAsync; + int32_t stopCalled; + int32_t dnodeId; +} SUdfdData; + +typedef struct SDnode { + EDndProcType ptype; + EDndNodeType ntype; + EDndEvent event; + EDndRunStatus status; + SStartupInfo startup; + SDnodeTrans trans; + SUdfdData udfdData; + TdThreadMutex mutex; + SRWLatch latch; + SEpSet mnodeEps; + TdFilePtr lockfile; + SMgmtInputOpt input; + SMgmtWrapper wrappers[NODE_END]; +} SDnode; + +// dmExec.c +int32_t dmOpenNode(SMgmtWrapper *pWrapper); +void dmCloseNode(SMgmtWrapper *pWrapper); + +// dmObj.c +SMgmtWrapper *dmAcquireWrapper(SDnode *pDnode, EDndNodeType nType); +int32_t dmMarkWrapper(SMgmtWrapper *pWrapper); +void dmReleaseWrapper(SMgmtWrapper *pWrapper); + +void dmSetStatus(SDnode *pDnode, EDndRunStatus stype); +void dmSetEvent(SDnode *pDnode, EDndEvent event); +void dmReportStartup(SDnode *pDnode, const char *pName, const char *pDesc); +void dmReportStartupByWrapper(SMgmtWrapper *pWrapper, const char *pName, const char *pDesc); + +void dmProcessServerStartupStatus(SDnode *pDnode, SRpcMsg *pMsg); +void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pMsg); +int32_t dmProcessCreateNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); +int32_t dmProcessDropNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); + +// dmTransport.c +int32_t dmInitServer(SDnode *pDnode); +void dmCleanupServer(SDnode *pDnode); +int32_t dmInitClient(SDnode *pDnode); +void dmCleanupClient(SDnode *pDnode); +SProcCfg dmGenProcCfg(SMgmtWrapper *pWrapper); +SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper); +int32_t dmInitMsgHandle(SDnode *pDnode); + +// mgmt nodes +SMgmtFunc dmGetMgmtFunc(); +SMgmtFunc bmGetMgmtFunc(); +SMgmtFunc qmGetMgmtFunc(); +SMgmtFunc smGetMgmtFunc(); +SMgmtFunc vmGetMgmtFunc(); +SMgmtFunc mmGetMgmtFunc(); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_DND_IMP_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/node_mgmt/src/dmMgmt.c b/source/dnode/mgmt/node_mgmt/src/dmMgmt.c new file mode 100644 index 0000000000..dbd861e6f7 --- /dev/null +++ b/source/dnode/mgmt/node_mgmt/src/dmMgmt.c @@ -0,0 +1,358 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmMgmt.h" + +static bool dmIsNodeDeployedFp(SDnode *pDnode, EDndNodeType ntype) { return pDnode->wrappers[ntype].required; } + +static int32_t dmInitVars(SDnode *pDnode, const SDnodeOpt *pOption) { + pDnode->input.dnodeId = 0; + pDnode->input.clusterId = 0; + pDnode->input.localEp = strdup(pOption->localEp); + pDnode->input.localFqdn = strdup(pOption->localFqdn); + pDnode->input.firstEp = strdup(pOption->firstEp); + pDnode->input.secondEp = strdup(pOption->secondEp); + pDnode->input.serverPort = pOption->serverPort; + pDnode->input.supportVnodes = pOption->numOfSupportVnodes; + pDnode->input.numOfDisks = pOption->numOfDisks; + pDnode->input.disks = pOption->disks; + pDnode->input.dataDir = strdup(pOption->dataDir); + pDnode->input.pDnode = pDnode; + pDnode->input.processCreateNodeFp = dmProcessCreateNodeReq; + pDnode->input.processDropNodeFp = dmProcessDropNodeReq; + pDnode->input.isNodeDeployedFp = dmIsNodeDeployedFp; + + if (pDnode->input.dataDir == NULL || pDnode->input.localEp == NULL || pDnode->input.localFqdn == NULL || + pDnode->input.firstEp == NULL || pDnode->input.secondEp == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + pDnode->ntype = pOption->ntype; + if (!tsMultiProcess || pDnode->ntype == DNODE || pDnode->ntype == NODE_END) { + pDnode->lockfile = dmCheckRunning(pOption->dataDir); + if (pDnode->lockfile == NULL) { + return -1; + } + } + + taosThreadMutexInit(&pDnode->mutex, NULL); + return 0; +} + +static void dmClearVars(SDnode *pDnode) { + for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + taosMemoryFreeClear(pWrapper->path); + } + if (pDnode->lockfile != NULL) { + taosUnLockFile(pDnode->lockfile); + taosCloseFile(&pDnode->lockfile); + pDnode->lockfile = NULL; + } + + taosMemoryFreeClear(pDnode->input.localEp); + taosMemoryFreeClear(pDnode->input.localFqdn); + taosMemoryFreeClear(pDnode->input.firstEp); + taosMemoryFreeClear(pDnode->input.secondEp); + taosMemoryFreeClear(pDnode->input.dataDir); + + taosThreadMutexDestroy(&pDnode->mutex); + memset(&pDnode->mutex, 0, sizeof(pDnode->mutex)); + taosMemoryFree(pDnode); + dDebug("dnode memory is cleared, data:%p", pDnode); +} + +static bool dmRequireNode(SMgmtWrapper *pWrapper) { + SMgmtInputOpt *pInput = &pWrapper->pDnode->input; + pInput->name = pWrapper->name; + pInput->path = pWrapper->path; + + bool required = false; + int32_t code = (*pWrapper->func.requiredFp)(pInput, &required); + if (!required) { + dDebug("node:%s, does not require startup", pWrapper->name); + } + return required; +} + +SDnode *dmCreate(const SDnodeOpt *pOption) { + dInfo("start to create dnode"); + int32_t code = -1; + char path[PATH_MAX + 100] = {0}; + SDnode *pDnode = NULL; + + pDnode = taosMemoryCalloc(1, sizeof(SDnode)); + if (pDnode == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + if (dmInitVars(pDnode, pOption) != 0) { + goto _OVER; + } + + dmSetStatus(pDnode, DND_STAT_INIT); + pDnode->wrappers[DNODE].func = dmGetMgmtFunc(); + pDnode->wrappers[MNODE].func = mmGetMgmtFunc(); + pDnode->wrappers[VNODE].func = vmGetMgmtFunc(); + pDnode->wrappers[QNODE].func = qmGetMgmtFunc(); + pDnode->wrappers[SNODE].func = smGetMgmtFunc(); + pDnode->wrappers[BNODE].func = bmGetMgmtFunc(); + + for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + pWrapper->pDnode = pDnode; + pWrapper->name = dmNodeName(ntype); + pWrapper->procShm.id = -1; + pWrapper->nodeType = ntype; + pWrapper->procType = DND_PROC_SINGLE; + taosInitRWLatch(&pWrapper->latch); + + snprintf(path, sizeof(path), "%s%s%s", pOption->dataDir, TD_DIRSEP, pWrapper->name); + pWrapper->path = strdup(path); + if (pWrapper->path == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + if (ntype != DNODE && dmReadShmFile(pWrapper->path, pWrapper->name, pDnode->ntype, &pWrapper->procShm) != 0) { + dError("node:%s, failed to read shm file since %s", pWrapper->name, terrstr()); + goto _OVER; + } + + pWrapper->required = dmRequireNode(pWrapper); + } + + if (dmInitMsgHandle(pDnode) != 0) { + dError("failed to init msg handles since %s", terrstr()); + goto _OVER; + } + + if (dmInitClient(pDnode) != 0) { + goto _OVER; + } + + dInfo("dnode is created, data:%p", pDnode); + code = 0; + +_OVER: + if (code != 0 && pDnode != NULL) { + dmClearVars(pDnode); + pDnode = NULL; + dError("failed to create dnode since %s", terrstr()); + } + + return pDnode; +} + +void dmClose(SDnode *pDnode) { + if (pDnode == NULL) return; + + dmCleanupClient(pDnode); + dmCleanupServer(pDnode); + + dmClearVars(pDnode); + dInfo("dnode is closed, data:%p", pDnode); +} + +void dmSetStatus(SDnode *pDnode, EDndRunStatus status) { + if (pDnode->status != status) { + dDebug("dnode status set from %s to %s", dmStatStr(pDnode->status), dmStatStr(status)); + pDnode->status = status; + } +} + +void dmSetEvent(SDnode *pDnode, EDndEvent event) { + if (event == DND_EVENT_STOP) { + pDnode->event = event; + } +} + +SMgmtWrapper *dmAcquireWrapper(SDnode *pDnode, EDndNodeType ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + SMgmtWrapper *pRetWrapper = pWrapper; + + taosRLockLatch(&pWrapper->latch); + if (pWrapper->deployed) { + int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1); + dTrace("node:%s, is acquired, refCount:%d", pWrapper->name, refCount); + } else { + terrno = TSDB_CODE_NODE_NOT_DEPLOYED; + pRetWrapper = NULL; + } + taosRUnLockLatch(&pWrapper->latch); + + return pRetWrapper; +} + +int32_t dmMarkWrapper(SMgmtWrapper *pWrapper) { + int32_t code = 0; + + taosRLockLatch(&pWrapper->latch); + if (pWrapper->deployed || (pWrapper->procType == DND_PROC_PARENT && pWrapper->required)) { + int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1); + dTrace("node:%s, is marked, refCount:%d", pWrapper->name, refCount); + } else { + terrno = TSDB_CODE_NODE_NOT_DEPLOYED; + code = -1; + } + taosRUnLockLatch(&pWrapper->latch); + + return code; +} + +void dmReleaseWrapper(SMgmtWrapper *pWrapper) { + if (pWrapper == NULL) return; + + taosRLockLatch(&pWrapper->latch); + int32_t refCount = atomic_sub_fetch_32(&pWrapper->refCount, 1); + taosRUnLockLatch(&pWrapper->latch); + dTrace("node:%s, is released, refCount:%d", pWrapper->name, refCount); +} + +void dmReportStartup(SDnode *pDnode, const char *pName, const char *pDesc) { + SStartupInfo *pStartup = &pDnode->startup; + tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN); + tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN); + dInfo("step:%s, %s", pStartup->name, pStartup->desc); +} + +void dmReportStartupByWrapper(SMgmtWrapper *pWrapper, const char *pName, const char *pDesc) { + dmReportStartup(pWrapper->pDnode, pName, pDesc); +} + +static void dmGetServerStartupStatus(SDnode *pDnode, SServerStatusRsp *pStatus) { + SDnodeMgmt *pMgmt = pDnode->wrappers[DNODE].pMgmt; + pStatus->details[0] = 0; + + if (pDnode->status == DND_STAT_INIT) { + pStatus->statusCode = TSDB_SRV_STATUS_NETWORK_OK; + snprintf(pStatus->details, sizeof(pStatus->details), "%s: %s", pDnode->startup.name, pDnode->startup.desc); + } else if (pDnode->status == DND_STAT_STOPPED) { + pStatus->statusCode = TSDB_SRV_STATUS_EXTING; + } else { + pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_OK; + } +} + +void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pReq) { + dDebug("net test req is received"); + SRpcMsg rsp = {.handle = pReq->handle, .refId = pReq->refId, .ahandle = pReq->ahandle, .code = 0}; + rsp.pCont = rpcMallocCont(pReq->contLen); + if (rsp.pCont == NULL) { + rsp.code = TSDB_CODE_OUT_OF_MEMORY; + } else { + rsp.contLen = pReq->contLen; + } + rpcSendResponse(&rsp); + rpcFreeCont(pReq->pCont); +} + +void dmProcessServerStartupStatus(SDnode *pDnode, SRpcMsg *pReq) { + dDebug("server startup status req is received"); + + SServerStatusRsp statusRsp = {0}; + dmGetServerStartupStatus(pDnode, &statusRsp); + + SRpcMsg rspMsg = {.handle = pReq->handle, .ahandle = pReq->ahandle, .refId = pReq->refId}; + int32_t rspLen = tSerializeSServerStatusRsp(NULL, 0, &statusRsp); + if (rspLen < 0) { + rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + void *pRsp = rpcMallocCont(rspLen); + if (pRsp == NULL) { + rspMsg.code = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + tSerializeSServerStatusRsp(pRsp, rspLen, &statusRsp); + rspMsg.pCont = pRsp; + rspMsg.contLen = rspLen; + +_OVER: + rpcSendResponse(&rspMsg); + rpcFreeCont(pReq->pCont); +} + +int32_t dmProcessCreateNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg) { + SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype); + if (pWrapper != NULL) { + dmReleaseWrapper(pWrapper); + terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED; + dError("failed to create node since %s", terrstr()); + return -1; + } + + taosThreadMutexLock(&pDnode->mutex); + pWrapper = &pDnode->wrappers[ntype]; + + if (taosMkDir(pWrapper->path) != 0) { + terrno = TAOS_SYSTEM_ERROR(errno); + dError("failed to create dir:%s since %s", pWrapper->path, terrstr()); + return -1; + } + + SMgmtInputOpt *pInput = &pWrapper->pDnode->input; + pInput->name = pWrapper->name; + pInput->path = pWrapper->path; + pInput->msgCb = dmGetMsgcb(pWrapper); + + int32_t code = (*pWrapper->func.createFp)(pInput, pMsg); + if (code != 0) { + dError("node:%s, failed to create since %s", pWrapper->name, terrstr()); + } else { + dDebug("node:%s, has been created", pWrapper->name); + (void)dmOpenNode(pWrapper); + pWrapper->required = true; + pWrapper->deployed = true; + pWrapper->procType = pDnode->ptype; + } + + taosThreadMutexUnlock(&pDnode->mutex); + return code; +} + +int32_t dmProcessDropNodeReq(SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg) { + SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype); + if (pWrapper == NULL) { + terrno = TSDB_CODE_NODE_NOT_DEPLOYED; + dError("failed to drop node since %s", terrstr()); + return -1; + } + + taosThreadMutexLock(&pDnode->mutex); + + int32_t code = (*pWrapper->func.dropFp)(pWrapper->pMgmt, pMsg); + if (code != 0) { + dError("node:%s, failed to drop since %s", pWrapper->name, terrstr()); + } else { + dDebug("node:%s, has been dropped", pWrapper->name); + pWrapper->required = false; + pWrapper->deployed = false; + } + + dmReleaseWrapper(pWrapper); + + if (code == 0) { + dmCloseNode(pWrapper); + taosRemoveDir(pWrapper->path); + } + taosThreadMutexUnlock(&pDnode->mutex); + return code; +} \ No newline at end of file diff --git a/source/dnode/mgmt/implement/src/dmExec.c b/source/dnode/mgmt/node_mgmt/src/dmRun.c similarity index 73% rename from source/dnode/mgmt/implement/src/dmExec.c rename to source/dnode/mgmt/node_mgmt/src/dmRun.c index 6999cee037..4d6290048a 100644 --- a/source/dnode/mgmt/implement/src/dmExec.c +++ b/source/dnode/mgmt/node_mgmt/src/dmRun.c @@ -14,34 +14,25 @@ */ #define _DEFAULT_SOURCE -#include "dmImp.h" - -static bool dmRequireNode(SMgmtWrapper *pWrapper) { - bool required = false; - int32_t code = (*pWrapper->fp.requiredFp)(pWrapper, &required); - if (!required) { - dDebug("node:%s, does not require startup", pWrapper->name); - } - return required; -} +#include "dmMgmt.h" static int32_t dmInitParentProc(SMgmtWrapper *pWrapper) { int32_t shmsize = tsMnodeShmSize; - if (pWrapper->ntype == VNODE) { + if (pWrapper->nodeType == VNODE) { shmsize = tsVnodeShmSize; - } else if (pWrapper->ntype == QNODE) { + } else if (pWrapper->nodeType == QNODE) { shmsize = tsQnodeShmSize; - } else if (pWrapper->ntype == SNODE) { + } else if (pWrapper->nodeType == SNODE) { shmsize = tsSnodeShmSize; - } else if (pWrapper->ntype == MNODE) { + } else if (pWrapper->nodeType == MNODE) { shmsize = tsMnodeShmSize; - } else if (pWrapper->ntype == BNODE) { + } else if (pWrapper->nodeType == BNODE) { shmsize = tsBnodeShmSize; } else { return -1; } - if (taosCreateShm(&pWrapper->procShm, pWrapper->ntype, shmsize) != 0) { + if (taosCreateShm(&pWrapper->procShm, pWrapper->nodeType, shmsize) != 0) { terrno = TAOS_SYSTEM_ERROR(terrno); dError("node:%s, failed to create shm size:%d since %s", pWrapper->name, shmsize, terrstr()); return -1; @@ -86,7 +77,7 @@ static int32_t dmRunParentProc(SMgmtWrapper *pWrapper) { if (pWrapper->pDnode->ntype == NODE_END) { dInfo("node:%s, should be started manually in child process", pWrapper->name); } else { - if (dmNewNodeProc(pWrapper, pWrapper->ntype) != 0) { + if (dmNewNodeProc(pWrapper, pWrapper->nodeType) != 0) { return -1; } } @@ -123,8 +114,17 @@ int32_t dmOpenNode(SMgmtWrapper *pWrapper) { return -1; } + SMgmtOutputOpt output = {0}; + SMgmtInputOpt *pInput = &pWrapper->pDnode->input; + pInput->name = pWrapper->name; + pInput->path = pWrapper->path; + pInput->msgCb = dmGetMsgcb(pWrapper); + if (pWrapper->nodeType == DNODE || pWrapper->procType == DND_PROC_CHILD) { + tmsgSetDefaultMsgCb(&pInput->msgCb); + } + if (pWrapper->procType == DND_PROC_SINGLE || pWrapper->procType == DND_PROC_CHILD) { - if ((*pWrapper->fp.openFp)(pWrapper) != 0) { + if ((*pWrapper->func.openFp)(pInput, &output) != 0) { dError("node:%s, failed to open since %s", pWrapper->name, terrstr()); return -1; } @@ -136,27 +136,39 @@ int32_t dmOpenNode(SMgmtWrapper *pWrapper) { pWrapper->deployed = true; } else { if (dmInitParentProc(pWrapper) != 0) return -1; - if (dmWriteShmFile(pWrapper) != 0) return -1; + if (dmWriteShmFile(pWrapper->path, pWrapper->name, &pWrapper->procShm) != 0) return -1; if (dmRunParentProc(pWrapper) != 0) return -1; } + if (output.dnodeId != 0) { + pInput->dnodeId = output.dnodeId; + } + if (output.pMgmt != NULL) { + pWrapper->pMgmt = output.pMgmt; + } + if (output.mnodeEps.numOfEps != 0) { + pWrapper->pDnode->mnodeEps = output.mnodeEps; + } + dmReportStartup(pWrapper->pDnode, pWrapper->name, "openned"); return 0; } int32_t dmStartNode(SMgmtWrapper *pWrapper) { + if (!pWrapper->required) return 0; + if (pWrapper->procType == DND_PROC_PARENT) { dInfo("node:%s, not start in parent process", pWrapper->name); } else if (pWrapper->procType == DND_PROC_CHILD) { dInfo("node:%s, start in child process", pWrapper->name); - if (pWrapper->ntype != DNODE) { - if (pWrapper->fp.startFp != NULL && (*pWrapper->fp.startFp)(pWrapper) != 0) { + if (pWrapper->nodeType != DNODE) { + if (pWrapper->func.startFp != NULL && (*pWrapper->func.startFp)(pWrapper->pMgmt) != 0) { dError("node:%s, failed to start since %s", pWrapper->name, terrstr()); return -1; } } } else { - if (pWrapper->fp.startFp != NULL && (*pWrapper->fp.startFp)(pWrapper) != 0) { + if (pWrapper->func.startFp != NULL && (*pWrapper->func.startFp)(pWrapper->pMgmt) != 0) { dError("node:%s, failed to start since %s", pWrapper->name, terrstr()); return -1; } @@ -167,8 +179,9 @@ int32_t dmStartNode(SMgmtWrapper *pWrapper) { } void dmStopNode(SMgmtWrapper *pWrapper) { - if (pWrapper->fp.stopFp != NULL) { - (*pWrapper->fp.stopFp)(pWrapper); + if (pWrapper->func.stopFp != NULL && pWrapper->pMgmt != NULL) { + (*pWrapper->func.stopFp)(pWrapper->pMgmt); + dDebug("node:%s, has been stopped", pWrapper->name); } } @@ -190,10 +203,11 @@ void dmCloseNode(SMgmtWrapper *pWrapper) { } } - dmStopNode(pWrapper); - taosWLockLatch(&pWrapper->latch); - (*pWrapper->fp.closeFp)(pWrapper); + if (pWrapper->pMgmt != NULL) { + (*pWrapper->func.closeFp)(pWrapper->pMgmt); + pWrapper->pMgmt = NULL; + } taosWUnLockLatch(&pWrapper->latch); if (pWrapper->procObj) { @@ -205,49 +219,29 @@ void dmCloseNode(SMgmtWrapper *pWrapper) { } static int32_t dmOpenNodes(SDnode *pDnode) { - if (pDnode->ptype == DND_PROC_CHILD) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[pDnode->ntype]; - pWrapper->required = dmRequireNode(pWrapper); - if (!pWrapper->required) { - dError("dnode:%s, failed to open since not required", pWrapper->name); - } - - pWrapper->procType = DND_PROC_CHILD; - if (dmInitClient(pDnode) != 0) { - return -1; - } - - pDnode->data.msgCb = dmGetMsgcb(pWrapper); - tmsgSetDefaultMsgCb(&pDnode->data.msgCb); - - if (dmOpenNode(pWrapper) != 0) { - dError("node:%s, failed to open since %s", pWrapper->name, terrstr()); - return -1; - } - } else { - for (EDndNodeType n = DNODE; n < NODE_END; ++n) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[n]; - pWrapper->required = dmRequireNode(pWrapper); - if (!pWrapper->required) continue; - - if (pDnode->ptype == DND_PROC_PARENT && n != DNODE) { - pWrapper->procType = DND_PROC_PARENT; - } else { - pWrapper->procType = DND_PROC_SINGLE; + for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + if (!pWrapper->required) continue; + if (ntype == DNODE) { + pWrapper->procType = DND_PROC_SINGLE; + if (dmOpenNode(pWrapper) != 0) { + return -1; } - - if (n == DNODE) { - if (dmInitClient(pDnode) != 0) { + } else { + if (pDnode->ptype == DND_PROC_CHILD) { + if (pDnode->ntype == ntype) { + pWrapper->procType = DND_PROC_CHILD; + if (dmOpenNode(pWrapper) != 0) { + return -1; + } + } else { + pWrapper->required = false; + } + } else { + pWrapper->procType = pDnode->ptype; + if (dmOpenNode(pWrapper) != 0) { return -1; } - - pDnode->data.msgCb = dmGetMsgcb(pWrapper); - tmsgSetDefaultMsgCb(&pDnode->data.msgCb); - } - - if (dmOpenNode(pWrapper) != 0) { - dError("node:%s, failed to open since %s", pWrapper->name, terrstr()); - return -1; } } } @@ -257,9 +251,9 @@ static int32_t dmOpenNodes(SDnode *pDnode) { } static int32_t dmStartNodes(SDnode *pDnode) { - for (EDndNodeType n = DNODE; n < NODE_END; ++n) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[n]; - if (!pWrapper->required) continue; + for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + if (ntype == DNODE && (pDnode->ptype == DND_PROC_CHILD || pDnode->ptype == DND_PROC_TEST)) continue; if (dmStartNode(pWrapper) != 0) { dError("node:%s, failed to start since %s", pWrapper->name, terrstr()); return -1; @@ -313,16 +307,27 @@ static void dmWatchNodes(SDnode *pDnode) { } int32_t dmRun(SDnode *pDnode) { - if (!tsMultiProcess) { + if (tsMultiProcess == 0) { pDnode->ptype = DND_PROC_SINGLE; - dInfo("dnode run in single process"); + dInfo("dnode run in single process mode"); + } else if (tsMultiProcess == 2) { + pDnode->ptype = DND_PROC_TEST; + dInfo("dnode run in multi-process test mode"); } else if (pDnode->ntype == DNODE || pDnode->ntype == NODE_END) { pDnode->ptype = DND_PROC_PARENT; - dInfo("dnode run in parent process"); + dInfo("dnode run in parent process mode"); } else { pDnode->ptype = DND_PROC_CHILD; SMgmtWrapper *pWrapper = &pDnode->wrappers[pDnode->ntype]; - dInfo("%s run in child process", pWrapper->name); + dInfo("%s run in child process mode", pWrapper->name); + } + + if (pDnode->ptype != DND_PROC_CHILD) { + if (dmInitServer(pDnode) != 0) { + dError("failed to init transport since %s", terrstr()); + return -1; + } + dmReportStartup(pDnode, "dnode-transport", "initialized"); } if (dmOpenNodes(pDnode) != 0) { diff --git a/source/dnode/mgmt/implement/src/dmTransport.c b/source/dnode/mgmt/node_mgmt/src/dmTransport.c similarity index 84% rename from source/dnode/mgmt/implement/src/dmTransport.c rename to source/dnode/mgmt/node_mgmt/src/dmTransport.c index a58999bf2d..30ec04d9ef 100644 --- a/source/dnode/mgmt/implement/src/dmTransport.c +++ b/source/dnode/mgmt/node_mgmt/src/dmTransport.c @@ -14,8 +14,7 @@ */ #define _DEFAULT_SOURCE -#include "dmImp.h" - +#include "dmMgmt.h" #include "qworker.h" #define INTERNAL_USER "_dnd" @@ -23,21 +22,21 @@ #define INTERNAL_SECRET "_pwd" static void dmGetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) { - taosRLockLatch(&pDnode->data.latch); - *pEpSet = pDnode->data.mnodeEps; - taosRUnLockLatch(&pDnode->data.latch); + taosRLockLatch(&pDnode->latch); + *pEpSet = pDnode->mnodeEps; + taosRUnLockLatch(&pDnode->latch); } static void dmSetMnodeEpSet(SDnode *pDnode, SEpSet *pEpSet) { dInfo("mnode is changed, num:%d use:%d", pEpSet->numOfEps, pEpSet->inUse); - taosWLockLatch(&pDnode->data.latch); - pDnode->data.mnodeEps = *pEpSet; + taosWLockLatch(&pDnode->latch); + pDnode->mnodeEps = *pEpSet; for (int32_t i = 0; i < pEpSet->numOfEps; ++i) { dInfo("mnode index:%d %s:%u", i, pEpSet->eps[i].fqdn, pEpSet->eps[i].port); } - taosWUnLockLatch(&pDnode->data.latch); + taosWUnLockLatch(&pDnode->latch); } static inline NodeMsgFp dmGetMsgFp(SMgmtWrapper *pWrapper, SRpcMsg *pRpc) { @@ -64,7 +63,7 @@ static inline int32_t dmBuildMsg(SNodeMsg *pMsg, SRpcMsg *pRpc) { if ((pRpc->msgType & 1u)) { assert(pRpc->refId != 0); } - // assert(pRpc->handle != NULL && pRpc->refId != 0 && pMsg->rpcMsg.refId != 0); + return 0; } @@ -76,20 +75,16 @@ static void dmProcessRpcMsg(SMgmtWrapper *pWrapper, SRpcMsg *pRpc, SEpSet *pEpSe bool needRelease = false; bool isReq = msgType & 1U; - if (pEpSet && pEpSet->numOfEps > 0 && msgType == TDMT_MND_STATUS_RSP) { - dmSetMnodeEpSet(pWrapper->pDnode, pEpSet); - } - if (dmMarkWrapper(pWrapper) != 0) goto _OVER; - needRelease = true; + if ((msgFp = dmGetMsgFp(pWrapper, pRpc)) == NULL) goto _OVER; if ((pMsg = taosAllocateQitem(sizeof(SNodeMsg))) == NULL) goto _OVER; if (dmBuildMsg(pMsg, pRpc) != 0) goto _OVER; if (pWrapper->procType != DND_PROC_PARENT) { dTrace("msg:%p, created, type:%s handle:%p user:%s", pMsg, TMSG_INFO(msgType), pRpc->handle, pMsg->user); - code = (*msgFp)(pWrapper, pMsg); + code = (*msgFp)(pWrapper->pMgmt, pMsg); } else { dTrace("msg:%p, created and put into child queue, type:%s handle:%p code:0x%04x user:%s contLen:%d", pMsg, TMSG_INFO(msgType), pRpc->handle, pMsg->rpcMsg.code & 0XFFFF, pMsg->user, pRpc->contLen); @@ -133,13 +128,17 @@ static void dmProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { tmsg_t msgType = pMsg->msgType; bool isReq = msgType & 1u; SMsgHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(msgType)]; - SMgmtWrapper *pWrapper = pHandle->pNdWrapper; + SMgmtWrapper *pWrapper = NULL; switch (msgType) { case TDMT_DND_SERVER_STATUS: - dTrace("server status req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle); - dmProcessServerStatusReq(pDnode, pMsg); - return; + if (pDnode->status != DND_STAT_RUNNING) { + dTrace("server status req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle); + dmProcessServerStartupStatus(pDnode, pMsg); + return; + } else { + break; + } case TDMT_DND_NET_TEST: dTrace("net test req will be processed, handle:%p, app:%p", pMsg->handle, pMsg->ahandle); dmProcessNetTestReq(pDnode, pMsg); @@ -171,7 +170,7 @@ static void dmProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { return; } - if (pWrapper == NULL) { + if (pHandle->defaultNtype == NODE_END) { dError("msg:%s not processed since no handle, handle:%p app:%p", TMSG_INFO(msgType), pMsg->handle, pMsg->ahandle); if (isReq) { SRpcMsg rspMsg = { @@ -182,13 +181,14 @@ static void dmProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { return; } - if (pHandle->pMndWrapper != NULL || pHandle->pQndWrapper != NULL) { + pWrapper = &pDnode->wrappers[pHandle->defaultNtype]; + if (pHandle->needCheckVgId) { SMsgHead *pHead = pMsg->pCont; int32_t vgId = ntohl(pHead->vgId); if (vgId == QNODE_HANDLE) { - pWrapper = pHandle->pQndWrapper; + pWrapper = &pDnode->wrappers[QNODE]; } else if (vgId == MNODE_HANDLE) { - pWrapper = pHandle->pMndWrapper; + pWrapper = &pDnode->wrappers[MNODE]; } else { } } @@ -203,35 +203,24 @@ static void dmProcessMsg(SDnode *pDnode, SRpcMsg *pMsg, SEpSet *pEpSet) { int32_t dmInitMsgHandle(SDnode *pDnode) { SDnodeTrans *pTrans = &pDnode->trans; - for (EDndNodeType n = DNODE; n < NODE_END; ++n) { - SMgmtWrapper *pWrapper = &pDnode->wrappers[n]; + for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) { + SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype]; + SArray *pArray = (*pWrapper->func.getHandlesFp)(); + if (pArray == NULL) return -1; - for (int32_t msgIndex = 0; msgIndex < TDMT_MAX; ++msgIndex) { - NodeMsgFp msgFp = pWrapper->msgFps[msgIndex]; - int8_t vgId = pWrapper->msgVgIds[msgIndex]; - if (msgFp == NULL) continue; - - SMsgHandle *pHandle = &pTrans->msgHandles[msgIndex]; - if (vgId == QNODE_HANDLE) { - if (pHandle->pQndWrapper != NULL) { - dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]); - return -1; - } - pHandle->pQndWrapper = pWrapper; - } else if (vgId == MNODE_HANDLE) { - if (pHandle->pMndWrapper != NULL) { - dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]); - return -1; - } - pHandle->pMndWrapper = pWrapper; - } else { - if (pHandle->pNdWrapper != NULL) { - dError("msg:%s has multiple process nodes", tMsgInfo[msgIndex]); - return -1; - } - pHandle->pNdWrapper = pWrapper; + for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) { + SMgmtHandle *pMgmt = taosArrayGet(pArray, i); + SMsgHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(pMgmt->msgType)]; + if (pMgmt->needCheckVgId) { + pHandle->needCheckVgId = pMgmt->needCheckVgId; } + if (!pMgmt->needCheckVgId) { + pHandle->defaultNtype = ntype; + } + pWrapper->msgFps[TMSG_INDEX(pMgmt->msgType)] = pMgmt->msgFp; } + + taosArrayDestroy(pArray); } return 0; @@ -244,7 +233,7 @@ static void dmSendRpcRedirectRsp(SDnode *pDnode, const SRpcMsg *pReq) { dDebug("RPC %p, req is redirected, num:%d use:%d", pReq->handle, epSet.numOfEps, epSet.inUse); for (int32_t i = 0; i < epSet.numOfEps; ++i) { dDebug("mnode index:%d %s:%u", i, epSet.eps[i].fqdn, epSet.eps[i].port); - if (strcmp(epSet.eps[i].fqdn, pDnode->data.localFqdn) == 0 && epSet.eps[i].port == pDnode->data.serverPort) { + if (strcmp(epSet.eps[i].fqdn, pDnode->input.localFqdn) == 0 && epSet.eps[i].port == pDnode->input.serverPort) { epSet.inUse = (i + 1) % epSet.numOfEps; } @@ -271,29 +260,32 @@ static inline void dmSendRpcRsp(SDnode *pDnode, const SRpcMsg *pRsp) { } } -void dmSendRecv(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp) { - rpcSendRecv(pDnode->trans.clientRpc, pEpSet, pReq, pRsp); +static inline void dmSendRecv(SDnode *pDnode, SEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp) { + if (pDnode->status != DND_STAT_RUNNING) { + pRsp->code = TSDB_CODE_NODE_OFFLINE; + rpcFreeCont(pReq->pCont); + pReq->pCont = NULL; + } else { + rpcSendRecv(pDnode->trans.clientRpc, pEpSet, pReq, pRsp); + } } -void dmSendToMnodeRecv(SDnode *pDnode, SRpcMsg *pReq, SRpcMsg *pRsp) { +static inline void dmSendToMnodeRecv(SMgmtWrapper *pWrapper, SRpcMsg *pReq, SRpcMsg *pRsp) { SEpSet epSet = {0}; - dmGetMnodeEpSet(pDnode, &epSet); - rpcSendRecv(pDnode->trans.clientRpc, &epSet, pReq, pRsp); + dmGetMnodeEpSet(pWrapper->pDnode, &epSet); + dmSendRecv(pWrapper->pDnode, &epSet, pReq, pRsp); } static inline int32_t dmSendReq(SMgmtWrapper *pWrapper, const SEpSet *pEpSet, SRpcMsg *pReq) { SDnode *pDnode = pWrapper->pDnode; - if (pDnode->status != DND_STAT_RUNNING) { + if (pDnode->status != DND_STAT_RUNNING || pDnode->trans.clientRpc == NULL) { + rpcFreeCont(pReq->pCont); + pReq->pCont = NULL; terrno = TSDB_CODE_NODE_OFFLINE; dError("failed to send rpc msg since %s, handle:%p", terrstr(), pReq->handle); return -1; } - if (pDnode->trans.clientRpc == NULL) { - terrno = TSDB_CODE_NODE_OFFLINE; - return -1; - } - rpcSendRequest(pDnode->trans.clientRpc, pEpSet, pReq, NULL); return 0; } @@ -326,17 +318,6 @@ static inline void dmSendRedirectRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp } } -#if 0 -static inline void dmSendRedirectRsp(SMgmtWrapper *pWrapper, const SRpcMsg *pRsp, const SEpSet *pNewEpSet) { - ASSERT(pRsp->code == TSDB_CODE_RPC_REDIRECT); - if (pWrapper->procType != DND_PROC_CHILD) { - rpcSendRedirectRsp(pRsp->handle, pNewEpSet); - } else { - taosProcPutToParentQ(pWrapper->procObj, pRsp, sizeof(SRpcMsg), pRsp->pCont, pRsp->contLen, PROC_FUNC_RSP); - } -} -#endif - static inline void dmRegisterBrokenLinkArg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) { if (pWrapper->procType != DND_PROC_CHILD) { rpcRegisterBrokenLinkArg(pMsg); @@ -361,7 +342,7 @@ static void dmConsumeChildQueue(SMgmtWrapper *pWrapper, SNodeMsg *pMsg, int16_t dTrace("msg:%p, get from child queue, handle:%p app:%p", pMsg, pRpc->handle, pRpc->ahandle); NodeMsgFp msgFp = pWrapper->msgFps[TMSG_INDEX(pRpc->msgType)]; - int32_t code = (*msgFp)(pWrapper, pMsg); + int32_t code = (*msgFp)(pWrapper->pMgmt, pMsg); if (code != 0) { dError("msg:%p, failed to process since code:0x%04x:%s", pMsg, code & 0XFFFF, tstrerror(code)); @@ -460,11 +441,7 @@ int32_t dmInitClient(SDnode *pDnode) { return -1; } - pDnode->data.msgCb = dmGetMsgcb(&pDnode->wrappers[DNODE]); - tmsgSetDefaultMsgCb(&pDnode->data.msgCb); - dDebug("dnode rpc client is initialized"); - return 0; } @@ -515,8 +492,10 @@ static inline int32_t dmRetrieveUserAuthInfo(SDnode *pDnode, char *user, char *s SRpcMsg rpcMsg = {.pCont = pReq, .contLen = contLen, .msgType = TDMT_MND_AUTH, .ahandle = (void *)9528}; SRpcMsg rpcRsp = {0}; + SEpSet epSet = {0}; dTrace("user:%s, send user auth req to other mnodes, spi:%d encrypt:%d", user, authReq.spi, authReq.encrypt); - dmSendToMnodeRecv(pDnode, &rpcMsg, &rpcRsp); + dmGetMnodeEpSet(pDnode, &epSet); + dmSendRecv(pDnode, &epSet, &rpcMsg, &rpcRsp); if (rpcRsp.code != 0) { terrno = rpcRsp.code; @@ -541,8 +520,8 @@ int32_t dmInitServer(SDnode *pDnode) { SRpcInit rpcInit = {0}; - strncpy(rpcInit.localFqdn, pDnode->data.localFqdn, strlen(pDnode->data.localFqdn)); - rpcInit.localPort = pDnode->data.serverPort; + strncpy(rpcInit.localFqdn, pDnode->input.localFqdn, strlen(pDnode->input.localFqdn)); + rpcInit.localPort = pDnode->input.serverPort; rpcInit.label = "DND"; rpcInit.numOfThreads = tsNumOfRpcThreads; rpcInit.cfp = (RpcCfp)dmProcessMsg; @@ -573,14 +552,15 @@ void dmCleanupServer(SDnode *pDnode) { SMsgCb dmGetMsgcb(SMgmtWrapper *pWrapper) { SMsgCb msgCb = { + .pWrapper = pWrapper, + .clientRpc = pWrapper->pDnode->trans.clientRpc, .sendReqFp = dmSendReq, .sendRspFp = dmSendRsp, + .sendMnodeRecvFp = dmSendToMnodeRecv, .sendRedirectRspFp = dmSendRedirectRsp, .registerBrokenLinkArgFp = dmRegisterBrokenLinkArg, .releaseHandleFp = dmReleaseHandle, .reportStartupFp = dmReportStartupByWrapper, - .pWrapper = pWrapper, - .clientRpc = pWrapper->pDnode->trans.clientRpc, }; return msgCb; } diff --git a/source/dnode/mgmt/node_util/CMakeLists.txt b/source/dnode/mgmt/node_util/CMakeLists.txt new file mode 100644 index 0000000000..5d879fdbcf --- /dev/null +++ b/source/dnode/mgmt/node_util/CMakeLists.txt @@ -0,0 +1,10 @@ +aux_source_directory(src NODE_UTIL) +add_library(node_util STATIC ${NODE_UTIL}) +target_include_directories( + node_util + PUBLIC "${TD_SOURCE_DIR}/include/dnode/mgmt" + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) +target_link_libraries( + node_util cjson mnode vnode qnode snode bnode wal sync taos_static tfs monitor +) \ No newline at end of file diff --git a/source/dnode/mgmt/node_util/inc/dmUtil.h b/source/dnode/mgmt/node_util/inc/dmUtil.h new file mode 100644 index 0000000000..8d4ea88d42 --- /dev/null +++ b/source/dnode/mgmt/node_util/inc/dmUtil.h @@ -0,0 +1,188 @@ +/* + * 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_DM_INT_H_ +#define _TD_DM_INT_H_ + +#include "cJSON.h" +#include "tcache.h" +#include "tcrc32c.h" +#include "tdatablock.h" +#include "tglobal.h" +#include "thash.h" +#include "tlockfree.h" +#include "tlog.h" +#include "tmsg.h" +#include "tmsgcb.h" +#include "tprocess.h" +#include "tqueue.h" +#include "trpc.h" +#include "tthread.h" +#include "ttime.h" +#include "tworker.h" + +#include "dnode.h" +#include "mnode.h" +#include "monitor.h" +#include "sync.h" +#include "wal.h" + +#include "libs/function/function.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define dFatal(...) { if (dDebugFlag & DEBUG_FATAL) { taosPrintLog("DND FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} +#define dError(...) { if (dDebugFlag & DEBUG_ERROR) { taosPrintLog("DND ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} +#define dWarn(...) { if (dDebugFlag & DEBUG_WARN) { taosPrintLog("DND WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} +#define dInfo(...) { if (dDebugFlag & DEBUG_INFO) { taosPrintLog("DND ", DEBUG_INFO, 255, __VA_ARGS__); }} +#define dDebug(...) { if (dDebugFlag & DEBUG_DEBUG) { taosPrintLog("DND ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} +#define dTrace(...) { if (dDebugFlag & DEBUG_TRACE) { taosPrintLog("DND ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} + +typedef enum { + DNODE = 0, + MNODE = 1, + VNODE = 2, + QNODE = 3, + SNODE = 4, + BNODE = 5, + NODE_END = 6, +} EDndNodeType; + +typedef enum { + DND_STAT_INIT, + DND_STAT_RUNNING, + DND_STAT_STOPPED, +} EDndRunStatus; + +typedef enum { + DND_ENV_INIT, + DND_ENV_READY, + DND_ENV_CLEANUP, +} EDndEnvStatus; + +typedef enum { + DND_PROC_SINGLE, + DND_PROC_CHILD, + DND_PROC_PARENT, + DND_PROC_TEST, +} EDndProcType; + +typedef int32_t (*ProcessCreateNodeFp)(struct SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); +typedef int32_t (*ProcessDropNodeFp)(struct SDnode *pDnode, EDndNodeType ntype, SNodeMsg *pMsg); +typedef bool (*IsNodeDeployedFp)(struct SDnode *pDnode, EDndNodeType ntype); + +typedef struct { + const char *path; + const char *name; + SMsgCb msgCb; + int32_t dnodeId; + int64_t clusterId; + const char *localEp; + const char *firstEp; + const char *secondEp; + const char *localFqdn; + uint16_t serverPort; + int32_t supportVnodes; + int32_t numOfDisks; + SDiskCfg *disks; + const char *dataDir; + struct SDnode *pDnode; + ProcessCreateNodeFp processCreateNodeFp; + ProcessDropNodeFp processDropNodeFp; + IsNodeDeployedFp isNodeDeployedFp; +} SMgmtInputOpt; + +typedef struct { + int32_t dnodeId; + void *pMgmt; + SEpSet mnodeEps; +} SMgmtOutputOpt; + +typedef int32_t (*NodeMsgFp)(void *pMgmt, SNodeMsg *pMsg); +typedef int32_t (*NodeOpenFp)(const SMgmtInputOpt *pInput, SMgmtOutputOpt *pOutput); +typedef void (*NodeCloseFp)(void *pMgmt); +typedef int32_t (*NodeStartFp)(void *pMgmt); +typedef void (*NodeStopFp)(void *pMgmt); +typedef int32_t (*NodeCreateFp)(const SMgmtInputOpt *pInput, SNodeMsg *pMsg); +typedef int32_t (*NodeDropFp)(void *pMgmt, SNodeMsg *pMsg); +typedef int32_t (*NodeRequireFp)(const SMgmtInputOpt *pInput, bool *required); +typedef SArray *(*NodeGetHandlesFp)(); // array of SMgmtHandle + +typedef struct { + NodeOpenFp openFp; + NodeCloseFp closeFp; + NodeStartFp startFp; + NodeStopFp stopFp; + NodeCreateFp createFp; + NodeDropFp dropFp; + NodeRequireFp requiredFp; + NodeGetHandlesFp getHandlesFp; +} SMgmtFunc; + +typedef struct { + tmsg_t msgType; + bool needCheckVgId; + NodeMsgFp msgFp; +} SMgmtHandle; + +// dmUtil.c +const char *dmStatStr(EDndRunStatus stype); +const char *dmNodeLogName(EDndNodeType ntype); +const char *dmNodeProcName(EDndNodeType ntype); +const char *dmNodeName(EDndNodeType ntype); +const char *dmEventStr(EDndEvent etype); +const char *dmProcStr(EDndProcType ptype); +void *dmSetMgmtHandle(SArray *pArray, tmsg_t msgType, void *nodeMsgFp, bool needCheckVgId); +void dmGetMonitorSystemInfo(SMonSysInfo *pInfo); + +// dmFile.c +int32_t dmReadFile(const char *path, const char *name, bool *pDeployed); +int32_t dmWriteFile(const char *path, const char *name, bool deployed); +TdFilePtr dmCheckRunning(const char *dataDir); +int32_t dmReadShmFile(const char *path, const char *name, EDndNodeType runType, SShm *pShm); +int32_t dmWriteShmFile(const char *path, const char *name, const SShm *pShm); + +// common define +typedef struct { + int32_t dnodeId; + int64_t clusterId; + int64_t dnodeVer; + int64_t updateTime; + int64_t rebootTime; + int32_t unsyncedVgId; + ESyncState vndState; + ESyncState mndState; + bool dropped; + bool stopped; + SEpSet mnodeEps; + SArray *dnodeEps; + SHashObj *dnodeHash; + SRWLatch latch; + SMsgCb msgCb; + const char *localEp; + const char *localFqdn; + const char *firstEp; + const char *secondEp; + int32_t supportVnodes; + uint16_t serverPort; +} SDnodeData; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_DM_INT_H_*/ \ No newline at end of file diff --git a/source/dnode/mgmt/interface/src/dmEnv.c b/source/dnode/mgmt/node_util/src/dmEnv.c similarity index 82% rename from source/dnode/mgmt/interface/src/dmEnv.c rename to source/dnode/mgmt/node_util/src/dmEnv.c index 2c836714ce..582df8055b 100644 --- a/source/dnode/mgmt/interface/src/dmEnv.c +++ b/source/dnode/mgmt/node_util/src/dmEnv.c @@ -14,16 +14,15 @@ */ #define _DEFAULT_SOURCE -#include "dmInt.h" -#include "wal.h" +#include "dmUtil.h" static int8_t once = DND_ENV_INIT; int32_t dmInit() { - dDebug("start to init dnode env"); + dInfo("start to init env"); if (atomic_val_compare_exchange_8(&once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) { + dError("env is already initialized"); terrno = TSDB_CODE_REPEAT_INIT; - dError("failed to init dnode env since %s", terrstr()); return -1; } @@ -41,14 +40,14 @@ int32_t dmInit() { return -1; } - dInfo("dnode env is initialized"); + dInfo("env is initialized"); return 0; } void dmCleanup() { - dDebug("start to cleanup dnode env"); + dDebug("start to cleanup env"); if (atomic_val_compare_exchange_8(&once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) { - dError("dnode env is already cleaned up"); + dError("env is already cleaned up"); return; } @@ -56,6 +55,7 @@ void dmCleanup() { syncCleanUp(); walCleanUp(); udfcClose(); + udfStopUdfd(); taosStopCacheRefreshWorker(); - dInfo("dnode env is cleaned up"); + dInfo("env is cleaned up"); } diff --git a/source/dnode/mgmt/interface/src/dmFile.c b/source/dnode/mgmt/node_util/src/dmFile.c similarity index 72% rename from source/dnode/mgmt/interface/src/dmFile.c rename to source/dnode/mgmt/node_util/src/dmFile.c index 38acf169be..7ac6fc129d 100644 --- a/source/dnode/mgmt/interface/src/dmFile.c +++ b/source/dnode/mgmt/node_util/src/dmFile.c @@ -14,11 +14,11 @@ */ #define _DEFAULT_SOURCE -#include "dmInt.h" +#include "dmUtil.h" #define MAXLEN 1024 -int32_t dmReadFile(SMgmtWrapper *pWrapper, bool *pDeployed) { +int32_t dmReadFile(const char *path, const char *name, bool *pDeployed) { int32_t code = TSDB_CODE_INVALID_JSON_FORMAT; int64_t len = 0; char content[MAXLEN + 1] = {0}; @@ -26,10 +26,9 @@ int32_t dmReadFile(SMgmtWrapper *pWrapper, bool *pDeployed) { char file[PATH_MAX] = {0}; TdFilePtr pFile = NULL; - snprintf(file, sizeof(file), "%s%s%s.json", pWrapper->path, TD_DIRSEP, pWrapper->name); + snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name); pFile = taosOpenFile(file, TD_FILE_READ); if (pFile == NULL) { - // dDebug("file %s not exist", file); code = 0; goto _OVER; } @@ -64,7 +63,7 @@ _OVER: return code; } -int32_t dmWriteFile(SMgmtWrapper *pWrapper, bool deployed) { +int32_t dmWriteFile(const char *path, const char *name, bool deployed) { int32_t code = -1; int32_t len = 0; char content[MAXLEN + 1] = {0}; @@ -72,8 +71,8 @@ int32_t dmWriteFile(SMgmtWrapper *pWrapper, bool deployed) { char realfile[PATH_MAX] = {0}; TdFilePtr pFile = NULL; - snprintf(file, sizeof(file), "%s%s%s.json", pWrapper->path, TD_DIRSEP, pWrapper->name); - snprintf(realfile, sizeof(realfile), "%s%s%s.json", pWrapper->path, TD_DIRSEP, pWrapper->name); + snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name); + snprintf(realfile, sizeof(realfile), "%s%s%s.json", path, TD_DIRSEP, name); pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC); if (pFile == NULL) { @@ -140,17 +139,16 @@ TdFilePtr dmCheckRunning(const char *dataDir) { return pFile; } -int32_t dmReadShmFile(SMgmtWrapper *pWrapper) { +int32_t dmReadShmFile(const char *path, const char *name, EDndNodeType runType, SShm *pShm) { int32_t code = -1; char content[MAXLEN + 1] = {0}; char file[PATH_MAX] = {0}; cJSON *root = NULL; TdFilePtr pFile = NULL; - snprintf(file, sizeof(file), "%s%sshmfile", pWrapper->path, TD_DIRSEP); + snprintf(file, sizeof(file), "%s%sshmfile", path, TD_DIRSEP); pFile = taosOpenFile(file, TD_FILE_READ); if (pFile == NULL) { - // dDebug("node:%s, file %s not exist", pWrapper->name, file); code = 0; goto _OVER; } @@ -159,36 +157,36 @@ int32_t dmReadShmFile(SMgmtWrapper *pWrapper) { root = cJSON_Parse(content); if (root == NULL) { terrno = TSDB_CODE_INVALID_JSON_FORMAT; - dError("node:%s, failed to read %s since invalid json format", pWrapper->name, file); + dError("node:%s, failed to read %s since invalid json format", name, file); goto _OVER; } cJSON *shmid = cJSON_GetObjectItem(root, "shmid"); if (shmid && shmid->type == cJSON_Number) { - pWrapper->procShm.id = shmid->valueint; + pShm->id = shmid->valueint; } cJSON *shmsize = cJSON_GetObjectItem(root, "shmsize"); if (shmsize && shmsize->type == cJSON_Number) { - pWrapper->procShm.size = shmsize->valueint; + pShm->size = shmsize->valueint; } } - if (!tsMultiProcess || pWrapper->pDnode->ntype == DNODE || pWrapper->pDnode->ntype == NODE_END) { - if (pWrapper->procShm.id >= 0) { - dDebug("node:%s, shmid:%d, is closed, size:%d", pWrapper->name, pWrapper->procShm.id, pWrapper->procShm.size); - taosDropShm(&pWrapper->procShm); + if (!tsMultiProcess || runType == DNODE || runType == NODE_END) { + if (pShm->id >= 0) { + dDebug("node:%s, shmid:%d, is closed, size:%d", name, pShm->id, pShm->size); + taosDropShm(pShm); } } else { - if (taosAttachShm(&pWrapper->procShm) != 0) { + if (taosAttachShm(pShm) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); - dError("shmid:%d, failed to attach shm since %s", pWrapper->procShm.id, terrstr()); + dError("shmid:%d, failed to attach shm since %s", pShm->id, terrstr()); goto _OVER; } - dInfo("node:%s, shmid:%d is attached, size:%d", pWrapper->name, pWrapper->procShm.id, pWrapper->procShm.size); + dInfo("node:%s, shmid:%d is attached, size:%d", name, pShm->id, pShm->size); } - dDebug("node:%s, successed to load %s", pWrapper->name, file); + dDebug("node:%s, successed to load %s", name, file); code = 0; _OVER: @@ -198,7 +196,7 @@ _OVER: return code; } -int32_t dmWriteShmFile(SMgmtWrapper *pWrapper) { +int32_t dmWriteShmFile(const char *path, const char *name, const SShm *pShm) { int32_t code = -1; int32_t len = 0; char content[MAXLEN + 1] = {0}; @@ -206,30 +204,30 @@ int32_t dmWriteShmFile(SMgmtWrapper *pWrapper) { char realfile[PATH_MAX] = {0}; TdFilePtr pFile = NULL; - snprintf(file, sizeof(file), "%s%sshmfile.bak", pWrapper->path, TD_DIRSEP); - snprintf(realfile, sizeof(realfile), "%s%sshmfile", pWrapper->path, TD_DIRSEP); + snprintf(file, sizeof(file), "%s%sshmfile.bak", path, TD_DIRSEP); + snprintf(realfile, sizeof(realfile), "%s%sshmfile", path, TD_DIRSEP); pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC); if (pFile == NULL) { terrno = TAOS_SYSTEM_ERROR(errno); - dError("node:%s, failed to open file:%s since %s", pWrapper->name, file, terrstr()); + dError("node:%s, failed to open file:%s since %s", name, file, terrstr()); goto _OVER; } len += snprintf(content + len, MAXLEN - len, "{\n"); - len += snprintf(content + len, MAXLEN - len, " \"shmid\":%d,\n", pWrapper->procShm.id); - len += snprintf(content + len, MAXLEN - len, " \"shmsize\":%d\n", pWrapper->procShm.size); + len += snprintf(content + len, MAXLEN - len, " \"shmid\":%d,\n", pShm->id); + len += snprintf(content + len, MAXLEN - len, " \"shmsize\":%d\n", pShm->size); len += snprintf(content + len, MAXLEN - len, "}\n"); if (taosWriteFile(pFile, content, len) != len) { terrno = TAOS_SYSTEM_ERROR(errno); - dError("node:%s, failed to write file:%s since %s", pWrapper->name, file, terrstr()); + dError("node:%s, failed to write file:%s since %s", name, file, terrstr()); goto _OVER; } if (taosFsyncFile(pFile) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); - dError("node:%s, failed to fsync file:%s since %s", pWrapper->name, file, terrstr()); + dError("node:%s, failed to fsync file:%s since %s", name, file, terrstr()); goto _OVER; } @@ -237,11 +235,11 @@ int32_t dmWriteShmFile(SMgmtWrapper *pWrapper) { if (taosRenameFile(file, realfile) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); - dError("node:%s, failed to rename %s to %s since %s", pWrapper->name, file, realfile, terrstr()); + dError("node:%s, failed to rename %s to %s since %s", name, file, realfile, terrstr()); return -1; } - dInfo("node:%s, successed to write %s", pWrapper->name, realfile); + dInfo("node:%s, successed to write %s", name, realfile); code = 0; _OVER: diff --git a/source/dnode/mgmt/node_util/src/dmUtil.c b/source/dnode/mgmt/node_util/src/dmUtil.c new file mode 100644 index 0000000000..e913af203b --- /dev/null +++ b/source/dnode/mgmt/node_util/src/dmUtil.c @@ -0,0 +1,132 @@ +/* + * 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 . + */ + +#define _DEFAULT_SOURCE +#include "dmUtil.h" + +const char *dmStatStr(EDndRunStatus stype) { + switch (stype) { + case DND_STAT_INIT: + return "init"; + case DND_STAT_RUNNING: + return "running"; + case DND_STAT_STOPPED: + return "stopped"; + default: + return "UNKNOWN"; + } +} + +const char *dmNodeLogName(EDndNodeType ntype) { + switch (ntype) { + case VNODE: + return "vnode"; + case QNODE: + return "qnode"; + case SNODE: + return "snode"; + case MNODE: + return "mnode"; + case BNODE: + return "bnode"; + default: + return "taosd"; + } +} + +const char *dmNodeProcName(EDndNodeType ntype) { + switch (ntype) { + case VNODE: + return "taosv"; + case QNODE: + return "taosq"; + case SNODE: + return "taoss"; + case MNODE: + return "taosm"; + case BNODE: + return "taosb"; + default: + return "taosd"; + } +} + +const char *dmNodeName(EDndNodeType ntype) { + switch (ntype) { + case VNODE: + return "vnode"; + case QNODE: + return "qnode"; + case SNODE: + return "snode"; + case MNODE: + return "mnode"; + case BNODE: + return "bnode"; + default: + return "dnode"; + } +} + +const char *dmEventStr(EDndEvent ev) { + switch (ev) { + case DND_EVENT_START: + return "start"; + case DND_EVENT_STOP: + return "stop"; + case DND_EVENT_CHILD: + return "child"; + default: + return "UNKNOWN"; + } +} + +const char *dmProcStr(EDndProcType etype) { + switch (etype) { + case DND_PROC_SINGLE: + return "start"; + case DND_PROC_CHILD: + return "stop"; + case DND_PROC_PARENT: + return "child"; + case DND_PROC_TEST: + return "test"; + default: + return "UNKNOWN"; + } +} + +void *dmSetMgmtHandle(SArray *pArray, tmsg_t msgType, void *nodeMsgFp, bool needCheckVgId) { + SMgmtHandle handle = { + .msgType = msgType, + .msgFp = (NodeMsgFp)nodeMsgFp, + .needCheckVgId = needCheckVgId, + }; + + return taosArrayPush(pArray, &handle); +} + +void dmGetMonitorSystemInfo(SMonSysInfo *pInfo) { + taosGetCpuUsage(&pInfo->cpu_engine, &pInfo->cpu_system); + taosGetCpuCores(&pInfo->cpu_cores); + taosGetProcMemory(&pInfo->mem_engine); + taosGetSysMemory(&pInfo->mem_system); + pInfo->mem_total = tsTotalMemoryKB; + pInfo->disk_engine = 0; + pInfo->disk_used = tsDataSpace.size.used; + pInfo->disk_total = tsDataSpace.size.total; + taosGetCardInfoDelta(&pInfo->net_in, &pInfo->net_out); + taosGetProcIODelta(&pInfo->io_read, &pInfo->io_write, &pInfo->io_read_disk, &pInfo->io_write_disk); +} diff --git a/source/dnode/mgmt/test/CMakeLists.txt b/source/dnode/mgmt/test/CMakeLists.txt index e1656ceb34..6b1919bf18 100644 --- a/source/dnode/mgmt/test/CMakeLists.txt +++ b/source/dnode/mgmt/test/CMakeLists.txt @@ -3,7 +3,7 @@ if(${BUILD_TEST}) add_subdirectory(qnode) add_subdirectory(bnode) add_subdirectory(snode) - add_subdirectory(mnode) + #add_subdirectory(mnode) add_subdirectory(vnode) add_subdirectory(sut) endif(${BUILD_TEST}) diff --git a/source/dnode/mgmt/test/bnode/dbnode.cpp b/source/dnode/mgmt/test/bnode/dbnode.cpp index 9016bf49ea..4cc2f2386f 100644 --- a/source/dnode/mgmt/test/bnode/dbnode.cpp +++ b/source/dnode/mgmt/test/bnode/dbnode.cpp @@ -84,6 +84,7 @@ TEST_F(DndTestBnode, 01_Create_Bnode) { } TEST_F(DndTestBnode, 02_Drop_Bnode) { +#if 0 { SDDropBnodeReq dropReq = {0}; dropReq.dnodeId = 2; @@ -96,7 +97,7 @@ TEST_F(DndTestBnode, 02_Drop_Bnode) { ASSERT_NE(pRsp, nullptr); ASSERT_EQ(pRsp->code, TSDB_CODE_INVALID_OPTION); } - +#endif { SDDropBnodeReq dropReq = {0}; dropReq.dnodeId = 1; diff --git a/source/dnode/mgmt/test/qnode/dqnode.cpp b/source/dnode/mgmt/test/qnode/dqnode.cpp index 8a0d97abb1..b610681b69 100644 --- a/source/dnode/mgmt/test/qnode/dqnode.cpp +++ b/source/dnode/mgmt/test/qnode/dqnode.cpp @@ -82,6 +82,7 @@ TEST_F(DndTestQnode, 01_Create_Qnode) { } TEST_F(DndTestQnode, 02_Drop_Qnode) { +#if 0 { SDDropQnodeReq dropReq = {0}; dropReq.dnodeId = 2; @@ -94,6 +95,7 @@ TEST_F(DndTestQnode, 02_Drop_Qnode) { ASSERT_NE(pRsp, nullptr); ASSERT_EQ(pRsp->code, TSDB_CODE_INVALID_OPTION); } +#endif { SDDropQnodeReq dropReq = {0}; diff --git a/source/dnode/mgmt/test/snode/dsnode.cpp b/source/dnode/mgmt/test/snode/dsnode.cpp index a744240a1a..5075313085 100644 --- a/source/dnode/mgmt/test/snode/dsnode.cpp +++ b/source/dnode/mgmt/test/snode/dsnode.cpp @@ -82,6 +82,7 @@ TEST_F(DndTestSnode, 01_Create_Snode) { } TEST_F(DndTestSnode, 01_Drop_Snode) { +#if 0 { SDDropSnodeReq dropReq = {0}; dropReq.dnodeId = 2; @@ -94,6 +95,7 @@ TEST_F(DndTestSnode, 01_Drop_Snode) { ASSERT_NE(pRsp, nullptr); ASSERT_EQ(pRsp->code, TSDB_CODE_INVALID_OPTION); } +#endif { SDDropSnodeReq dropReq = {0}; diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index b96444bebc..75dda28a73 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -87,13 +87,11 @@ typedef struct { typedef struct SMnode { int32_t selfId; int64_t clusterId; + TdThread thread; + bool stopped; int8_t replica; int8_t selfIndex; SReplica replicas[TSDB_MAX_REPLICA]; - tmr_h timer; - tmr_h transTimer; - tmr_h mqTimer; - tmr_h telemTimer; char *path; int64_t checkTime; SSdb *pSdb; diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 5085de8610..4828b9f523 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -1051,7 +1051,7 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans) { int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->redoActions); if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { - mError("failed to execute redoActions since %s", terrstr()); + mError("failed to execute redoActions since:%s, code:0x%x", terrstr(), terrno); } return code; } diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index 690399f099..bc3dcfbe8c 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -56,82 +56,76 @@ static void *mndBuildTimerMsg(int32_t *pContLen) { return pReq; } -static void mndPullupTrans(void *param, void *tmrId) { - SMnode *pMnode = param; - if (mndIsMaster(pMnode)) { - int32_t contLen = 0; - void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS_TIMER, .pCont = pReq, .contLen = contLen}; - tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); - } - - taosTmrReset(mndPullupTrans, tsTransPullupInterval * 1000, pMnode, pMnode->timer, &pMnode->transTimer); +static void mndPullupTrans(SMnode *pMnode) { + int32_t contLen = 0; + void *pReq = mndBuildTimerMsg(&contLen); + SRpcMsg rpcMsg = {.msgType = TDMT_MND_TRANS_TIMER, .pCont = pReq, .contLen = contLen}; + tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg); } -static void mndCalMqRebalance(void *param, void *tmrId) { - SMnode *pMnode = param; - if (mndIsMaster(pMnode)) { - int32_t contLen = 0; - void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = { - .msgType = TDMT_MND_MQ_TIMER, - .pCont = pReq, - .contLen = contLen, - }; - tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); - } - - taosTmrReset(mndCalMqRebalance, tsMqRebalanceInterval * 1000, pMnode, pMnode->timer, &pMnode->mqTimer); +static void mndCalMqRebalance(SMnode *pMnode) { + int32_t contLen = 0; + void *pReq = mndBuildTimerMsg(&contLen); + SRpcMsg rpcMsg = { + .msgType = TDMT_MND_MQ_TIMER, + .pCont = pReq, + .contLen = contLen, + }; + tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); } -static void mndPullupTelem(void *param, void *tmrId) { +static void mndPullupTelem(SMnode *pMnode) { + int32_t contLen = 0; + void *pReq = mndBuildTimerMsg(&contLen); + SRpcMsg rpcMsg = {.msgType = TDMT_MND_TELEM_TIMER, .pCont = pReq, .contLen = contLen}; + tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); +} + +static void *mndThreadFp(void *param) { SMnode *pMnode = param; - if (mndIsMaster(pMnode)) { - int32_t contLen = 0; - void *pReq = mndBuildTimerMsg(&contLen); - SRpcMsg rpcMsg = {.msgType = TDMT_MND_TELEM_TIMER, .pCont = pReq, .contLen = contLen}; - tmsgPutToQueue(&pMnode->msgCb, READ_QUEUE, &rpcMsg); + int64_t lastTime = 0; + setThreadName("mnode-timer"); + + while (1) { + lastTime++; + taosMsleep(100); + if (pMnode->stopped) break; + if (!mndIsMaster(pMnode)) continue; + + if (lastTime % (tsTransPullupInterval * 10) == 0) { + mndPullupTrans(pMnode); + } + + if (lastTime % (tsMqRebalanceInterval * 10) == 0) { + mndCalMqRebalance(pMnode); + } + + if (lastTime % (tsTelemInterval * 10) == 0) { + mndPullupTelem(pMnode); + } } - taosTmrReset(mndPullupTelem, tsTelemInterval * 1000, pMnode, pMnode->timer, &pMnode->telemTimer); + return NULL; } static int32_t mndInitTimer(SMnode *pMnode) { - pMnode->timer = taosTmrInit(5000, 200, 3600000, "MND"); - if (pMnode->timer == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - if (taosTmrReset(mndPullupTrans, tsTransPullupInterval * 1000, pMnode, pMnode->timer, &pMnode->transTimer)) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - if (taosTmrReset(mndCalMqRebalance, tsMqRebalanceInterval * 1000, pMnode, pMnode->timer, &pMnode->mqTimer)) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - int32_t interval = tsTelemInterval < 10 ? tsTelemInterval : 10; - if (taosTmrReset(mndPullupTelem, interval * 1000, pMnode, pMnode->timer, &pMnode->telemTimer)) { - terrno = TSDB_CODE_OUT_OF_MEMORY; + TdThreadAttr thAttr; + taosThreadAttrInit(&thAttr); + taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_JOINABLE); + if (taosThreadCreate(&pMnode->thread, &thAttr, mndThreadFp, pMnode) != 0) { + mError("failed to create timer thread since %s", strerror(errno)); return -1; } + taosThreadAttrDestroy(&thAttr); + tmsgReportStartup("mnode-timer", "initialized"); return 0; } static void mndCleanupTimer(SMnode *pMnode) { - if (pMnode->timer != NULL) { - taosTmrStop(pMnode->transTimer); - pMnode->transTimer = NULL; - taosTmrStop(pMnode->mqTimer); - pMnode->mqTimer = NULL; - taosTmrStop(pMnode->telemTimer); - pMnode->telemTimer = NULL; - taosTmrCleanUp(pMnode->timer); - pMnode->timer = NULL; + pMnode->stopped = true; + if (taosCheckPthreadValid(pMnode->thread)) { + taosThreadJoin(pMnode->thread, NULL); } } diff --git a/source/dnode/mnode/impl/test/CMakeLists.txt b/source/dnode/mnode/impl/test/CMakeLists.txt index feeebad674..b6e3c8f3b4 100644 --- a/source/dnode/mnode/impl/test/CMakeLists.txt +++ b/source/dnode/mnode/impl/test/CMakeLists.txt @@ -5,7 +5,7 @@ add_subdirectory(bnode) add_subdirectory(db) add_subdirectory(dnode) add_subdirectory(func) -add_subdirectory(mnode) +#add_subdirectory(mnode) add_subdirectory(profile) add_subdirectory(qnode) add_subdirectory(sdb) diff --git a/source/dnode/qnode/src/qnode.c b/source/dnode/qnode/src/qnode.c index 54b29f546c..1259363f94 100644 --- a/source/dnode/qnode/src/qnode.c +++ b/source/dnode/qnode/src/qnode.c @@ -26,10 +26,6 @@ SQnode *qndOpen(const SQnodeOpt *pOption) { return NULL; } - if (udfcOpen() != 0) { - qError("qnode can not open udfc"); - } - if (qWorkerInit(NODE_TYPE_QNODE, pQnode->qndId, NULL, (void **)&pQnode->pQuery, &pOption->msgCb)) { taosMemoryFreeClear(pQnode); return NULL; @@ -41,9 +37,6 @@ SQnode *qndOpen(const SQnodeOpt *pOption) { void qndClose(SQnode *pQnode) { qWorkerDestroy((void **)&pQnode->pQuery); - - udfcClose(); - taosMemoryFree(pQnode); } diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index b84732c848..130cebf0b1 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -115,6 +115,7 @@ void tsdbResetReadHandle(tsdbReaderT queryHandle, SQueryTableDataCond *pCond) void tsdbDestroyTableGroup(STableGroupInfo *pGroupList); int32_t tsdbGetOneTableGroup(void *pMeta, uint64_t uid, TSKEY startKey, STableGroupInfo *pGroupInfo); int32_t tsdbGetTableGroupFromIdList(SVnode *pVnode, SArray *pTableIdList, STableGroupInfo *pGroupInfo); +void tsdbCleanupReadHandle(tsdbReaderT queryHandle); // tq diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 5eb89e8bb7..38dedee5a2 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -93,6 +93,7 @@ struct STqReadHandle { SMeta* pVnodeMeta; SArray* pColIdList; // SArray int32_t sver; + int64_t cachedSchemaUid; SSchemaWrapper* pSchemaWrapper; STSchema* pSchema; }; diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index c9305f6af9..102c40337d 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -99,7 +99,6 @@ int32_t tsdbInitSma(STsdb *pTsdb); int32_t tsdbDropTSma(STsdb *pTsdb, char *pMsg); int32_t tsdbDropTSmaData(STsdb *pTsdb, int64_t indexUid); int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg); -void tsdbCleanupReadHandle(tsdbReaderT queryHandle); typedef enum { TSDB_FILE_HEAD = 0, // .head TSDB_FILE_DATA, // .data diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 0cdefb3cff..9526451907 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -457,9 +457,9 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) { } if (pHeadWithCkSum->head.msgType != TDMT_VND_SUBMIT) { - walSkipFetchBody(pExec->pWalReader, pHeadWithCkSum); + ASSERT(walSkipFetchBody(pExec->pWalReader, pHeadWithCkSum) == 0); } else { - walFetchBody(pExec->pWalReader, &pHeadWithCkSum); + ASSERT(walFetchBody(pExec->pWalReader, &pHeadWithCkSum) == 0); } SWalReadHead* pHead = &pHeadWithCkSum->head; @@ -559,6 +559,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) { } // db subscribe } else if (pExec->subType == TOPIC_SUB_TYPE__DB) { + rsp.withSchema = 1; STqReadHandle* pReader = pExec->pExecReader[workerId]; tqReadHandleSetMsg(pReader, pCont, 0); while (tqNextDataBlock(pReader)) { @@ -950,6 +951,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int32_t parallel) { .reader = pStreamReader, .meta = pTq->pVnode->pMeta, .pMsgCb = &pTq->pVnode->msgCb, + .vnode = pTq->pVnode, }; pTask->exec.runners[i].inputHandle = pStreamReader; pTask->exec.runners[i].executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index f531d3f5fb..996d789e24 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -25,6 +25,7 @@ STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) { pReadHandle->ver = -1; pReadHandle->pColIdList = NULL; pReadHandle->sver = -1; + pReadHandle->cachedSchemaUid = -1; pReadHandle->pSchema = NULL; pReadHandle->pSchemaWrapper = NULL; pReadHandle->tbIdHash = NULL; @@ -84,19 +85,20 @@ bool tqNextDataBlock(STqReadHandle* pHandle) { return false; } -int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* pGroupId, uint64_t* pUid, int32_t* pNumOfRows, - int16_t* pNumOfCols) { +int32_t tqRetrieveDataBlock(SArray** ppCols, STqReadHandle* pHandle, uint64_t* pGroupId, uint64_t* pUid, + int32_t* pNumOfRows, int16_t* pNumOfCols) { /*int32_t sversion = pHandle->pBlock->sversion;*/ // TODO set to real sversion *pUid = 0; int32_t sversion = 0; - if (pHandle->sver != sversion) { + if (pHandle->sver != sversion || pHandle->cachedSchemaUid != pHandle->msgIter.suid) { pHandle->pSchema = metaGetTbTSchema(pHandle->pVnodeMeta, pHandle->msgIter.uid, sversion); // this interface use suid instead of uid pHandle->pSchemaWrapper = metaGetTableSchema(pHandle->pVnodeMeta, pHandle->msgIter.suid, sversion, true); pHandle->sver = sversion; + pHandle->cachedSchemaUid = pHandle->msgIter.suid; } STSchema* pTschema = pHandle->pSchema; diff --git a/source/dnode/vnode/src/vnd/vnodeCfg.c b/source/dnode/vnode/src/vnd/vnodeCfg.c index 32866d7469..a66ecc493d 100644 --- a/source/dnode/vnode/src/vnd/vnodeCfg.c +++ b/source/dnode/vnode/src/vnd/vnodeCfg.c @@ -114,24 +114,42 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) { int vnodeDecodeConfig(const SJson *pJson, void *pObj) { SVnodeCfg *pCfg = (SVnodeCfg *)pObj; - if (tjsonGetNumberValue(pJson, "vgId", pCfg->vgId) < 0) return -1; + int32_t code; + tjsonGetNumberValue(pJson, "vgId", pCfg->vgId, code); + if(code < 0) return -1; if (tjsonGetStringValue(pJson, "dbname", pCfg->dbname) < 0) return -1; - if (tjsonGetNumberValue(pJson, "dbId", pCfg->dbId) < 0) return -1; - if (tjsonGetNumberValue(pJson, "szPage", pCfg->szPage) < 0) return -1; - if (tjsonGetNumberValue(pJson, "szCache", pCfg->szCache) < 0) return -1; - if (tjsonGetNumberValue(pJson, "szBuf", pCfg->szBuf) < 0) return -1; - if (tjsonGetNumberValue(pJson, "isHeap", pCfg->isHeap) < 0) return -1; - if (tjsonGetNumberValue(pJson, "isWeak", pCfg->isWeak) < 0) return -1; - if (tjsonGetNumberValue(pJson, "precision", pCfg->tsdbCfg.precision) < 0) return -1; - if (tjsonGetNumberValue(pJson, "update", pCfg->tsdbCfg.update) < 0) return -1; - if (tjsonGetNumberValue(pJson, "compression", pCfg->tsdbCfg.compression) < 0) return -1; - if (tjsonGetNumberValue(pJson, "slLevel", pCfg->tsdbCfg.slLevel) < 0) return -1; - if (tjsonGetNumberValue(pJson, "daysPerFile", pCfg->tsdbCfg.days) < 0) return -1; - if (tjsonGetNumberValue(pJson, "minRows", pCfg->tsdbCfg.minRows) < 0) return -1; - if (tjsonGetNumberValue(pJson, "maxRows", pCfg->tsdbCfg.maxRows) < 0) return -1; - if (tjsonGetNumberValue(pJson, "keep0", pCfg->tsdbCfg.keep0) < 0) return -1; - if (tjsonGetNumberValue(pJson, "keep1", pCfg->tsdbCfg.keep1) < 0) return -1; - if (tjsonGetNumberValue(pJson, "keep2", pCfg->tsdbCfg.keep2) < 0) return -1; + tjsonGetNumberValue(pJson, "dbId", pCfg->dbId, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "szPage", pCfg->szPage, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "szCache", pCfg->szCache, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "szBuf", pCfg->szBuf, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "isHeap", pCfg->isHeap, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "isWeak", pCfg->isWeak, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "precision", pCfg->tsdbCfg.precision, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "update", pCfg->tsdbCfg.update, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "compression", pCfg->tsdbCfg.compression, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "slLevel", pCfg->tsdbCfg.slLevel, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "daysPerFile", pCfg->tsdbCfg.days, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "minRows", pCfg->tsdbCfg.minRows, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "maxRows", pCfg->tsdbCfg.maxRows, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "keep0", pCfg->tsdbCfg.keep0, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "keep1", pCfg->tsdbCfg.keep1, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "keep2", pCfg->tsdbCfg.keep2, code); + if(code < 0) return -1; SJson *pNodeRetentions = tjsonGetObjectItem(pJson, "retentions"); int32_t nRetention = tjsonGetArraySize(pNodeRetentions); if (nRetention > TSDB_RETENTION_MAX) { @@ -140,24 +158,36 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) { for (int32_t i = 0; i < nRetention; ++i) { SJson *pNodeRetention = tjsonGetArrayItem(pNodeRetentions, i); ASSERT(pNodeRetention != NULL); - tjsonGetNumberValue(pNodeRetention, "freq", (pCfg->tsdbCfg.retentions)[i].freq); - tjsonGetNumberValue(pNodeRetention, "freqUnit", (pCfg->tsdbCfg.retentions)[i].freqUnit); - tjsonGetNumberValue(pNodeRetention, "keep", (pCfg->tsdbCfg.retentions)[i].keep); - tjsonGetNumberValue(pNodeRetention, "keepUnit", (pCfg->tsdbCfg.retentions)[i].keepUnit); + tjsonGetNumberValue(pNodeRetention, "freq", (pCfg->tsdbCfg.retentions)[i].freq, code); + tjsonGetNumberValue(pNodeRetention, "freqUnit", (pCfg->tsdbCfg.retentions)[i].freqUnit, code); + tjsonGetNumberValue(pNodeRetention, "keep", (pCfg->tsdbCfg.retentions)[i].keep, code); + tjsonGetNumberValue(pNodeRetention, "keepUnit", (pCfg->tsdbCfg.retentions)[i].keepUnit, code); } - if (tjsonGetNumberValue(pJson, "wal.vgId", pCfg->walCfg.vgId) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.rollPeriod", pCfg->walCfg.rollPeriod) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.retentionSize", pCfg->walCfg.retentionSize) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.segSize", pCfg->walCfg.segSize) < 0) return -1; - if (tjsonGetNumberValue(pJson, "wal.level", pCfg->walCfg.level) < 0) return -1; - if (tjsonGetNumberValue(pJson, "hashBegin", pCfg->hashBegin) < 0) return -1; - if (tjsonGetNumberValue(pJson, "hashEnd", pCfg->hashEnd) < 0) return -1; - if (tjsonGetNumberValue(pJson, "hashMethod", pCfg->hashMethod) < 0) return -1; + tjsonGetNumberValue(pJson, "wal.vgId", pCfg->walCfg.vgId, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.rollPeriod", pCfg->walCfg.rollPeriod, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.retentionSize", pCfg->walCfg.retentionSize, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.segSize", pCfg->walCfg.segSize, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "wal.level", pCfg->walCfg.level, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "hashBegin", pCfg->hashBegin, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "hashEnd", pCfg->hashEnd, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "hashMethod", pCfg->hashMethod, code); + if(code < 0) return -1; - if (tjsonGetNumberValue(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum) < 0) return -1; - if (tjsonGetNumberValue(pJson, "syncCfg.myIndex", pCfg->syncCfg.myIndex) < 0) return -1; + tjsonGetNumberValue(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "syncCfg.myIndex", pCfg->syncCfg.myIndex, code); + if(code < 0) return -1; SJson *pNodeInfoArr = tjsonGetObjectItem(pJson, "syncCfg.nodeInfo"); int arraySize = tjsonGetArraySize(pNodeInfoArr); @@ -166,7 +196,7 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) { for (int i = 0; i < arraySize; ++i) { SJson *pNodeInfo = tjsonGetArrayItem(pNodeInfoArr, i); assert(pNodeInfo != NULL); - tjsonGetNumberValue(pNodeInfo, "nodePort", (pCfg->syncCfg.nodeInfo)[i].nodePort); + tjsonGetNumberValue(pNodeInfo, "nodePort", (pCfg->syncCfg.nodeInfo)[i].nodePort, code); tjsonGetStringValue(pNodeInfo, "nodeFqdn", (pCfg->syncCfg.nodeInfo)[i].nodeFqdn); } diff --git a/source/dnode/vnode/src/vnd/vnodeCommit.c b/source/dnode/vnode/src/vnd/vnodeCommit.c index 6d8bcb35c8..e7bee3342a 100644 --- a/source/dnode/vnode/src/vnd/vnodeCommit.c +++ b/source/dnode/vnode/src/vnd/vnodeCommit.c @@ -310,8 +310,11 @@ static int vnodeEncodeState(const void *pObj, SJson *pJson) { static int vnodeDecodeState(const SJson *pJson, void *pObj) { SVState *pState = (SVState *)pObj; - if (tjsonGetNumberValue(pJson, "commit version", pState->committed) < 0) return -1; - if (tjsonGetNumberValue(pJson, "applied version", pState->applied) < 0) return -1; + int32_t code; + tjsonGetNumberValue(pJson, "commit version", pState->committed, code); + if(code < 0) return -1; + tjsonGetNumberValue(pJson, "applied version", pState->applied, code); + if(code < 0) return -1; return 0; } diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c index ae134e6496..7476da2a0f 100644 --- a/source/dnode/vnode/src/vnd/vnodeOpen.c +++ b/source/dnode/vnode/src/vnd/vnodeOpen.c @@ -137,18 +137,21 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) { // open query if (vnodeQueryOpen(pVnode)) { vError("vgId:%d failed to open vnode query since %s", TD_VID(pVnode), tstrerror(terrno)); + terrno = TSDB_CODE_OUT_OF_MEMORY; goto _err; } // vnode begin if (vnodeBegin(pVnode) < 0) { vError("vgId:%d failed to begin since %s", TD_VID(pVnode), tstrerror(terrno)); + terrno = TSDB_CODE_OUT_OF_MEMORY; goto _err; } // open sync if (vnodeSyncOpen(pVnode, dir)) { vError("vgId:%d failed to open sync since %s", TD_VID(pVnode), tstrerror(terrno)); + terrno = TSDB_CODE_OUT_OF_MEMORY; goto _err; } diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index f485f85809..64090d0283 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -841,6 +841,8 @@ int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STable return TSDB_CODE_SUCCESS; } + + ctgDebug("Got subtable meta from cache, type:%d, dbFName:%s, tbName:%s, suid:%" PRIx64, tbMeta->tableType, dbFName, pTableName->tname, tbMeta->suid); CTG_LOCK(CTG_READ, &dbCache->tbCache.stbLock); @@ -1655,6 +1657,11 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui STableMeta *orig = taosHashGet(tbCache->metaCache, tbName, strlen(tbName)); if (orig) { origType = orig->tableType; + + if (origType == meta->tableType && orig->uid == meta->uid && orig->sversion >= meta->sversion && orig->tversion >= meta->tversion) { + CTG_UNLOCK(CTG_READ, &tbCache->metaLock); + return TSDB_CODE_SUCCESS; + } if (origType == TSDB_SUPER_TABLE) { if ((!isStb) || orig->suid != meta->suid) { @@ -1693,7 +1700,7 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui CTG_CACHE_STAT_ADD(tblNum, 1); } - ctgDebug("tbmeta updated to cache, dbFName:%s, tbName:%s, tbType:%d", dbFName, tbName, meta->tableType); + ctgDebug("tbmeta updated to cache, dbFName:%s, tbName:%s, tbType:%d, suid:%" PRIx64, dbFName, tbName, meta->tableType, meta->suid); ctgdShowTableMeta(pCtg, tbName, meta); if (!isStb) { @@ -1701,12 +1708,6 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui return TSDB_CODE_SUCCESS; } - if (origType == TSDB_SUPER_TABLE && origSuid == meta->suid) { - CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock); - CTG_UNLOCK(CTG_READ, &tbCache->metaLock); - return TSDB_CODE_SUCCESS; - } - STableMeta *tbMeta = taosHashGet(tbCache->metaCache, tbName, strlen(tbName)); if (taosHashPut(tbCache->stbCache, &meta->suid, sizeof(meta->suid), &tbMeta, POINTER_BYTES) != 0) { CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock); @@ -1721,7 +1722,7 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui CTG_UNLOCK(CTG_READ, &tbCache->metaLock); - ctgDebug("stb updated to stbCache, dbFName:%s, tbName:%s, tbType:%d", dbFName, tbName, meta->tableType); + ctgDebug("stb updated to stbCache, dbFName:%s, tbName:%s, tbType:%d, suid:%" PRIx64 ",ma:%p", dbFName, tbName, meta->tableType, meta->suid, tbMeta); SSTableMetaVersion metaRent = {.dbId = dbId, .suid = meta->suid, .sversion = meta->sversion, .tversion = meta->tversion}; strcpy(metaRent.dbFName, dbFName); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 4881f23134..dd0bcbff0e 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -333,6 +333,8 @@ typedef struct SScanInfo { typedef struct STableScanInfo { void* dataReader; + SReadHandle readHandle; + SFileBlockLoadRecorder readRecorder; int64_t numOfRows; int64_t elapsedTime; @@ -348,6 +350,11 @@ typedef struct STableScanInfo { SArray* pColMatchInfo; int32_t numOfOutput; + SExprInfo* pPseudoExpr; + int32_t numOfPseudoExpr; + SqlFunctionCtx* pPseudoCtx; +// int32_t* rowCellInfoOffset; + SQueryTableDataCond cond; int32_t scanFlag; // table scan flag to denote if it is a repeat/reverse/main scan int32_t dataBlockLoadFlag; @@ -364,9 +371,18 @@ typedef struct STagScanInfo { STableGroupInfo *pTableGroups; } STagScanInfo; +typedef enum EStreamScanMode { + STREAM_SCAN_FROM_READERHANDLE = 1, + STREAM_SCAN_FROM_RES, + STREAM_SCAN_FROM_UPDATERES, + STREAM_SCAN_FROM_DATAREADER, +} EStreamScanMode; + typedef struct SStreamBlockScanInfo { SArray* pBlockLists; // multiple SSDatablock. SSDataBlock* pRes; // result SSDataBlock + SSDataBlock* pUpdateRes; // update SSDataBlock + int32_t updateResIndex; int32_t blockType; // current block type int32_t validBlockIndex; // Is current data has returned? SColumnInfo* pCols; // the output column info @@ -376,8 +392,12 @@ typedef struct SStreamBlockScanInfo { SArray* pColMatchInfo; // SNode* pCondition; SArray* tsArray; - SUpdateInfo* pUpdateInfo; + SUpdateInfo* pUpdateInfo; int32_t primaryTsIndex; // primary time stamp slot id + void* pDataReader; + EStreamScanMode scanMode; + SOperatorInfo* pOperatorDumy; + SInterval interval; // if the upstream is an interval operator, the interval info is also kept here. } SStreamBlockScanInfo; typedef struct SSysTableScanInfo { @@ -544,7 +564,7 @@ typedef struct SStateWindowOperatorInfo { SAggSupporter aggSup; SGroupResInfo groupResInfo; SWindowRowsSup winSup; - int32_t colIndex; // start row index + SColumn stateCol; // start row index bool hasKey; SStateKeys stateKey; int32_t tsSlotId; // primary timestamp column slot id @@ -616,7 +636,7 @@ int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t int32_t initAggInfo(SOptrBasicInfo* pBasicInfo, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, size_t keyBufSize, const char* pkey); void initResultSizeInfo(SOperatorInfo* pOperator, int32_t numOfRows); -void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo *pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf); +void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pBuf); void finalizeMultiTupleQueryResult(int32_t numOfOutput, SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset); void doApplyFunctions(SExecTaskInfo* taskInfo, SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData* pTimeWindowData, int32_t offset, @@ -628,7 +648,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total, SArray* pColList); void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, STimeWindow* win); -int32_t getTableScanOrder(SOperatorInfo* pOperator); +int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag); void doSetOperatorCompleted(SOperatorInfo* pOperator); void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock); @@ -638,18 +658,25 @@ void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWin void cleanupAggSup(SAggSupporter* pAggSup); void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle); +SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode); +SColumn extractColumnFromColumnNode(SColumnNode* pColNode); SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo); SSDataBlock* loadNextDataBlock(void* param); void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset); +SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols, + int32_t type); +SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* numOfExprs); +SSDataBlock* createResDataBlock(SDataBlockDescNode* pNode); +int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode); + SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pResultRowInfo, char* pData, int16_t bytes, bool masterscan, uint64_t groupId, SExecTaskInfo* pTaskInfo, bool isIntervalQuery, SAggSupporter* pSup); -SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCond* pCond, int32_t numOfOutput, int32_t dataLoadFlag, const uint8_t* scanInfo, - SArray* pColMatchInfo, SSDataBlock* pResBlock, SNode* pCondition, SInterval* pInterval, double sampleRatio, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, tsdbReaderT pDataReader, SReadHandle* pHandle, SExecTaskInfo* pTaskInfo); SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo, int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); @@ -678,14 +705,15 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx SExprInfo* pScalarExprInfo, int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo* pTaskInfo); -SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, - SArray* pTableIdList, SExecTaskInfo* pTaskInfo, SNode* pConditions); +SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, void* pDataReader, SSDataBlock* pResBlock, + SArray* pColList, SArray* pTableIdList, SExecTaskInfo* pTaskInfo, + SNode* pConditions, SOperatorInfo* pOperatorDumy); SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SInterval* pInterval, STimeWindow* pWindow, SSDataBlock* pResBlock, int32_t fillType, SNodeListNode* fillVal, bool multigroupResult, SExecTaskInfo* pTaskInfo); SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, - SSDataBlock* pResBlock, STimeWindowAggSupp *pTwAggSupp, int32_t tsSlotId, SExecTaskInfo* pTaskInfo); + SSDataBlock* pResBlock, STimeWindowAggSupp *pTwAggSupp, int32_t tsSlotId, SColumn* pStateKeyCol, SExecTaskInfo* pTaskInfo); SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SArray* pGroupColList, SExecTaskInfo* pTaskInfo, @@ -704,7 +732,7 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntim int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBlock* pSrcBlock, SqlFunctionCtx* pCtx, int32_t numOfOutput, SArray* pPseudoList); -void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, bool createDummyCol); +void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, int32_t scanFlag, bool createDummyCol); void copyTsColoum(SSDataBlock* pRes, SqlFunctionCtx* pCtx, int32_t numOfOutput); @@ -733,6 +761,15 @@ bool aggDecodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasi int32_t length); void aggEncodeResultRow(SOperatorInfo* pOperator, SAggSupporter* pSup, SOptrBasicInfo* pInfo, char** result, int32_t* length); +STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, + SInterval* pInterval, int32_t precision, STimeWindow* win); +int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, + TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item, + int32_t order); +int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order); + +void doClearWindow(SIntervalAggOperatorInfo* pInfo, char* pData, int16_t bytes, + uint64_t groupId, int32_t numOfOutput); #ifdef __cplusplus } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index a5bc1fdf58..f04ab24fe7 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -155,9 +155,8 @@ SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, void operatorDummyCloseFn(void* param, int32_t numOfCols) {} -static int32_t doCopyToSDataBlock(SExecTaskInfo *taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, - SGroupResInfo* pGroupResInfo, int32_t orderType, int32_t* rowCellOffset, - SqlFunctionCtx* pCtx); +static int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, + int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx, int32_t numOfExprs); static void initCtxOutputBuffer(SqlFunctionCtx* pCtx, int32_t size); static void setResultBufSize(STaskAttr* pQueryAttr, SResultInfo* pResultInfo); @@ -344,6 +343,28 @@ SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId, return pResultRow; } +void doClearWindow(SIntervalAggOperatorInfo* pInfo, char* pData, int16_t bytes, + uint64_t groupId, int32_t numOfOutput) { + SAggSupporter* pSup = &pInfo->aggSup; + SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId); + SResultRowPosition* p1 = + (SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf, + GET_RES_WINDOW_KEY_LEN(bytes)); + SResultRow* pResult = getResultRowByPos(pSup->pResultBuf, p1); + SqlFunctionCtx* pCtx = pInfo->binfo.pCtx; + for (int32_t i = 0; i < numOfOutput; ++i) { + pCtx[i].resultInfo = getResultCell(pResult, i, pInfo->binfo.rowCellInfoOffset); + struct SResultRowEntryInfo* pResInfo = pCtx[i].resultInfo; + if (fmIsWindowPseudoColumnFunc(pCtx[i].functionId)) { + continue; + } + pResInfo->initialized = false; + if (pCtx[i].functionId != -1) { + pCtx[i].fpSet.init(&pCtx[i], pResInfo); + } + } +} + /** * the struct of key in hash table * +----------+---------------+ @@ -654,7 +675,7 @@ static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* p } static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, - bool createDummyCol); + int32_t scanFlag, bool createDummyCol); static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) { @@ -665,12 +686,12 @@ static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SqlFunctionCtx* pC } } -void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, +void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, int32_t scanFlag, bool createDummyCol) { if (pBlock->pBlockAgg != NULL) { doSetInputDataBlockInfo(pOperator, pCtx, pBlock, order); } else { - doSetInputDataBlock(pOperator, pCtx, pBlock, order, createDummyCol); + doSetInputDataBlock(pOperator, pCtx, pBlock, order, scanFlag, createDummyCol); } } @@ -717,14 +738,14 @@ static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunc } static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order, - bool createDummyCol) { + int32_t scanFlag, bool createDummyCol) { int32_t code = TSDB_CODE_SUCCESS; for (int32_t i = 0; i < pOperator->numOfExprs; ++i) { pCtx[i].order = order; pCtx[i].size = pBlock->info.rows; pCtx[i].pSrcBlock = pBlock; - pCtx[i].currentStage = MAIN_SCAN; + pCtx[i].scanFlag = scanFlag; SInputColumnInfoData* pInput = &pCtx[i].input; pInput->uid = pBlock->info.uid; @@ -740,7 +761,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt pInput->numOfRows = pBlock->info.rows; pInput->startRowIndex = 0; - // the last parameter is the timestamp column + // NOTE: the last parameter is the primary timestamp column if (fmIsTimelineFunc(pCtx[i].functionId) && (j == pOneExpr->base.numOfParams - 1)) { pInput->pPTS = pInput->pData[j]; } @@ -804,23 +825,22 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt return code; } -static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) { +static int32_t doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SqlFunctionCtx* pCtx) { for (int32_t k = 0; k < pOperator->numOfExprs; ++k) { if (functionNeedToExecute(&pCtx[k])) { pCtx[k].startTs = startTs; - // this can be set during create the struct // todo add a dummy funtion to avoid process check if (pCtx[k].fpSet.process != NULL) { int32_t code = pCtx[k].fpSet.process(&pCtx[k]); if (code != TSDB_CODE_SUCCESS) { - qError("%s call aggregate function error happens, code : %s", - GET_TASKID(pOperator->pTaskInfo), tstrerror(code)); - pOperator->pTaskInfo->code = code; - longjmp(pOperator->pTaskInfo->env, code); + qError("%s aggregate function error happens, code: %s", GET_TASKID(pOperator->pTaskInfo), tstrerror(code)); + return code; } } } } + + return TSDB_CODE_SUCCESS; } static void setPseudoOutputColInfo(SSDataBlock* pResult, SqlFunctionCtx* pCtx, SArray* pPseudoList) { @@ -877,6 +897,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc scalarCalculate(pExpr[k].pExpr->_optrRoot.pRootNode, pBlockList, &dest); int32_t startOffset = createNewColModel ? 0 : pResult->info.rows; + colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity); colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows); numOfRows = dest.numOfRows; @@ -884,7 +905,8 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc } else if (pExpr[k].pExpr->nodeType == QUERY_NODE_FUNCTION) { ASSERT(!fmIsAggFunc(pfCtx->functionId)); - if (fmIsPseudoColumnFunc(pfCtx->functionId)) { + // _rowts/_c0, not tbname column + if (fmIsPseudoColumnFunc(pfCtx->functionId) && (!fmIsScanPseudoColumnFunc(pfCtx->functionId))) { // do nothing } else if (fmIsNonstandardSQLFunc(pfCtx->functionId)) { SResultRowEntryInfo* pResInfo = GET_RES_INFO(&pCtx[k]); @@ -915,6 +937,7 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc } int32_t startOffset = createNewColModel ? 0 : pResult->info.rows; + colInfoDataEnsureCapacity(pResColData, startOffset, pResult->info.capacity); colDataMergeCol(pResColData, startOffset, &pResult->info.capacity, &idata, dest.numOfRows); numOfRows = dest.numOfRows; @@ -975,18 +998,22 @@ static bool functionNeedToExecute(SqlFunctionCtx* pCtx) { return false; } + if (pCtx->scanFlag == REPEAT_SCAN) { + return fmIsRepeatScanFunc(pCtx->functionId); + } + if (isRowEntryCompleted(pResInfo)) { return false; } - if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) { - // return QUERY_IS_ASC_QUERY(pQueryAttr); - } - - // denote the order type - if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) { - // return pCtx->param[0].i == pQueryAttr->order.order; - } +// if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_FIRST) { +// // return QUERY_IS_ASC_QUERY(pQueryAttr); +// } +// +// // denote the order type +// if ((functionId == FUNCTION_LAST_DST || functionId == FUNCTION_LAST)) { +// // return pCtx->param[0].i == pQueryAttr->order.order; +// } // in the reverse table scan, only the following functions need to be executed // if (IS_REVERSE_SCAN(pRuntimeEnv) || @@ -1921,7 +1948,7 @@ void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t cleanupResultRowEntry(pEntry); pCtx[i].resultInfo = pEntry; - pCtx[i].currentStage = stage; + pCtx[i].scanFlag = stage; // set the timestamp output buffer for top/bottom/diff query // int32_t fid = pCtx[i].functionId; @@ -2188,7 +2215,7 @@ void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* p * @param result */ int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf, SGroupResInfo* pGroupResInfo, - int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx) { + int32_t orderType, int32_t* rowCellOffset, SqlFunctionCtx* pCtx, int32_t numOfExprs) { int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows @@ -2222,13 +2249,12 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprIn pGroupResInfo->index += 1; - for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) { + for (int32_t j = 0; j < numOfExprs; ++j) { int32_t slotId = pExprInfo[j].base.resSchema.slotId; pCtx[j].resultInfo = getResultCell(pRow, j, rowCellOffset); if (pCtx[j].fpSet.finalize) { - int32_t code = TSDB_CODE_SUCCESS; - code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); + int32_t code = pCtx[j].fpSet.finalize(&pCtx[j], pBlock); if (TAOS_FAILED(code)) { qError("%s build result data block error, code %s", GET_TASKID(taskInfo), tstrerror(code)); taskInfo->code = code; @@ -2260,10 +2286,13 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* taskInfo, SSDataBlock* pBlock, SExprIn return 0; } -void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SExprInfo* pExprInfo, - SDiskbasedBuf* pBuf) { +void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo, SDiskbasedBuf* pBuf) { assert(pGroupResInfo->currentGroup <= pGroupResInfo->totalGroup); + SExprInfo* pExprInfo = pOperator->pExpr; + int32_t numOfExprs = pOperator->numOfExprs; + SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; + int32_t* rowCellOffset = pbInfo->rowCellInfoOffset; SSDataBlock* pBlock = pbInfo->pRes; SqlFunctionCtx* pCtx = pbInfo->pCtx; @@ -2274,7 +2303,7 @@ void doBuildResultDatablock(SExecTaskInfo *taskInfo, SOptrBasicInfo* pbInfo, SGr } int32_t orderType = TSDB_ORDER_ASC; - doCopyToSDataBlock(taskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx); + doCopyToSDataBlock(pTaskInfo, pBlock, pExprInfo, pBuf, pGroupResInfo, orderType, rowCellOffset, pCtx, numOfExprs); // add condition (pBlock->info.rows >= 1) just to runtime happy blockDataUpdateTsWindow(pBlock); @@ -3506,7 +3535,7 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) { break; } - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, true); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pDataBlock, TSDB_ORDER_ASC, MAIN_SCAN, true); // updateOutputBuf(&pInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor, // pOperator->pRuntimeEnv, true); doMergeImpl(pOperator, pOperator->numOfExprs, pDataBlock); @@ -3671,17 +3700,24 @@ _error: return NULL; } -int32_t getTableScanOrder(SOperatorInfo* pOperator) { - if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { +int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scanFlag) { + // todo add more information about exchange operation + if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) { + *order = TSDB_ORDER_ASC; + *scanFlag = MAIN_SCAN; + return TSDB_CODE_SUCCESS; + } else if (pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) { + STableScanInfo* pTableScanInfo = pOperator->info; + *order = pTableScanInfo->cond.order; + *scanFlag = pTableScanInfo->scanFlag; + return TSDB_CODE_SUCCESS; + } else { if (pOperator->pDownstream == NULL || pOperator->pDownstream[0] == NULL) { - return TSDB_ORDER_ASC; + return TSDB_CODE_INVALID_PARA; } else { - return getTableScanOrder(pOperator->pDownstream[0]); + return getTableScanInfo(pOperator->pDownstream[0], order, scanFlag); } } - - STableScanInfo* pTableScanInfo = pOperator->info; - return pTableScanInfo->cond.order; } // this is a blocking operator @@ -3694,9 +3730,11 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { SAggOperatorInfo* pAggInfo = pOperator->info; SOptrBasicInfo* pInfo = &pAggInfo->binfo; - SOperatorInfo* downstream = pOperator->pDownstream[0]; + int32_t order = TSDB_ORDER_ASC; + int32_t scanFlag = MAIN_SCAN; + while (1) { publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC); SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream); @@ -3705,26 +3743,28 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) { if (pBlock == NULL) { break; } - // if (pAggInfo->current != NULL) { - // setTagValue(pOperator, pAggInfo->current->pTable, pInfo->pCtx, pOperator->numOfExprs); - // } - int32_t order = getTableScanOrder(pOperator); + int32_t code = getTableScanInfo(pOperator, &order, &scanFlag); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } // there is an scalar expression that needs to be calculated before apply the group aggregation. if (pAggInfo->pScalarExprInfo != NULL) { - int32_t code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, - pAggInfo->numOfScalarExpr, NULL); + code = projectApplyFunctions(pAggInfo->pScalarExprInfo, pBlock, pBlock, pAggInfo->pScalarCtx, + pAggInfo->numOfScalarExpr, NULL); if (code != TSDB_CODE_SUCCESS) { - pTaskInfo->code = code; - longjmp(pTaskInfo->env, pTaskInfo->code); + longjmp(pTaskInfo->env, code); } } // the pDataBlock are always the same one, no need to call this again setExecutionContext(pOperator->numOfExprs, pBlock->info.groupId, pTaskInfo, pAggInfo); - setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, true); - doAggregateImpl(pOperator, 0, pInfo->pCtx); + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, true); + code = doAggregateImpl(pOperator, 0, pInfo->pCtx); + if (code != 0) { + longjmp(pTaskInfo->env, code); + } #if 0 // test for encode/decode result info if(pOperator->encodeResultRow){ @@ -3766,7 +3806,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator) { } blockDataEnsureCapacity(pInfo->pRes, pOperator->resultInfo.capacity); - doBuildResultDatablock(pTaskInfo, pInfo, &pAggInfo->groupResInfo, pOperator->pExpr, pAggInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, pInfo, &pAggInfo->groupResInfo, pAggInfo->aggSup.pResultBuf); if (pInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pAggInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); } @@ -4004,6 +4044,9 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { } #endif + int32_t order = 0; + int32_t scanFlag = 0; + SOperatorInfo* downstream = pOperator->pDownstream[0]; while (1) { @@ -4035,15 +4078,14 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { // } // the pDataBlock are always the same one, no need to call this again - int32_t order = getTableScanOrder(pOperator->pDownstream[0]); + int32_t code = getTableScanInfo(pOperator->pDownstream[0], &order, &scanFlag); - setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, false); + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false); blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows); - pTaskInfo->code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs, - pProjectInfo->pPseudoColInfo); - if (pTaskInfo->code != TSDB_CODE_SUCCESS) { - longjmp(pTaskInfo->env, pTaskInfo->code); + code = projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfExprs, pProjectInfo->pPseudoColInfo); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); } int32_t status = handleLimitOffset(pOperator, pBlock); @@ -4565,7 +4607,7 @@ static SResSchema createResSchema(int32_t type, int32_t bytes, int32_t slotId, i return s; } -static SColumn* createColumn(int32_t blockId, int32_t slotId, SDataType* pType) { +static SColumn* createColumn(int32_t blockId, int32_t slotId, int32_t colId, SDataType* pType) { SColumn* pCol = taosMemoryCalloc(1, sizeof(SColumn)); if (pCol == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -4573,9 +4615,10 @@ static SColumn* createColumn(int32_t blockId, int32_t slotId, SDataType* pType) } pCol->slotId = slotId; - pCol->bytes = pType->bytes; - pCol->type = pType->type; - pCol->scale = pType->scale; + pCol->colId = colId; + pCol->bytes = pType->bytes; + pCol->type = pType->type; + pCol->scale = pType->scale; pCol->precision = pType->precision; pCol->dataBlockId = blockId; @@ -4618,7 +4661,7 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* SDataType* pType = &pColNode->node.resType; pExp->base.resSchema = createResSchema(pType->type, pType->bytes, pTargetNode->slotId, pType->scale, pType->precision, pColNode->colName); - pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pType); + pExp->base.pParam[0].pCol = createColumn(pColNode->dataBlockId, pColNode->slotId, pColNode->colId, pType); pExp->base.pParam[0].type = FUNC_PARAM_TYPE_COLUMN; } else if (type == QUERY_NODE_VALUE) { pExp->pExpr->nodeType = QUERY_NODE_VALUE; @@ -4642,8 +4685,22 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* pExp->pExpr->_function.functionId = pFuncNode->funcId; pExp->pExpr->_function.pFunctNode = pFuncNode; + strncpy(pExp->pExpr->_function.functionName, pFuncNode->functionName, tListLen(pExp->pExpr->_function.functionName)); +#if 1 + // todo refactor: add the parameter for tbname function + if (strcmp(pExp->pExpr->_function.functionName, "tbname") == 0) { + pFuncNode->pParameterList = nodesMakeList(); + ASSERT(LIST_LENGTH(pFuncNode->pParameterList) == 0); + SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE); + if (NULL == res) { // todo handle error + } else { + res->node.resType = (SDataType) {.bytes = sizeof(int64_t), .type = TSDB_DATA_TYPE_BIGINT}; + nodesListAppend(pFuncNode->pParameterList, res); + } + } +#endif int32_t numOfParam = LIST_LENGTH(pFuncNode->pParameterList); @@ -4656,7 +4713,7 @@ SExprInfo* createExprInfo(SNodeList* pNodeList, SNodeList* pGroupKeys, int32_t* SColumnNode* pcn = (SColumnNode*)p1; pExp->base.pParam[j].type = FUNC_PARAM_TYPE_COLUMN; - pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, &pcn->node.resType); + pExp->base.pParam[j].pCol = createColumn(pcn->dataBlockId, pcn->slotId, pcn->colId, &pcn->node.resType); } else if (p1->type == QUERY_NODE_VALUE) { SValueNode* pvn = (SValueNode*)p1; pExp->base.pParam[j].type = FUNC_PARAM_TYPE_VALUE; @@ -4704,58 +4761,29 @@ static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t uint64_t queryId, uint64_t taskId); static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo); static SArray* extractColumnInfo(SNodeList* pNodeList); -static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols, - int32_t type); static SArray* createSortInfo(SNodeList* pNodeList); static SArray* extractPartitionColInfo(SNodeList* pNodeList); -static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode); static void setJoinColumnInfo(SColumnInfo* pColumn, const SColumnNode* pColumnNode); -static SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) { - SInterval interval = { - .interval = pTableScanNode->interval, - .sliding = pTableScanNode->sliding, - .intervalUnit = pTableScanNode->intervalUnit, - .slidingUnit = pTableScanNode->slidingUnit, - .offset = pTableScanNode->offset, - }; - - return interval; -} - SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, uint64_t queryId, uint64_t taskId, STableGroupInfo* pTableGroupInfo) { int32_t type = nodeType(pPhyNode); if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) { if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) { - SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode; - int32_t numOfCols = 0; tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId); if (pDataReader == NULL && terrno != 0) { return NULL; } - SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc; + SOperatorInfo* pOperator = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo); - SArray* pColList = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID); - SSDataBlock* pResBlock = createResDataBlock(pDescNode); - - SQueryTableDataCond cond = {0}; - int32_t code = initQueryTableDataCond(&cond, pTableScanNode); - if (code != TSDB_CODE_SUCCESS) { - return NULL; - } - - SInterval interval = extractIntervalInfo(pTableScanNode); - SOperatorInfo* pOperator = createTableScanOperatorInfo( - pDataReader, &cond, numOfCols, pTableScanNode->dataRequired, pTableScanNode->scanSeq, pColList, pResBlock, - pScanPhyNode->node.pConditions, &interval, pTableScanNode->ratio, pTaskInfo); STableScanInfo* pScanInfo = pOperator->info; pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder; + return pOperator; } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) { SExchangePhysiNode* pExchange = (SExchangePhysiNode*)pPhyNode; @@ -4763,18 +4791,34 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, pExchange->pSrcEndPoints, pResBlock, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) { SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table. + STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode; - int32_t code = doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, - queryId, taskId); - SArray* tableIdList = extractTableIdList(pTableGroupInfo); + int32_t numOfCols = 0; + + tsdbReaderT pDataReader = NULL; + if (pHandle->vnode) { + pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableGroupInfo, (uint64_t)queryId, taskId); + } else { + doCreateTableGroup(pHandle->meta, pScanPhyNode->tableType, pScanPhyNode->uid, pTableGroupInfo, + queryId, taskId); + } + + if (pDataReader == NULL && terrno != 0) { + qDebug("pDataReader is NULL"); + // return NULL; + } else { + qDebug("pDataReader is not NULL"); + } SDataBlockDescNode* pDescNode = pScanPhyNode->node.pOutputDataBlockDesc; + SOperatorInfo* pOperatorDumy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo); + + SArray* tableIdList = extractTableIdList(pTableGroupInfo); SSDataBlock* pResBlock = createResDataBlock(pDescNode); - int32_t numOfCols = 0; SArray* pCols = extractColMatchInfo(pScanPhyNode->pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID); - SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pResBlock, pCols, tableIdList, pTaskInfo, - pScanPhyNode->node.pConditions); + SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle->reader, pDataReader, pResBlock, pCols, tableIdList, pTaskInfo, + pScanPhyNode->node.pConditions, pOperatorDumy); taosArrayDestroy(tableIdList); return pOperator; } else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) { @@ -4922,7 +4966,9 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc); int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId; - pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, tsSlotId, pTaskInfo); + SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pStateNode->pStateKey)->pExpr; + SColumn col = extractColumnFromColumnNode(pColNode); + pOptr = createStatewindowOperatorInfo(ops[0], pExprInfo, num, pResBlock, &as, tsSlotId, &col, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_JOIN == type) { SJoinPhysiNode* pJoinNode = (SJoinPhysiNode*)pPhyNode; SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc); @@ -4945,7 +4991,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo return pOptr; } -static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) { +int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode) { pCond->loadExternalRows = false; pCond->order = pTableScanNode->scanSeq[0] > 0 ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; @@ -4987,6 +5033,17 @@ static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableSc return TSDB_CODE_SUCCESS; } +SColumn extractColumnFromColumnNode(SColumnNode* pColNode) { + SColumn c = {0}; + c.slotId = pColNode->slotId; + c.colId = pColNode->colId; + c.type = pColNode->node.resType.type; + c.bytes = pColNode->node.resType.bytes; + c.scale = pColNode->node.resType.scale; + c.precision = pColNode->node.resType.precision; + return c; +} + SArray* extractColumnInfo(SNodeList* pNodeList) { size_t numOfCols = LIST_LENGTH(pNodeList); SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn)); @@ -5001,15 +5058,7 @@ SArray* extractColumnInfo(SNodeList* pNodeList) { if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) { SColumnNode* pColNode = (SColumnNode*)pNode->pExpr; - // todo extract method - SColumn c = {0}; - c.slotId = pColNode->slotId; - c.colId = pColNode->colId; - c.type = pColNode->node.resType.type; - c.bytes = pColNode->node.resType.bytes; - c.scale = pColNode->node.resType.scale; - c.precision = pColNode->node.resType.precision; - + SColumn c = extractColumnFromColumnNode(pColNode); taosArrayPush(pList, &c); } else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) { SValueNode* pValNode = (SValueNode*)pNode->pExpr; diff --git a/source/libs/executor/src/groupoperator.c b/source/libs/executor/src/groupoperator.c index 5d22c13ec6..d8ccac8cea 100644 --- a/source/libs/executor/src/groupoperator.c +++ b/source/libs/executor/src/groupoperator.c @@ -268,7 +268,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) { SSDataBlock* pRes = pInfo->binfo.pRes; if (pOperator->status == OP_RES_TO_RETURN) { - doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { pOperator->status = OP_EXEC_DONE; } @@ -287,7 +287,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) { } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, MAIN_SCAN, true); // there is an scalar expression that needs to be calculated right before apply the group aggregation. if (pInfo->pScalarExprInfo != NULL) { @@ -317,7 +317,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) { initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, false); while(1) { - doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); doFilter(pInfo->pCondition, pRes); bool hasRemain = hasRemainDataInCurrentGroup(&pInfo->groupResInfo); diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index eaacb561d5..c6cb01e8fb 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -13,9 +13,8 @@ * along with this program. If not, see . */ -#include -#include "filter.h" #include "function.h" +#include "filter.h" #include "functionMgt.h" #include "os.h" #include "querynodes.h" @@ -261,6 +260,53 @@ static void prepareForDescendingScan(STableScanInfo* pTableScanInfo, SqlFunction pTableScanInfo->cond.order = TSDB_ORDER_DESC; } +static void addTagPseudoColumnData(STableScanInfo* pTableScanInfo, SSDataBlock* pBlock) { + // currently only the tbname pseudo column + if (pTableScanInfo->numOfPseudoExpr == 0) { + return; + } + + SMetaReader mr = {0}; + metaReaderInit(&mr, pTableScanInfo->readHandle.meta, 0); + metaGetTableEntryByUid(&mr, pBlock->info.uid); + + for (int32_t j = 0; j < pTableScanInfo->numOfPseudoExpr; ++j) { + SExprInfo* pExpr = &pTableScanInfo->pPseudoExpr[j]; + + int32_t dstSlotId = pExpr->base.resSchema.slotId; + + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotId); + colInfoDataEnsureCapacity(pColInfoData, 0, pBlock->info.rows); + + int32_t functionId = pExpr->pExpr->_function.functionId; + + // this is to handle the tbname + if (fmIsScanPseudoColumnFunc(functionId)) { + struct SScalarFuncExecFuncs fpSet = {0}; + fmGetScalarFuncExecFuncs(functionId, &fpSet); + + SColumnInfoData infoData = {0}; + infoData.info.type = TSDB_DATA_TYPE_BIGINT; + infoData.info.bytes = sizeof(uint64_t); + colInfoDataEnsureCapacity(&infoData, 0, 1); + + colDataAppendInt64(&infoData, 0, &pBlock->info.uid); + SScalarParam srcParam = { + .numOfRows = pBlock->info.rows, .param = pTableScanInfo->readHandle.meta, .columnData = &infoData}; + + SScalarParam param = {.columnData = pColInfoData}; + fpSet.process(&srcParam, 1, ¶m); + } else { // these are tags + const char* p = metaGetTableTagVal(&mr.me, pExpr->base.pParam[0].pCol->colId); + for (int32_t i = 0; i < pBlock->info.rows; ++i) { + colDataAppend(pColInfoData, i, p, (p == NULL)); + } + } + } + + metaReaderClear(&mr); +} + static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) { STableScanInfo* pTableScanInfo = pOperator->info; SSDataBlock* pBlock = pTableScanInfo->pResBlock; @@ -284,6 +330,11 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) { continue; } + // currently only the tbname pseudo column + if (pTableScanInfo->numOfPseudoExpr > 0) { + addTagPseudoColumnData(pTableScanInfo, pBlock); + } + return pBlock; } @@ -314,8 +365,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) { STimeWindow* pWin = &pTableScanInfo->cond.twindow; qDebug("%s start to repeat ascending order scan data blocks due to query func required, qrange:%" PRId64 - "-%" PRId64, - GET_TASKID(pTaskInfo), pWin->skey, pWin->ekey); + "-%" PRId64, GET_TASKID(pTaskInfo), pWin->skey, pWin->ekey); // do prepare for the next round table scan operation tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond); @@ -359,10 +409,29 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) { return NULL; } -SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCond* pCond, int32_t numOfOutput, - int32_t dataLoadFlag, const uint8_t* scanInfo, SArray* pColMatchInfo, - SSDataBlock* pResBlock, SNode* pCondition, SInterval* pInterval, - double sampleRatio, SExecTaskInfo* pTaskInfo) { +SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode) { + SInterval interval = { + .interval = pTableScanNode->interval, + .sliding = pTableScanNode->sliding, + .intervalUnit = pTableScanNode->intervalUnit, + .slidingUnit = pTableScanNode->slidingUnit, + .offset = pTableScanNode->offset, + }; + + return interval; +} + +static void destroyTableScanOperatorInfo(void* param, int32_t numOfOutput) { + STableScanInfo* pTableScanInfo = (STableScanInfo*)param; + taosMemoryFree(pTableScanInfo->pResBlock); + tsdbCleanupReadHandle(pTableScanInfo->dataReader); + + if (pTableScanInfo->pColMatchInfo != NULL) { + taosArrayDestroy(pTableScanInfo->pColMatchInfo); + } +} + +SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, tsdbReaderT pDataReader, SReadHandle* readHandle, SExecTaskInfo* pTaskInfo) { STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { @@ -373,27 +442,42 @@ SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCon return NULL; } - pInfo->cond = *pCond; - pInfo->scanInfo = (SScanInfo){.numOfAsc = scanInfo[0], .numOfDesc = scanInfo[1]}; + SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc; - pInfo->interval = *pInterval; - pInfo->sampleRatio = sampleRatio; - pInfo->dataBlockLoadFlag = dataLoadFlag; - pInfo->pResBlock = pResBlock; - pInfo->pFilterNode = pCondition; - pInfo->dataReader = pDataReader; - pInfo->scanFlag = MAIN_SCAN; - pInfo->pColMatchInfo = pColMatchInfo; + int32_t numOfCols = 0; + SArray* pColList = extractColMatchInfo(pTableScanNode->scan.pScanCols, pDescNode, &numOfCols, COL_MATCH_FROM_COL_ID); - pOperator->name = "TableScanOperator"; // for dubug purpose + int32_t code = initQueryTableDataCond(&pInfo->cond, pTableScanNode); + if (code != TSDB_CODE_SUCCESS) { + return NULL; + } + + if (pTableScanNode->scan.pScanPseudoCols != NULL) { + pInfo->pPseudoExpr = createExprInfo(pTableScanNode->scan.pScanPseudoCols, NULL, &pInfo->numOfPseudoExpr); + pInfo->pPseudoCtx = createSqlFunctionCtx(pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, &pInfo->rowCellInfoOffset); + } + + pInfo->scanInfo = (SScanInfo){.numOfAsc = pTableScanNode->scanSeq[0], .numOfDesc = pTableScanNode->scanSeq[1]}; + + pInfo->readHandle = *readHandle; + pInfo->interval = extractIntervalInfo(pTableScanNode); + pInfo->sampleRatio = pTableScanNode->ratio; + pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired; + pInfo->pResBlock = createResDataBlock(pDescNode); + pInfo->pFilterNode = pTableScanNode->scan.node.pConditions; + pInfo->dataReader = pDataReader; + pInfo->scanFlag = MAIN_SCAN; + pInfo->pColMatchInfo = pColList; + + pOperator->name = "TableScanOperator"; // for debug purpose pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN; - pOperator->blocking = false; - pOperator->status = OP_NOT_OPENED; - pOperator->info = pInfo; - pOperator->numOfExprs = numOfOutput; - pOperator->pTaskInfo = pTaskInfo; + pOperator->blocking = false; + pOperator->status = OP_NOT_OPENED; + pOperator->info = pInfo; + pOperator->numOfExprs = numOfCols; + pOperator->pTaskInfo = pTaskInfo; - pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScan, NULL, NULL, NULL, NULL, NULL, NULL); + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doTableScan, NULL, NULL, destroyTableScanOperatorInfo, NULL, NULL, NULL); static int32_t cost = 0; @@ -515,7 +599,40 @@ static void doClearBufferedBlocks(SStreamBlockScanInfo* pInfo) { taosArrayClear(pInfo->pBlockLists); } -static SSDataBlock* getUpdateDataBlock(SStreamBlockScanInfo* pInfo) { +static bool prepareDataScan(SStreamBlockScanInfo* pInfo) { + SSDataBlock* pSDB = pInfo->pUpdateRes; + if (pInfo->updateResIndex < pSDB->info.rows) { + SColumnInfoData* pColDataInfo = taosArrayGet(pSDB->pDataBlock, 0); + TSKEY *tsCols = (TSKEY*)pColDataInfo->pData; + SResultRowInfo dumyInfo; + dumyInfo.cur.pageId = -1; + STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[pInfo->updateResIndex], &pInfo->interval, + pInfo->interval.precision, NULL); + STableScanInfo* pTableScanInfo = pInfo->pOperatorDumy->info; + pTableScanInfo->cond.twindow = win; + tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond); + pInfo->updateResIndex += getNumOfRowsInTimeWindow(&pSDB->info, tsCols, pInfo->updateResIndex, + win.ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC); + pTableScanInfo->scanTimes = 0; + return true; + } else { + return false; + } +} + +static SSDataBlock* doDataScan(SStreamBlockScanInfo* pInfo) { + SSDataBlock* pResult = NULL; + pResult = doTableScan(pInfo->pOperatorDumy); + if (pResult == NULL) { + if (prepareDataScan(pInfo)) { + // scan next window data + pResult = doTableScan(pInfo->pOperatorDumy); + } + } + return pResult; +} + +static SSDataBlock* getUpdateDataBlock(SStreamBlockScanInfo* pInfo, bool invertible) { SColumnInfoData* pColDataInfo = taosArrayGet(pInfo->pRes->pDataBlock, pInfo->primaryTsIndex); TSKEY* ts = (TSKEY*)pColDataInfo->pData; for (int32_t i = 0; i < pInfo->pRes->info.rows; i++) { @@ -523,13 +640,19 @@ static SSDataBlock* getUpdateDataBlock(SStreamBlockScanInfo* pInfo) { taosArrayPush(pInfo->tsArray, ts + i); } } - if (taosArrayGetSize(pInfo->tsArray) > 0) { + int32_t size = taosArrayGetSize(pInfo->tsArray); + if (size > 0 && invertible) { // TODO(liuyao) get from tsdb // SSDataBlock* p = createOneDataBlock(pInfo->pRes, true); // p->info.type = STREAM_INVERT; // taosArrayClear(pInfo->tsArray); // return p; - return NULL; + SSDataBlock* p = createOneDataBlock(pInfo->pRes, false); + taosArraySet(p->pDataBlock, 0, pInfo->tsArray); + p->info.rows = size; + p->info.type = STREAM_REPROCESS; + taosArrayClear(pInfo->tsArray); + return p; } return NULL; } @@ -556,14 +679,23 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { int32_t current = pInfo->validBlockIndex++; return taosArrayGetP(pInfo->pBlockLists, current); } else { - if (total > 0) { - ASSERT(total == 2); - SSDataBlock* pRes = taosArrayGetP(pInfo->pBlockLists, 0); - SSDataBlock* pUpRes = taosArrayGetP(pInfo->pBlockLists, 1); - blockDataDestroy(pUpRes); - taosArrayClear(pInfo->pBlockLists); - return pRes; + if (pInfo->scanMode == STREAM_SCAN_FROM_RES) { + blockDataDestroy(pInfo->pUpdateRes); + pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; + return pInfo->pRes; + } else if (pInfo->scanMode == STREAM_SCAN_FROM_UPDATERES) { + blockDataCleanup(pInfo->pRes); + pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER; + return pInfo->pUpdateRes; + } else if (pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER) { + SSDataBlock* pSDB = doDataScan(pInfo); + if (pSDB == NULL) { + pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; + } else { + return pSDB; + } } + SDataBlockInfo* pBlockInfo = &pInfo->pRes->info; blockDataCleanup(pInfo->pRes); @@ -629,12 +761,18 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { if (rows == 0) { pOperator->status = OP_EXEC_DONE; - } else { - SSDataBlock* upRes = getUpdateDataBlock(pInfo); + } else if (pInfo->interval.interval > 0) { + SSDataBlock* upRes = getUpdateDataBlock(pInfo, true); //TODO(liuyao) get invertible from plan if (upRes) { - taosArrayPush(pInfo->pBlockLists, &(pInfo->pRes)); - taosArrayPush(pInfo->pBlockLists, &upRes); - return upRes; + pInfo->pUpdateRes = upRes; + if (upRes->info.type = STREAM_REPROCESS) { + pInfo->updateResIndex = 0; + prepareDataScan(pInfo); + pInfo->scanMode = STREAM_SCAN_FROM_UPDATERES; + } else if (upRes->info.type = STREAM_INVERT) { + pInfo->scanMode = STREAM_SCAN_FROM_RES; + return upRes; + } } } @@ -642,8 +780,9 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) { } } -SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pResBlock, SArray* pColList, - SArray* pTableIdList, SExecTaskInfo* pTaskInfo, SNode* pCondition) { +SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, void* pDataReader, + SSDataBlock* pResBlock, SArray* pColList, SArray* pTableIdList, + SExecTaskInfo* pTaskInfo, SNode* pCondition, SOperatorInfo* pOperatorDumy ) { SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { @@ -651,6 +790,8 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* goto _error; } + STableScanInfo* pSTInfo = (STableScanInfo*)pOperatorDumy->info; + int32_t numOfOutput = taosArrayGetSize(pColList); SArray* pColIds = taosArrayInit(4, sizeof(int16_t)); @@ -683,7 +824,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* } pInfo->primaryTsIndex = 0; // TODO(liuyao) get it from physical plan - pInfo->pUpdateInfo = updateInfoInit(60000, 0, 100); // TODO(liuyao) get it from physical plan + pInfo->pUpdateInfo = updateInfoInitP(&pSTInfo->interval, 10000); // TODO(liuyao) get watermark from physical plan if (pInfo->pUpdateInfo == NULL) { taosMemoryFreeClear(pInfo); taosMemoryFreeClear(pOperator); @@ -693,6 +834,10 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock* pInfo->readerHandle = streamReadHandle; pInfo->pRes = pResBlock; pInfo->pCondition = pCondition; + pInfo->pDataReader = pDataReader; + pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE; + pInfo->pOperatorDumy = pOperatorDumy; + pInfo->interval = pSTInfo->interval; pOperator->name = "StreamBlockScanOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN; @@ -1295,36 +1440,33 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) { char str[512] = {0}; int32_t count = 0; SMetaReader mr = {0}; + metaReaderInit(&mr, pInfo->readHandle.meta, 0); while (pInfo->curPos < pInfo->pTableGroups->numOfTables && count < pOperator->resultInfo.capacity) { STableKeyInfo* item = taosArrayGet(pa, pInfo->curPos); + metaGetTableEntryByUid(&mr, item->uid); for (int32_t j = 0; j < pOperator->numOfExprs; ++j) { SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId); // refactor later if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) { - metaReaderInit(&mr, pInfo->readHandle.meta, 0); - metaGetTableEntryByUid(&mr, item->uid); - STR_TO_VARSTR(str, mr.me.name); - metaReaderClear(&mr); - colDataAppend(pDst, count, str, false); - - // data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.pColumns->info.colId, type, bytes); - // dst = pColInfo->pData + count * pExprInfo[j].base.resSchema.bytes; - // doSetTagValueToResultBuf(dst, data, type, bytes); + } else { // it is a tag value + const char* p = metaGetTableTagVal(&mr.me, pExprInfo[j].base.pParam[0].pCol->colId); + colDataAppend(pDst, count, p, (p == NULL)); } - - count += 1; } + count += 1; if (++pInfo->curPos >= pInfo->pTableGroups->numOfTables) { pOperator->status = OP_EXEC_DONE; } } + metaReaderClear(&mr); + // qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_TASKID(pRuntimeEnv), count); if (pOperator->status == OP_EXEC_DONE) { setTaskStatus(pTaskInfo, TASK_COMPLETED); diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 0f3b1bda20..10dc482462 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -82,7 +82,7 @@ static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, T } // get the correct time window according to the handled timestamp -static STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, +STimeWindow getActiveTimeWindow(SDiskbasedBuf* pBuf, SResultRowInfo* pResultRowInfo, int64_t ts, SInterval* pInterval, int32_t precision, STimeWindow* win) { STimeWindow w = {0}; @@ -186,7 +186,7 @@ static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_se return forwardStep; } -static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) { +int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) { int32_t midPos = -1; int32_t numOfRows; @@ -249,7 +249,7 @@ static int32_t binarySearchForKey(char* pValue, int num, TSKEY key, int order) { return midPos; } -static int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, +int32_t getNumOfRowsInTimeWindow(SDataBlockInfo* pDataBlockInfo, TSKEY* pPrimaryColumn, int32_t startPos, TSKEY ekey, __block_search_fn_t searchFn, STableQueryInfo* item, int32_t order) { assert(startPos >= 0 && startPos < pDataBlockInfo->rows); @@ -775,7 +775,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { // setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfExprs); // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, MAIN_SCAN, true); STableQueryInfo* pTableQueryInfo = pInfo->pCurrent; setIntervalQueryRange(pTableQueryInfo, pBlock->info.window.skey, &pTaskInfo->window); @@ -806,10 +806,22 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) { return TSDB_CODE_SUCCESS; } +static bool compareVal(const char* v, const SStateKeys* pKey) { + if (IS_VAR_DATA_TYPE(pKey->type)) { + if (varDataLen(v) != varDataLen(pKey->pData)) { + return false; + } else { + return strncmp(varDataVal(v), varDataVal(pKey->pData), varDataLen(v)) == 0; + } + } else { + return memcmp(pKey->pData, v, pKey->bytes) == 0; + } +} + static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo* pInfo, SSDataBlock* pBlock) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; - SColumnInfoData* pStateColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->colIndex); + SColumnInfoData* pStateColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->stateCol.slotId); int64_t gid = pBlock->info.groupId; bool masterScan = true; @@ -822,20 +834,28 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI SWindowRowsSup* pRowSup = &pInfo->winSup; pRowSup->numOfRows = 0; + struct SColumnDataAgg* pAgg = NULL; for (int32_t j = 0; j < pBlock->info.rows; ++j) { - if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pBlock->pBlockAgg[pInfo->colIndex])) { + pAgg = (pBlock->pBlockAgg != NULL)? pBlock->pBlockAgg[pInfo->stateCol.slotId]: NULL; + if (colDataIsNull(pStateColInfoData, pBlock->info.rows, j, pAgg)) { continue; } char* val = colDataGetData(pStateColInfoData, j); if (!pInfo->hasKey) { - memcpy(pInfo->stateKey.pData, val, bytes); + // todo extract method + if (IS_VAR_DATA_TYPE(pInfo->stateKey.type)) { + varDataCopy(pInfo->stateKey.pData, val); + } else { + memcpy(pInfo->stateKey.pData, val, bytes); + } + pInfo->hasKey = true; doKeepNewWindowStartInfo(pRowSup, tsList, j); doKeepTuple(pRowSup, tsList[j]); - } else if (memcmp(pInfo->stateKey.pData, val, bytes) == 0) { + } else if (compareVal(val, &pInfo->stateKey)) { doKeepTuple(pRowSup, tsList[j]); if (j == 0 && pRowSup->startRowIndex != 0) { pRowSup->startRowIndex = 0; @@ -861,6 +881,13 @@ static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorI // here we start a new session window doKeepNewWindowStartInfo(pRowSup, tsList, j); doKeepTuple(pRowSup, tsList[j]); + + // todo extract method + if (IS_VAR_DATA_TYPE(pInfo->stateKey.type)) { + varDataCopy(pInfo->stateKey.pData, val); + } else { + memcpy(pInfo->stateKey.pData, val, bytes); + } } } @@ -888,7 +915,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) { SOptrBasicInfo* pBInfo = &pInfo->binfo; if (pOperator->status == OP_RES_TO_RETURN) { - doBuildResultDatablock(pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); return NULL; @@ -910,7 +937,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) { break; } - setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, MAIN_SCAN, true); doStateWindowAggImpl(pOperator, pInfo, pBlock); } @@ -921,7 +948,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator) { initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true); blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); - doBuildResultDatablock(pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); } @@ -948,7 +975,7 @@ static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator) { } blockDataEnsureCapacity(pBlock, pOperator->resultInfo.capacity); - doBuildResultDatablock(pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pBlock->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); @@ -988,6 +1015,20 @@ static void setInverFunction(SqlFunctionCtx* pCtx, int32_t num, EStreamType type } } } +static void doClearWindows(SIntervalAggOperatorInfo* pInfo, int32_t numOfOutput, SSDataBlock* pBlock) { + SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, pInfo->primaryTsIndex); + TSKEY *tsCols = (TSKEY*)pColDataInfo->pData; + int32_t step = 0; + for (int32_t i = 0; i < pBlock->info.rows; i += step) { + SResultRowInfo dumyInfo; + dumyInfo.cur.pageId = -1; + STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[i], &pInfo->interval, + pInfo->interval.precision, NULL); + step = getNumOfRowsInTimeWindow(&pBlock->info, tsCols, i, + win.ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC); + doClearWindow(pInfo, (char*)&win.skey, sizeof(TKEY), pBlock->info.groupId, numOfOutput); + } +} static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { SIntervalAggOperatorInfo* pInfo = pOperator->info; @@ -998,7 +1039,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { } if (pOperator->status == OP_RES_TO_RETURN) { - doBuildResultDatablock(pOperator->pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pInfo->binfo.pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { pOperator->status = OP_EXEC_DONE; } @@ -1024,10 +1065,14 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { // setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfExprs); // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, order, MAIN_SCAN, true); if (pInfo->invertible) { setInverFunction(pInfo->binfo.pCtx, pOperator->numOfExprs, pBlock->info.type); } + if (pBlock->info.type == STREAM_REPROCESS) { + doClearWindows(pInfo, pOperator->numOfExprs, pBlock); + continue; + } pUpdated = hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, 0); } @@ -1035,7 +1080,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) { initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated); blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity); - doBuildResultDatablock(pOperator->pTaskInfo, &pInfo->binfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); // TODO: remove for stream /*ASSERT(pInfo->binfo.pRes->info.rows > 0);*/ @@ -1265,7 +1310,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { SOptrBasicInfo* pBInfo = &pInfo->binfo; if (pOperator->status == OP_RES_TO_RETURN) { - doBuildResultDatablock(pOperator->pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); return NULL; @@ -1286,7 +1331,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, order, MAIN_SCAN, true); doSessionWindowAggImpl(pOperator, pInfo, pBlock); } @@ -1298,7 +1343,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator) { initGroupedResultInfo(&pInfo->groupResInfo, pInfo->aggSup.pResultRowHashTable, true); blockDataEnsureCapacity(pBInfo->pRes, pOperator->resultInfo.capacity); - doBuildResultDatablock(pOperator->pTaskInfo, pBInfo, &pInfo->groupResInfo, pOperator->pExpr, pInfo->aggSup.pResultBuf); + doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf); if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pInfo->groupResInfo)) { doSetOperatorCompleted(pOperator); } @@ -1334,7 +1379,7 @@ static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator) { // setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfExprs); // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, true); + setInputDataBlock(pOperator, pSliceInfo->binfo.pCtx, pBlock, order, MAIN_SCAN, true); // hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0); } @@ -1388,14 +1433,21 @@ _error: SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, STimeWindowAggSupp* pTwAggSup, int32_t tsSlotId, - SExecTaskInfo* pTaskInfo) { + SColumn* pStateKeyCol, SExecTaskInfo* pTaskInfo) { SStateWindowOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStateWindowOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { goto _error; } - pInfo->colIndex = -1; + pInfo->stateCol = *pStateKeyCol; + pInfo->stateKey.type = pInfo->stateCol.type; + pInfo->stateKey.bytes = pInfo->stateCol.bytes; + pInfo->stateKey.pData = taosMemoryCalloc(1, pInfo->stateCol.bytes); + if (pInfo->stateKey.pData == NULL) { + goto _error; + } + size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES; initResultSizeInfo(pOperator, 4096); @@ -1405,15 +1457,15 @@ SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInf pInfo->twAggSup = *pTwAggSup; initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window); - pInfo->tsSlotId = tsSlotId; - pOperator->name = "StateWindowOperator"; + pInfo->tsSlotId = tsSlotId; + pOperator->name = "StateWindowOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW; - pOperator->blocking = true; - pOperator->status = OP_NOT_OPENED; - pOperator->pExpr = pExpr; + pOperator->blocking = true; + pOperator->status = OP_NOT_OPENED; + pOperator->pExpr = pExpr; pOperator->numOfExprs = numOfCols; - pOperator->pTaskInfo = pTaskInfo; - pOperator->info = pInfo; + pOperator->pTaskInfo = pTaskInfo; + pOperator->info = pInfo; pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStateWindowAgg, NULL, NULL, destroyStateWindowOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL); diff --git a/source/libs/executor/test/indexexcutorTests.cpp b/source/libs/executor/test/index_executor_tests.cpp similarity index 100% rename from source/libs/executor/test/indexexcutorTests.cpp rename to source/libs/executor/test/index_executor_tests.cpp diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index 087e243497..807234a1b1 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -98,6 +98,15 @@ int32_t stateDurationFunction(SqlFunctionCtx* pCtx); bool getCsumFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); int32_t csumFunction(SqlFunctionCtx* pCtx); +bool getMavgFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); +bool mavgFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo); +int32_t mavgFunction(SqlFunctionCtx* pCtx); + +bool getSampleFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); +bool sampleFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo); +int32_t sampleFunction(SqlFunctionCtx* pCtx); +int32_t sampleFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); + bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv); #ifdef __cplusplus diff --git a/source/libs/function/inc/fnLog.h b/source/libs/function/inc/fnLog.h index f572948907..d85dd02433 100644 --- a/source/libs/function/inc/fnLog.h +++ b/source/libs/function/inc/fnLog.h @@ -10,12 +10,12 @@ extern "C" { #endif -#define fnFatal(...) { if (fnDebugFlag & DEBUG_FATAL) { taosPrintLog("FN FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} -#define fnError(...) { if (fnDebugFlag & DEBUG_ERROR) { taosPrintLog("FN ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} -#define fnWarn(...) { if (fnDebugFlag & DEBUG_WARN) { taosPrintLog("FN WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} -#define fnInfo(...) { if (fnDebugFlag & DEBUG_INFO) { taosPrintLog("FN ", DEBUG_INFO, 255, __VA_ARGS__); }} -#define fnDebug(...) { if (fnDebugFlag & DEBUG_DEBUG) { taosPrintLog("FN ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} -#define fnTrace(...) { if (fnDebugFlag & DEBUG_TRACE) { taosPrintLog("FN ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} +#define fnFatal(...) { if (fnDebugFlag & DEBUG_FATAL) { taosPrintLog("FN FATAL ", DEBUG_FATAL, 255, __VA_ARGS__); }} +#define fnError(...) { if (fnDebugFlag & DEBUG_ERROR) { taosPrintLog("FN ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); }} +#define fnWarn(...) { if (fnDebugFlag & DEBUG_WARN) { taosPrintLog("FN WARN ", DEBUG_WARN, 255, __VA_ARGS__); }} +#define fnInfo(...) { if (fnDebugFlag & DEBUG_INFO) { taosPrintLog("FN ", DEBUG_INFO, 255, __VA_ARGS__); }} +#define fnDebug(...) { if (fnDebugFlag & DEBUG_DEBUG) { taosPrintLog("FN ", DEBUG_DEBUG, dDebugFlag, __VA_ARGS__); }} +#define fnTrace(...) { if (fnDebugFlag & DEBUG_TRACE) { taosPrintLog("FN ", DEBUG_TRACE, dDebugFlag, __VA_ARGS__); }} #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index e165810e30..fc93008312 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -339,6 +339,53 @@ static int32_t translateCsum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return TSDB_CODE_SUCCESS; } +static int32_t translateMavg(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + if (2 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + + SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); + if (QUERY_NODE_COLUMN != nodeType(pPara)) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "The input parameter of MAVG function can only be column"); + } + + uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; + uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type; + if (!IS_NUMERIC_TYPE(colType) || !IS_INTEGER_TYPE(paraType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + + pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE}; + return TSDB_CODE_SUCCESS; +} + +static int32_t translateSample(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { + if (2 != LIST_LENGTH(pFunc->pParameterList)) { + return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); + } + + SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); + if (QUERY_NODE_COLUMN != nodeType(pPara)) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "The input parameter of SAMPLE function can only be column"); + } + + uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type; + if (!IS_INTEGER_TYPE(paraType)) { + return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + } + + SExprNode* pCol = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0); + uint8_t colType = pCol->resType.type; + if (IS_VAR_DATA_TYPE(colType)) { + pFunc->node.resType = (SDataType){.bytes = pCol->resType.bytes, .type = colType}; + } else { + pFunc->node.resType = (SDataType){.bytes = tDataTypes[colType].bytes, .type = colType}; + } + return TSDB_CODE_SUCCESS; +} + static int32_t translateLastRow(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { // todo return TSDB_CODE_SUCCESS; @@ -783,6 +830,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .processFunc = csumFunction, .finalizeFunc = NULL }, + { + .name = "mavg", + .type = FUNCTION_TYPE_MAVG, + .classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC, + .translateFunc = translateMavg, + .getEnvFunc = getMavgFuncEnv, + .initFunc = mavgFunctionSetup, + .processFunc = mavgFunction, + .finalizeFunc = NULL + }, + { + .name = "sample", + .type = FUNCTION_TYPE_SAMPLE, + .classification = FUNC_MGT_NONSTANDARD_SQL_FUNC | FUNC_MGT_TIMELINE_FUNC, + .translateFunc = translateSample, + .getEnvFunc = getSampleFuncEnv, + .initFunc = sampleFunctionSetup, + .processFunc = sampleFunction, + .finalizeFunc = NULL + }, { .name = "abs", .type = FUNCTION_TYPE_ABS, diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index ca470a0521..af86eb4e90 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -21,7 +21,9 @@ #include "tdatablock.h" #include "tpercentile.h" -#define HISTOGRAM_MAX_BINS_NUM 100 +#define HISTOGRAM_MAX_BINS_NUM 1000 +#define MAVG_MAX_POINTS_NUM 1000 +#define SAMPLE_MAX_POINTS_NUM 1000 typedef struct SSumRes { union { @@ -141,6 +143,24 @@ typedef enum { STATE_OPER_EQ, } EStateOperType; +typedef struct SMavgInfo { + int32_t pos; + double sum; + int32_t numOfPoints; + bool pointsMeet; + double points[]; +} SMavgInfo; + +typedef struct SSampleInfo { + int32_t samples; + int32_t totalPoints; + int32_t numSampled; + uint8_t colType; + int16_t colBytes; + char *data; + int64_t *timestamp; +} SSampleInfo; + #define SET_VAL(_info, numOfElem, res) \ do { \ if ((numOfElem) <= 0) { \ @@ -1636,7 +1656,7 @@ int32_t percentileFunction(SqlFunctionCtx* pCtx) { int32_t type = pCol->info.type; SPercentileInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); - if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) { + if (pCtx->scanFlag == REPEAT_SCAN && pInfo->stage == 0) { pInfo->stage += 1; // all data are null, set it completed @@ -1644,7 +1664,7 @@ int32_t percentileFunction(SqlFunctionCtx* pCtx) { pResInfo->complete = true; return 0; } else { - pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval); + pInfo->pMemBucket = tMemBucketCreate(pCol->info.bytes, type, pInfo->minval, pInfo->maxval); } } @@ -1695,30 +1715,28 @@ int32_t percentileFunction(SqlFunctionCtx* pCtx) { pInfo->numOfElems += 1; } } + } else { + // the second stage, calculate the true percentile value + int32_t start = pInput->startRowIndex; + for (int32_t i = start; i < pInput->numOfRows + start; ++i) { + if (colDataIsNull_f(pCol->nullbitmap, i)) { + continue; + } - return 0; - } - - // the second stage, calculate the true percentile value - int32_t start = pInput->startRowIndex; - for (int32_t i = start; i < pInput->numOfRows + start; ++i) { - if (colDataIsNull_f(pCol->nullbitmap, i)) { - continue; + char* data = colDataGetData(pCol, i); + notNullElems += 1; + tMemBucketPut(pInfo->pMemBucket, data, 1); } - char* data = colDataGetData(pCol, i); - - notNullElems += 1; - tMemBucketPut(pInfo->pMemBucket, data, 1); + SET_VAL(pResInfo, notNullElems, 1); } - SET_VAL(pResInfo, notNullElems, 1); return TSDB_CODE_SUCCESS; } int32_t percentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { SVariant* pVal = &pCtx->param[1].param; - double v = pVal->nType == TSDB_DATA_TYPE_INT ? pVal->i : pVal->d; + double v = (pVal->nType == TSDB_DATA_TYPE_BIGINT) ? pVal->i : pVal->d; SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); SPercentileInfo* ppInfo = (SPercentileInfo*)GET_ROWCELL_INTERBUF(pResInfo); @@ -2949,3 +2967,177 @@ int32_t csumFunction(SqlFunctionCtx* pCtx) { return numOfElems; } + +bool getMavgFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) { + pEnv->calcMemSize = sizeof(SMavgInfo) + MAVG_MAX_POINTS_NUM * sizeof(double); + return true; +} + +bool mavgFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo *pResultInfo) { + if (!functionSetup(pCtx, pResultInfo)) { + return false; + } + + SMavgInfo *pInfo = GET_ROWCELL_INTERBUF(pResultInfo); + pInfo->pos = 0; + pInfo->sum = 0; + pInfo->numOfPoints = pCtx->param[1].param.i; + if (pInfo->numOfPoints < 1 || pInfo->numOfPoints > MAVG_MAX_POINTS_NUM) { + return false; + } + pInfo->pointsMeet = false; + + return true; +} + +int32_t mavgFunction(SqlFunctionCtx* pCtx) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SMavgInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); + + SInputColumnInfoData* pInput = &pCtx->input; + TSKEY* tsList = (int64_t*)pInput->pPTS->pData; + + SColumnInfoData* pInputCol = pInput->pData[0]; + SColumnInfoData* pTsOutput = pCtx->pTsOutput; + SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput; + + int32_t numOfElems = 0; + int32_t type = pInputCol->info.type; + int32_t startOffset = pCtx->offset; + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) { + int32_t pos = startOffset + numOfElems; + if (colDataIsNull_f(pInputCol->nullbitmap, i)) { + //colDataAppendNULL(pOutput, i); + continue; + } + + char* data = colDataGetData(pInputCol, i); + double v; + GET_TYPED_DATA(v, double, type, data); + + if (!pInfo->pointsMeet && (pInfo->pos < pInfo->numOfPoints - 1)) { + pInfo->points[pInfo->pos] = v; + pInfo->sum += v; + } else { + if (!pInfo->pointsMeet && (pInfo->pos == pInfo->numOfPoints - 1)) { + pInfo->sum +=v; + pInfo->pointsMeet = true; + } else { + pInfo->sum = pInfo->sum + v - pInfo->points[pInfo->pos]; + } + + pInfo->points[pInfo->pos] = v; + double result = pInfo->sum / pInfo->numOfPoints; + colDataAppend(pOutput, pos, (char *)&result, false); + + //TODO: remove this after pTsOutput is handled + if (pTsOutput != NULL) { + colDataAppendInt64(pTsOutput, pos, &tsList[i]); + } + numOfElems++; + } + + pInfo->pos++; + if (pInfo->pos == pInfo->numOfPoints) { + pInfo->pos = 0; + } + } + + return numOfElems; +} + +bool getSampleFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) { + SColumnNode* pCol = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0); + SValueNode* pVal = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1); + int32_t numOfSamples = pVal->datum.i; + pEnv->calcMemSize = sizeof(SSampleInfo) + numOfSamples * (pCol->node.resType.bytes + sizeof(int64_t)); + return true; +} + +bool sampleFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo *pResultInfo) { + if (!functionSetup(pCtx, pResultInfo)) { + return false; + } + + taosSeedRand(taosSafeRand()); + + SSampleInfo *pInfo = GET_ROWCELL_INTERBUF(pResultInfo); + pInfo->samples = pCtx->param[1].param.i; + pInfo->totalPoints = 0; + pInfo->numSampled = 0; + pInfo->colType = pCtx->resDataInfo.type; + pInfo->colBytes = pCtx->resDataInfo.bytes; + if (pInfo->samples < 1 || pInfo->samples > SAMPLE_MAX_POINTS_NUM) { + return false; + } + pInfo->data = (char *)pInfo + sizeof(SSampleInfo); + pInfo->timestamp = (int64_t *)((char *)pInfo + sizeof(SSampleInfo) + pInfo->samples * pInfo->colBytes); + + return true; +} + +static void sampleAssignResult(SSampleInfo* pInfo, char *data, TSKEY ts, int32_t index) { + assignVal(pInfo->data + index * pInfo->colBytes, data, pInfo->colBytes, pInfo->colType); + *(pInfo->timestamp + index) = ts; +} + +static void doReservoirSample(SSampleInfo* pInfo, char *data, TSKEY ts, int32_t index) { + pInfo->totalPoints++; + if (pInfo->numSampled < pInfo->samples) { + sampleAssignResult(pInfo, data, ts, pInfo->numSampled); + pInfo->numSampled++; + } else { + int32_t j = taosRand() % (pInfo->totalPoints); + if (j < pInfo->samples) { + sampleAssignResult(pInfo, data, ts, j); + } + } +} + +int32_t sampleFunction(SqlFunctionCtx* pCtx) { + SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); + SSampleInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo); + + SInputColumnInfoData* pInput = &pCtx->input; + TSKEY* tsList = (int64_t*)pInput->pPTS->pData; + + SColumnInfoData* pInputCol = pInput->pData[0]; + SColumnInfoData* pTsOutput = pCtx->pTsOutput; + SColumnInfoData* pOutput = (SColumnInfoData*)pCtx->pOutput; + + int32_t startOffset = pCtx->offset; + for (int32_t i = pInput->startRowIndex; i < pInput->numOfRows + pInput->startRowIndex; i += 1) { + if (colDataIsNull_f(pInputCol->nullbitmap, i)) { + //colDataAppendNULL(pOutput, i); + continue; + } + + char* data = colDataGetData(pInputCol, i); + doReservoirSample(pInfo, data, tsList[i], i); + } + + for (int32_t i = 0; i < pInfo->numSampled; ++i) { + int32_t pos = startOffset + i; + colDataAppend(pOutput, pos, pInfo->data + i * pInfo->colBytes, false); + //TODO: handle ts output + } + + return pInfo->numSampled; +} + +//int32_t sampleFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { +// SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); +// SSampleInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); +// int32_t slotId = pCtx->pExpr->base.resSchema.slotId; +// SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId); +// +// //int32_t currentRow = pBlock->info.rows; +// pResInfo->numOfRes = pInfo->numSampled; +// +// for (int32_t i = 0; i < pInfo->numSampled; ++i) { +// colDataAppend(pCol, i, pInfo->data + i * pInfo->colBytes, false); +// //TODO: handle ts output +// } +// +// return pResInfo->numOfRes; +//} diff --git a/source/libs/function/src/taggfunction.c b/source/libs/function/src/taggfunction.c index 4d80b88a3a..b6d5d38c9e 100644 --- a/source/libs/function/src/taggfunction.c +++ b/source/libs/function/src/taggfunction.c @@ -37,7 +37,7 @@ #define GET_TRUE_DATA_TYPE() \ int32_t type = 0; \ - if (pCtx->currentStage == MERGE_STAGE) { \ + if (pCtx->scanFlag == MERGE_STAGE) { \ type = pCtx->resDataInfo.type; \ assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); \ } else { \ @@ -908,7 +908,7 @@ static void avg_func_merge(SqlFunctionCtx *pCtx) { static void avg_finalizer(SqlFunctionCtx *pCtx) { SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); - if (pCtx->currentStage == MERGE_STAGE) { + if (pCtx->scanFlag == MERGE_STAGE) { assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); if (GET_INT64_VAL(GET_ROWCELL_INTERBUF(pResInfo)) <= 0) { @@ -1152,7 +1152,7 @@ static void stddev_function(SqlFunctionCtx *pCtx) { SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); SStddevInfo *pStd = GET_ROWCELL_INTERBUF(pResInfo); - if (pCtx->currentStage == REPEAT_SCAN && pStd->stage == 0) { + if (pCtx->scanFlag == REPEAT_SCAN && pStd->stage == 0) { pStd->stage++; avg_finalizer(pCtx); @@ -1814,7 +1814,7 @@ static STopBotInfo *getTopBotOutputInfo(SqlFunctionCtx *pCtx) { SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); // only the first_stage_merge is directly written data into final output buffer - if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) { + if (pCtx->stableQuery && pCtx->scanFlag != MERGE_STAGE) { return (STopBotInfo*) pCtx->pOutput; } else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer return GET_ROWCELL_INTERBUF(pResInfo); @@ -1956,7 +1956,7 @@ static void top_func_merge(SqlFunctionCtx *pCtx) { for (int32_t i = 0; i < pInput->num; ++i) { int16_t type = (pCtx->resDataInfo.type == TSDB_DATA_TYPE_FLOAT)? TSDB_DATA_TYPE_DOUBLE:pCtx->resDataInfo.type; // do_top_function_add(pOutput, (int32_t)pCtx->param[0].param.i, &pInput->res[i]->v.i, pInput->res[i]->timestamp, -// type, &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->currentStage); +// type, &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->scanFlag); } SET_VAL(pCtx, pInput->num, pOutput->num); @@ -2013,7 +2013,7 @@ static void bottom_func_merge(SqlFunctionCtx *pCtx) { for (int32_t i = 0; i < pInput->num; ++i) { int16_t type = (pCtx->resDataInfo.type == TSDB_DATA_TYPE_FLOAT) ? TSDB_DATA_TYPE_DOUBLE : pCtx->resDataInfo.type; // do_bottom_function_add(pOutput, (int32_t)pCtx->param[0].param.i, &pInput->res[i]->v.i, pInput->res[i]->timestamp, type, -// &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->currentStage); +// &pCtx->tagInfo, pInput->res[i]->pTags, pCtx->scanFlag); } SET_VAL(pCtx, pInput->num, pOutput->num); @@ -2073,7 +2073,7 @@ static void percentile_function(SqlFunctionCtx *pCtx) { SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); - if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) { + if (pCtx->scanFlag == REPEAT_SCAN && pInfo->stage == 0) { pInfo->stage += 1; // all data are null, set it completed @@ -2180,7 +2180,7 @@ static SAPercentileInfo *getAPerctInfo(SqlFunctionCtx *pCtx) { SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); SAPercentileInfo* pInfo = NULL; - if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) { + if (pCtx->stableQuery && pCtx->scanFlag != MERGE_STAGE) { pInfo = (SAPercentileInfo*) pCtx->pOutput; } else { pInfo = GET_ROWCELL_INTERBUF(pResInfo); @@ -2270,7 +2270,7 @@ static void apercentile_finalizer(SqlFunctionCtx *pCtx) { SResultRowEntryInfo * pResInfo = GET_RES_INFO(pCtx); SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo); - if (pCtx->currentStage == MERGE_STAGE) { + if (pCtx->scanFlag == MERGE_STAGE) { // if (pResInfo->hasResult == DATA_SET_FLAG) { // check for null // assert(pOutput->pHisto->numOfElems > 0); // @@ -2510,7 +2510,7 @@ static void copy_function(SqlFunctionCtx *pCtx); static void tag_function(SqlFunctionCtx *pCtx) { SET_VAL(pCtx, 1, 1); - if (pCtx->currentStage == MERGE_STAGE) { + if (pCtx->scanFlag == MERGE_STAGE) { copy_function(pCtx); } else { taosVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->resDataInfo.type, true); @@ -2966,7 +2966,7 @@ static bool spread_function_setup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pRe SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); // this is the server-side setup function in client-side, the secondary merge do not need this procedure - if (pCtx->currentStage == MERGE_STAGE) { + if (pCtx->scanFlag == MERGE_STAGE) { // pCtx->param[0].param.d = DBL_MAX; // pCtx->param[3].param.d = -DBL_MAX; } else { @@ -3086,7 +3086,7 @@ void spread_function_finalizer(SqlFunctionCtx *pCtx) { */ SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx); - if (pCtx->currentStage == MERGE_STAGE) { + if (pCtx->scanFlag == MERGE_STAGE) { assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); // if (pResInfo->hasResult != DATA_SET_FLAG) { diff --git a/source/libs/function/src/texpr.c b/source/libs/function/src/texpr.c index 61ff6bb825..b91af2d157 100644 --- a/source/libs/function/src/texpr.c +++ b/source/libs/function/src/texpr.c @@ -27,19 +27,6 @@ #include "tvariant.h" #include "tdef.h" -//static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) { -// if (pLeft->nodeType == TEXPR_COL_NODE) { -// // if left node is the primary column,return true -// return (strcmp(primaryColumnName, pLeft->pSchema->name) == 0) ? 1 : 0; -// } else { -// // if any children have query on primary key, their parents are also keep this value -// return ((pLeft->nodeType == TEXPR_BINARYEXPR_NODE && pLeft->_node.hasPK == 1) || -// (pRight->nodeType == TEXPR_BINARYEXPR_NODE && pRight->_node.hasPK == 1)) == true -// ? 1 -// : 0; -// } -//} - static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)); void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) { @@ -64,21 +51,7 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { } int32_t type = (*pExpr)->nodeType; - if (type == TEXPR_BINARYEXPR_NODE) { - doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp); - doExprTreeDestroy(&(*pExpr)->_node.pRight, fp); - - if (fp != NULL) { - fp((*pExpr)->_node.info); - } - } else if (type == TEXPR_UNARYEXPR_NODE) { - doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp); - if (fp != NULL) { - fp((*pExpr)->_node.info); - } - - assert((*pExpr)->_node.pRight == NULL); - } else if (type == TEXPR_VALUE_NODE) { + if (type == TEXPR_VALUE_NODE) { taosVariantDestroy((*pExpr)->pVal); taosMemoryFree((*pExpr)->pVal); } else if (type == TEXPR_COL_NODE) { @@ -90,9 +63,7 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { } bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) { - tExprNode *pLeft = pExpr->_node.pLeft; - tExprNode *pRight = pExpr->_node.pRight; - +#if 0 //non-leaf nodes, recursively traverse the expression tree in the post-root order if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE && pRight->nodeType == TEXPR_BINARYEXPR_NODE) { if (pExpr->_node.optr == LOGIC_COND_TYPE_OR) { // or @@ -114,6 +85,9 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp // handle the leaf node param->setupInfoFn(pExpr, param->pExtInfo); return param->nodeFilterFn(pItem, pExpr->_node.info); +#endif + + return 0; } // TODO: these three functions should be made global @@ -141,59 +115,6 @@ static UNUSED_FUNC char* exception_strdup(const char* str) { return p; } -static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) { - int32_t anchor = CLEANUP_GET_ANCHOR(); - if (CLEANUP_EXCEED_LIMIT()) { - THROW(TSDB_CODE_QRY_EXCEED_TAGS_LIMIT); - return NULL; - } - - tExprNode* pExpr = exception_calloc(1, sizeof(tExprNode)); - CLEANUP_PUSH_VOID_PTR_PTR(true, tExprTreeDestroy, pExpr, NULL); - pExpr->nodeType = tbufReadUint8(br); - - if (pExpr->nodeType == TEXPR_VALUE_NODE) { - SVariant* pVal = exception_calloc(1, sizeof(SVariant)); - pExpr->pVal = pVal; - - pVal->nType = tbufReadUint32(br); - if (pVal->nType == TSDB_DATA_TYPE_BINARY) { - tbufReadToBuffer(br, &pVal->nLen, sizeof(pVal->nLen)); - pVal->pz = taosMemoryCalloc(1, pVal->nLen + 1); - tbufReadToBuffer(br, pVal->pz, pVal->nLen); - } else { - pVal->i = tbufReadInt64(br); - } - - } else if (pExpr->nodeType == TEXPR_COL_NODE) { - SSchema* pSchema = exception_calloc(1, sizeof(SSchema)); - pExpr->pSchema = pSchema; - - pSchema->colId = tbufReadInt16(br); - pSchema->bytes = tbufReadInt16(br); - pSchema->type = tbufReadUint8(br); - tbufReadToString(br, pSchema->name, TSDB_COL_NAME_LEN); - - } else if (pExpr->nodeType == TEXPR_BINARYEXPR_NODE) { - pExpr->_node.optr = tbufReadUint8(br); - pExpr->_node.pLeft = exprTreeFromBinaryImpl(br); - pExpr->_node.pRight = exprTreeFromBinaryImpl(br); - assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL); - } - - CLEANUP_EXECUTE_TO(anchor, false); - return pExpr; -} - -tExprNode* exprTreeFromBinary(const void* data, size_t size) { - if (size == 0) { - return NULL; - } - - SBufferReader br = tbufInitReader(data, size, false); - return exprTreeFromBinaryImpl(&br); -} - void buildFilterSetFromBinary(void **q, const char *buf, int32_t len) { SBufferReader br = tbufInitReader(buf, len, false); uint32_t type = tbufReadUint32(&br); @@ -405,38 +326,3 @@ err_ret: taosHashCleanup(pObj); taosMemoryFreeClear(tmp); } - -tExprNode* exprdup(tExprNode* pNode) { - if (pNode == NULL) { - return NULL; - } - - tExprNode* pCloned = taosMemoryCalloc(1, sizeof(tExprNode)); - if (pNode->nodeType == TEXPR_BINARYEXPR_NODE) { - tExprNode* pLeft = exprdup(pNode->_node.pLeft); - tExprNode* pRight = exprdup(pNode->_node.pRight); - - pCloned->_node.pLeft = pLeft; - pCloned->_node.pRight = pRight; - pCloned->_node.optr = pNode->_node.optr; - } else if (pNode->nodeType == TEXPR_VALUE_NODE) { - pCloned->pVal = taosMemoryCalloc(1, sizeof(SVariant)); - taosVariantAssign(pCloned->pVal, pNode->pVal); - } else if (pNode->nodeType == TEXPR_COL_NODE) { - pCloned->pSchema = taosMemoryCalloc(1, sizeof(SSchema)); - *pCloned->pSchema = *pNode->pSchema; - } else if (pNode->nodeType == TEXPR_FUNCTION_NODE) { - strcpy(pCloned->_function.functionName, pNode->_function.functionName); - - int32_t num = pNode->_function.num; - pCloned->_function.num = num; - pCloned->_function.pChild = taosMemoryCalloc(num, POINTER_BYTES); - for(int32_t i = 0; i < num; ++i) { - pCloned->_function.pChild[i] = exprdup(pNode->_function.pChild[i]); - } - } - - pCloned->nodeType = pNode->nodeType; - return pCloned; -} - diff --git a/source/libs/function/src/tudf.c b/source/libs/function/src/tudf.c index 8e96a2a063..9fa20d3556 100644 --- a/source/libs/function/src/tudf.c +++ b/source/libs/function/src/tudf.c @@ -34,6 +34,9 @@ typedef struct SUdfdData { uv_thread_t thread; uv_barrier_t barrier; uv_process_t process; +#ifdef WINDOWS + HANDLE jobHandle; +#endif int spawnErr; uv_pipe_t ctrlPipe; uv_async_t stopAsync; @@ -104,6 +107,24 @@ static int32_t udfSpawnUdfd(SUdfdData* pData) { int err = uv_spawn(&pData->loop, &pData->process, &options); pData->process.data = (void*)pData; +#ifdef WINDOWS + // End udfd.exe by Job. + if (pData->jobHandle != NULL) CloseHandle(pData->jobHandle); + pData->jobHandle = CreateJobObject(NULL, NULL); + bool add_job_ok = AssignProcessToJobObject(pData->jobHandle, pData->process.process_handle); + if (!add_job_ok) { + fnError("Assign udfd to job failed."); + } else { + JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info; + memset(&limit_info, 0x0, sizeof(limit_info)); + limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + bool set_auto_kill_ok = SetInformationJobObject(pData->jobHandle, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)); + if (!set_auto_kill_ok) { + fnError("Set job auto kill udfd failed."); + } + } +#endif + if (err != 0) { fnError("can not spawn udfd. path: %s, error: %s", path, uv_strerror(err)); } @@ -145,7 +166,7 @@ int32_t udfStartUdfd(int32_t startDnodeId) { } SUdfdData *pData = &udfdGlobal; if (pData->startCalled) { - fnInfo("dnode-mgmt start udfd already called"); + fnInfo("dnode start udfd already called"); return 0; } pData->startCalled = true; @@ -163,7 +184,7 @@ int32_t udfStartUdfd(int32_t startDnodeId) { uv_async_send(&pData->stopAsync); uv_thread_join(&pData->thread); pData->needCleanUp = false; - fnInfo("dnode-mgmt udfd cleaned up after spawn err"); + fnInfo("dnode udfd cleaned up after spawn err"); } else { pData->needCleanUp = true; } @@ -172,7 +193,7 @@ int32_t udfStartUdfd(int32_t startDnodeId) { int32_t udfStopUdfd() { SUdfdData *pData = &udfdGlobal; - fnInfo("dnode-mgmt to stop udfd. need cleanup: %d, spawn err: %d", + fnInfo("dnode to stop udfd. need cleanup: %d, spawn err: %d", pData->needCleanUp, pData->spawnErr); if (!pData->needCleanUp || atomic_load_32(&pData->stopCalled)) { return 0; @@ -182,7 +203,10 @@ int32_t udfStopUdfd() { uv_barrier_destroy(&pData->barrier); uv_async_send(&pData->stopAsync); uv_thread_join(&pData->thread); - fnInfo("dnode-mgmt udfd cleaned up"); +#ifdef WINDOWS + if (pData->jobHandle != NULL) CloseHandle(pData->jobHandle); +#endif + fnInfo("dnode udfd cleaned up"); return 0; } @@ -286,28 +310,28 @@ enum { }; int64_t gUdfTaskSeqNum = 0; -typedef struct SUdfdProxy { +typedef struct SUdfcProxy { char udfdPipeName[PATH_MAX + UDF_LISTEN_PIPE_NAME_LEN + 2]; - uv_barrier_t gUdfInitBarrier; + uv_barrier_t initBarrier; - uv_loop_t gUdfdLoop; - uv_thread_t gUdfLoopThread; - uv_async_t gUdfLoopTaskAync; + uv_loop_t uvLoop; + uv_thread_t loopThread; + uv_async_t loopTaskAync; - uv_async_t gUdfLoopStopAsync; + uv_async_t loopStopAsync; - uv_mutex_t gUdfTaskQueueMutex; - int8_t gUdfcState; - QUEUE gUdfTaskQueue; - QUEUE gUvProcTaskQueue; + uv_mutex_t taskQueueMutex; + int8_t udfcState; + QUEUE taskQueue; + QUEUE uvProcTaskQueue; int8_t initialized; -} SUdfdProxy; +} SUdfcProxy; -SUdfdProxy gUdfdProxy = {0}; +SUdfcProxy gUdfdProxy = {0}; typedef struct SClientUdfUvSession { - SUdfdProxy *udfc; + SUdfcProxy *udfc; int64_t severHandle; uv_pipe_t *udfUvPipe; @@ -317,7 +341,7 @@ typedef struct SClientUdfUvSession { } SClientUdfUvSession; typedef struct SClientUvTaskNode { - SUdfdProxy *udfc; + SUdfcProxy *udfc; int8_t type; int errCode; @@ -1031,11 +1055,11 @@ int32_t udfcCreateUvTask(SClientUdfTask *task, int8_t uvTaskType, SClientUvTaskN int32_t udfcQueueUvTask(SClientUvTaskNode *uvTask) { fnTrace("queue uv task to event loop, task: %d, %p", uvTask->type, uvTask); - SUdfdProxy *udfc = uvTask->udfc; - uv_mutex_lock(&udfc->gUdfTaskQueueMutex); - QUEUE_INSERT_TAIL(&udfc->gUdfTaskQueue, &uvTask->recvTaskQueue); - uv_mutex_unlock(&udfc->gUdfTaskQueueMutex); - uv_async_send(&udfc->gUdfLoopTaskAync); + SUdfcProxy *udfc = uvTask->udfc; + uv_mutex_lock(&udfc->taskQueueMutex); + QUEUE_INSERT_TAIL(&udfc->taskQueue, &uvTask->recvTaskQueue); + uv_mutex_unlock(&udfc->taskQueueMutex); + uv_async_send(&udfc->loopTaskAync); uv_sem_wait(&uvTask->taskSem); fnInfo("udfc uv task finished. task: %d, %p", uvTask->type, uvTask); @@ -1049,7 +1073,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) { switch (uvTask->type) { case UV_TASK_CONNECT: { uv_pipe_t *pipe = taosMemoryMalloc(sizeof(uv_pipe_t)); - uv_pipe_init(&uvTask->udfc->gUdfdLoop, pipe, 0); + uv_pipe_init(&uvTask->udfc->uvLoop, pipe, 0); uvTask->pipe = pipe; SClientUvConn *conn = taosMemoryCalloc(1, sizeof(SClientUvConn)); @@ -1089,46 +1113,46 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) { } void udfClientAsyncCb(uv_async_t *async) { - SUdfdProxy *udfc = async->data; + SUdfcProxy *udfc = async->data; QUEUE wq; - uv_mutex_lock(&udfc->gUdfTaskQueueMutex); - QUEUE_MOVE(&udfc->gUdfTaskQueue, &wq); - uv_mutex_unlock(&udfc->gUdfTaskQueueMutex); + uv_mutex_lock(&udfc->taskQueueMutex); + QUEUE_MOVE(&udfc->taskQueue, &wq); + uv_mutex_unlock(&udfc->taskQueueMutex); while (!QUEUE_EMPTY(&wq)) { QUEUE* h = QUEUE_HEAD(&wq); QUEUE_REMOVE(h); SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, recvTaskQueue); udfcStartUvTask(task); - QUEUE_INSERT_TAIL(&udfc->gUvProcTaskQueue, &task->procTaskQueue); + QUEUE_INSERT_TAIL(&udfc->uvProcTaskQueue, &task->procTaskQueue); } } -void cleanUpUvTasks(SUdfdProxy *udfc) { +void cleanUpUvTasks(SUdfcProxy *udfc) { fnDebug("clean up uv tasks") QUEUE wq; - uv_mutex_lock(&udfc->gUdfTaskQueueMutex); - QUEUE_MOVE(&udfc->gUdfTaskQueue, &wq); - uv_mutex_unlock(&udfc->gUdfTaskQueueMutex); + uv_mutex_lock(&udfc->taskQueueMutex); + QUEUE_MOVE(&udfc->taskQueue, &wq); + uv_mutex_unlock(&udfc->taskQueueMutex); while (!QUEUE_EMPTY(&wq)) { QUEUE* h = QUEUE_HEAD(&wq); QUEUE_REMOVE(h); SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, recvTaskQueue); - if (udfc->gUdfcState == UDFC_STATE_STOPPING) { + if (udfc->udfcState == UDFC_STATE_STOPPING) { task->errCode = TSDB_CODE_UDF_STOPPING; } uv_sem_post(&task->taskSem); } - while (!QUEUE_EMPTY(&udfc->gUvProcTaskQueue)) { - QUEUE* h = QUEUE_HEAD(&udfc->gUvProcTaskQueue); + while (!QUEUE_EMPTY(&udfc->uvProcTaskQueue)) { + QUEUE* h = QUEUE_HEAD(&udfc->uvProcTaskQueue); QUEUE_REMOVE(h); SClientUvTaskNode *task = QUEUE_DATA(h, SClientUvTaskNode, procTaskQueue); - if (udfc->gUdfcState == UDFC_STATE_STOPPING) { + if (udfc->udfcState == UDFC_STATE_STOPPING) { task->errCode = TSDB_CODE_UDF_STOPPING; } uv_sem_post(&task->taskSem); @@ -1136,28 +1160,28 @@ void cleanUpUvTasks(SUdfdProxy *udfc) { } void udfStopAsyncCb(uv_async_t *async) { - SUdfdProxy *udfc = async->data; + SUdfcProxy *udfc = async->data; cleanUpUvTasks(udfc); - if (udfc->gUdfcState == UDFC_STATE_STOPPING) { - uv_stop(&udfc->gUdfdLoop); + if (udfc->udfcState == UDFC_STATE_STOPPING) { + uv_stop(&udfc->uvLoop); } } void constructUdfService(void *argsThread) { - SUdfdProxy *udfc = (SUdfdProxy*)argsThread; - uv_loop_init(&udfc->gUdfdLoop); + SUdfcProxy *udfc = (SUdfcProxy *)argsThread; + uv_loop_init(&udfc->uvLoop); - uv_async_init(&udfc->gUdfdLoop, &udfc->gUdfLoopTaskAync, udfClientAsyncCb); - udfc->gUdfLoopTaskAync.data = udfc; - uv_async_init(&udfc->gUdfdLoop, &udfc->gUdfLoopStopAsync, udfStopAsyncCb); - udfc->gUdfLoopStopAsync.data = udfc; - uv_mutex_init(&udfc->gUdfTaskQueueMutex); - QUEUE_INIT(&udfc->gUdfTaskQueue); - QUEUE_INIT(&udfc->gUvProcTaskQueue); - uv_barrier_wait(&udfc->gUdfInitBarrier); + uv_async_init(&udfc->uvLoop, &udfc->loopTaskAync, udfClientAsyncCb); + udfc->loopTaskAync.data = udfc; + uv_async_init(&udfc->uvLoop, &udfc->loopStopAsync, udfStopAsyncCb); + udfc->loopStopAsync.data = udfc; + uv_mutex_init(&udfc->taskQueueMutex); + QUEUE_INIT(&udfc->taskQueue); + QUEUE_INIT(&udfc->uvProcTaskQueue); + uv_barrier_wait(&udfc->initBarrier); //TODO return value of uv_run - uv_run(&udfc->gUdfdLoop, UV_RUN_DEFAULT); - uv_loop_close(&udfc->gUdfdLoop); + uv_run(&udfc->uvLoop, UV_RUN_DEFAULT); + uv_loop_close(&udfc->uvLoop); } int32_t udfcOpen() { @@ -1165,14 +1189,14 @@ int32_t udfcOpen() { if (old == 1) { return 0; } - SUdfdProxy *proxy = &gUdfdProxy; + SUdfcProxy *proxy = &gUdfdProxy; getUdfdPipeName(proxy->udfdPipeName, sizeof(proxy->udfdPipeName)); - proxy->gUdfcState = UDFC_STATE_STARTNG; - uv_barrier_init(&proxy->gUdfInitBarrier, 2); - uv_thread_create(&proxy->gUdfLoopThread, constructUdfService, proxy); - atomic_store_8(&proxy->gUdfcState, UDFC_STATE_READY); - proxy->gUdfcState = UDFC_STATE_READY; - uv_barrier_wait(&proxy->gUdfInitBarrier); + proxy->udfcState = UDFC_STATE_STARTNG; + uv_barrier_init(&proxy->initBarrier, 2); + uv_thread_create(&proxy->loopThread, constructUdfService, proxy); + atomic_store_8(&proxy->udfcState, UDFC_STATE_READY); + proxy->udfcState = UDFC_STATE_READY; + uv_barrier_wait(&proxy->initBarrier); fnInfo("udfc initialized") return 0; } @@ -1183,13 +1207,13 @@ int32_t udfcClose() { return 0; } - SUdfdProxy *udfc = &gUdfdProxy; - udfc->gUdfcState = UDFC_STATE_STOPPING; - uv_async_send(&udfc->gUdfLoopStopAsync); - uv_thread_join(&udfc->gUdfLoopThread); - uv_mutex_destroy(&udfc->gUdfTaskQueueMutex); - uv_barrier_destroy(&udfc->gUdfInitBarrier); - udfc->gUdfcState = UDFC_STATE_INITAL; + SUdfcProxy *udfc = &gUdfdProxy; + udfc->udfcState = UDFC_STATE_STOPPING; + uv_async_send(&udfc->loopStopAsync); + uv_thread_join(&udfc->loopThread); + uv_mutex_destroy(&udfc->taskQueueMutex); + uv_barrier_destroy(&udfc->initBarrier); + udfc->udfcState = UDFC_STATE_INITAL; fnInfo("udfc cleaned up"); return 0; } @@ -1212,7 +1236,7 @@ int32_t udfcRunUdfUvTask(SClientUdfTask *task, int8_t uvTaskType) { int32_t setupUdf(char udfName[], UdfcFuncHandle *funcHandle) { fnInfo("udfc setup udf. udfName: %s", udfName); - if (gUdfdProxy.gUdfcState != UDFC_STATE_READY) { + if (gUdfdProxy.udfcState != UDFC_STATE_READY) { return TSDB_CODE_UDF_INVALID_STATE; } SClientUdfTask *task = taosMemoryCalloc(1,sizeof(SClientUdfTask)); @@ -1460,7 +1484,7 @@ int32_t udfAggProcess(struct SqlFunctionCtx *pCtx) { SSDataBlock tempBlock = {0}; tempBlock.info.numOfCols = numOfCols; - tempBlock.info.rows = numOfRows; + tempBlock.info.rows = pInput->totalRows; tempBlock.info.uid = pInput->uid; bool hasVarCol = false; tempBlock.pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); diff --git a/source/libs/function/test/udf2.c b/source/libs/function/test/udf2.c index b3b60f93a4..6410af2a4b 100644 --- a/source/libs/function/test/udf2.c +++ b/source/libs/function/test/udf2.c @@ -19,17 +19,18 @@ int32_t udf2_destroy() { int32_t udf2_start(SUdfInterBuf *buf) { *(int64_t*)(buf->buf) = 0; - buf->bufLen = sizeof(int64_t); + buf->bufLen = sizeof(double); buf->numOfResult = 0; return 0; } int32_t udf2(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInterBuf) { - int64_t sumSquares = *(int64_t*)interBuf->buf; + double sumSquares = *(double*)interBuf->buf; int8_t numOutput = 0; for (int32_t i = 0; i < block->numOfCols; ++i) { SUdfColumn* col = block->udfCols[i]; - if (col->colMeta.type != TSDB_DATA_TYPE_INT) { + if (!(col->colMeta.type == TSDB_DATA_TYPE_INT || + col->colMeta.type == TSDB_DATA_TYPE_DOUBLE)) { return TSDB_CODE_UDF_INVALID_INPUT; } } @@ -39,17 +40,29 @@ int32_t udf2(SUdfDataBlock* block, SUdfInterBuf *interBuf, SUdfInterBuf *newInte if (udfColDataIsNull(col, j)) { continue; } - - char* cell = udfColDataGetData(col, j); - int32_t num = *(int32_t*)cell; - sumSquares += num * num; + switch (col->colMeta.type) { + case TSDB_DATA_TYPE_INT: { + char* cell = udfColDataGetData(col, j); + int32_t num = *(int32_t*)cell; + sumSquares += (double)num * num; + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + char* cell = udfColDataGetData(col, j); + double num = *(double*)cell; + sumSquares += num * num; + break; + } + default: + break; + } numOutput = 1; } } if (numOutput == 1) { - *(int64_t*)(newInterBuf->buf) = sumSquares; - newInterBuf->bufLen = sizeof(int64_t); + *(double*)(newInterBuf->buf) = sumSquares; + newInterBuf->bufLen = sizeof(double); } newInterBuf->numOfResult = numOutput; return 0; @@ -60,7 +73,7 @@ int32_t udf2_finish(SUdfInterBuf* buf, SUdfInterBuf *resultData) { resultData->numOfResult = 0; return 0; } - int64_t sumSquares = *(int64_t*)(buf->buf); + double sumSquares = *(double*)(buf->buf); *(double*)(resultData->buf) = sqrt(sumSquares); resultData->bufLen = sizeof(double); resultData->numOfResult = 1; diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index a625fc0d0c..6e0775ff17 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -317,15 +317,16 @@ static int32_t tableComInfoToJson(const void* pObj, SJson* pJson) { static int32_t jsonToTableComInfo(const SJson* pJson, void* pObj) { STableComInfo* pNode = (STableComInfo*)pObj; - int32_t code = tjsonGetNumberValue(pJson, jkTableComInfoNumOfTags, pNode->numOfTags); + int32_t code; + tjsonGetNumberValue(pJson, jkTableComInfoNumOfTags, pNode->numOfTags, code);; if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableComInfoPrecision, pNode->precision); + tjsonGetNumberValue(pJson, jkTableComInfoPrecision, pNode->precision, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableComInfoNumOfColumns, pNode->numOfColumns); + tjsonGetNumberValue(pJson, jkTableComInfoNumOfColumns, pNode->numOfColumns, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableComInfoRowSize, pNode->rowSize); + tjsonGetNumberValue(pJson, jkTableComInfoRowSize, pNode->rowSize, code);; } return code; @@ -356,12 +357,13 @@ static int32_t schemaToJson(const void* pObj, SJson* pJson) { static int32_t jsonToSchema(const SJson* pJson, void* pObj) { SSchema* pNode = (SSchema*)pObj; - int32_t code = tjsonGetNumberValue(pJson, jkSchemaType, pNode->type); + int32_t code; + tjsonGetNumberValue(pJson, jkSchemaType, pNode->type, code);; if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkSchemaColId, pNode->colId); + tjsonGetNumberValue(pJson, jkSchemaColId, pNode->colId, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkSchemaBytes, pNode->bytes); + tjsonGetNumberValue(pJson, jkSchemaBytes, pNode->bytes, code);; } if (TSDB_CODE_SUCCESS == code) { code = tjsonGetStringValue(pJson, jkSchemaName, pNode->name); @@ -412,21 +414,22 @@ static int32_t tableMetaToJson(const void* pObj, SJson* pJson) { static int32_t jsonToTableMeta(const SJson* pJson, void* pObj) { STableMeta* pNode = (STableMeta*)pObj; - int32_t code = tjsonGetNumberValue(pJson, jkTableMetaVgId, pNode->vgId); + int32_t code; + tjsonGetNumberValue(pJson, jkTableMetaVgId, pNode->vgId, code);; if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableMetaTableType, pNode->tableType); + tjsonGetNumberValue(pJson, jkTableMetaTableType, pNode->tableType, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableMetaUid, pNode->uid); + tjsonGetNumberValue(pJson, jkTableMetaUid, pNode->uid, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableMetaSuid, pNode->suid); + tjsonGetNumberValue(pJson, jkTableMetaSuid, pNode->suid, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableMetaSversion, pNode->sversion); + tjsonGetNumberValue(pJson, jkTableMetaSversion, pNode->sversion, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableMetaTversion, pNode->tversion); + tjsonGetNumberValue(pJson, jkTableMetaTversion, pNode->tversion, code);; } if (TSDB_CODE_SUCCESS == code) { code = tjsonToObject(pJson, jkTableMetaComInfo, jsonToTableComInfo, &pNode->tableInfo); @@ -602,7 +605,7 @@ static int32_t jsonToLogicFillNode(const SJson* pJson, void* pObj) { int32_t code = jsonToLogicPlanNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkFillLogicPlanMode, pNode->mode); + tjsonGetNumberValue(pJson, jkFillLogicPlanMode, pNode->mode, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkFillLogicPlanWStartTs, &pNode->pWStartTs); @@ -878,7 +881,7 @@ static int32_t jsonToLogicSubplan(const SJson* pJson, void* pObj) { code = jsonToNodeObject(pJson, jkLogicSubplanRootNode, (SNode**)&pNode->pNode); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkLogicSubplanType, pNode->subplanType); + tjsonGetNumberValue(pJson, jkLogicSubplanType, pNode->subplanType, code);; } int32_t objSize = 0; if (TSDB_CODE_SUCCESS == code) { @@ -1118,33 +1121,33 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) { code = tjsonGetDoubleValue(pJson, jkTableScanPhysiPlanRatio, &pNode->ratio); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanDataRequired, pNode->dataRequired); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanDataRequired, pNode->dataRequired, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkTableScanPhysiPlanDynamicScanFuncs, &pNode->pDynamicScanFuncs); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanInterval, pNode->interval); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanInterval, pNode->interval, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanOffset, pNode->offset); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanOffset, pNode->offset, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSliding, pNode->sliding); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSliding, pNode->sliding, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanIntervalUnit, pNode->intervalUnit); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanIntervalUnit, pNode->intervalUnit, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSlidingUnit, pNode->slidingUnit); + tjsonGetNumberValue(pJson, jkTableScanPhysiPlanSlidingUnit, pNode->slidingUnit, code);; } return code; } -static int32_t physiStreamScanNodeToJson(const void* pObj, SJson* pJson) { return physiScanNodeToJson(pObj, pJson); } +static int32_t physiStreamScanNodeToJson(const void* pObj, SJson* pJson) { return physiTableScanNodeToJson(pObj, pJson); } -static int32_t jsonToPhysiStreamScanNode(const SJson* pJson, void* pObj) { return jsonToPhysiScanNode(pJson, pObj); } +static int32_t jsonToPhysiStreamScanNode(const SJson* pJson, void* pObj) { return jsonToPhysiTableScanNode(pJson, pObj); } static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet"; static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite"; @@ -1178,7 +1181,7 @@ static int32_t jsonToPhysiSysTableScanNode(const SJson* pJson, void* pObj) { code = tjsonGetBoolValue(pJson, jkSysTableScanPhysiPlanShowRewrite, &pNode->showRewrite); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkSysTableScanPhysiPlanAccountId, pNode->accountId); + tjsonGetNumberValue(pJson, jkSysTableScanPhysiPlanAccountId, pNode->accountId, code);; } return code; @@ -1262,7 +1265,7 @@ static int32_t jsonToPhysiJoinNode(const SJson* pJson, void* pObj) { int32_t code = jsonToPhysicPlanNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkJoinPhysiPlanJoinType, pNode->joinType); + tjsonGetNumberValue(pJson, jkJoinPhysiPlanJoinType, pNode->joinType, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkJoinPhysiPlanOnConditions, &pNode->pOnConditions); @@ -1424,10 +1427,10 @@ static int32_t jsonToPhysiWindowNode(const SJson* pJson, void* pObj) { code = jsonToNodeObject(pJson, jkWindowPhysiPlanTsPk, (SNode**)&pNode->pTspk); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkWindowPhysiPlanTriggerType, pNode->triggerType); + tjsonGetNumberValue(pJson, jkWindowPhysiPlanTriggerType, pNode->triggerType, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkWindowPhysiPlanWatermark, pNode->watermark); + tjsonGetNumberValue(pJson, jkWindowPhysiPlanWatermark, pNode->watermark, code);; } return code; @@ -1523,7 +1526,7 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) { int32_t code = jsonToPhysicPlanNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode); + tjsonGetNumberValue(pJson, jkFillPhysiPlanMode, pNode->mode, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkFillPhysiPlanWStartTs, &pNode->pWStartTs); @@ -1562,7 +1565,7 @@ static int32_t jsonToPhysiSessionWindowNode(const SJson* pJson, void* pObj) { int32_t code = jsonToPhysiWindowNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkSessionWindowPhysiPlanGap, pNode->gap); + tjsonGetNumberValue(pJson, jkSessionWindowPhysiPlanGap, pNode->gap, code);; } return code; @@ -1724,7 +1727,7 @@ static int32_t jsonToSubplan(const SJson* pJson, void* pObj) { int32_t code = tjsonToObject(pJson, jkSubplanId, jsonToSubplanId, &pNode->id); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkSubplanType, pNode->subplanType); + tjsonGetNumberValue(pJson, jkSubplanType, pNode->subplanType, code);; } if (TSDB_CODE_SUCCESS == code) { code = tjsonGetIntValue(pJson, jkSubplanMsgType, &pNode->msgType); @@ -1914,7 +1917,7 @@ static int32_t jsonToColumnNode(const SJson* pJson, void* pObj) { code = tjsonGetSmallIntValue(pJson, jkColumnColId, &pNode->colId); } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkColumnColType, pNode->colType); + tjsonGetNumberValue(pJson, jkColumnColType, pNode->colType, code);; } if (TSDB_CODE_SUCCESS == code) { code = tjsonGetStringValue(pJson, jkColumnDbName, pNode->dbName); @@ -2168,7 +2171,7 @@ static int32_t jsonToOperatorNode(const SJson* pJson, void* pObj) { int32_t code = jsonToExprNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkOperatorType, pNode->opType); + tjsonGetNumberValue(pJson, jkOperatorType, pNode->opType, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkOperatorLeft, &pNode->pLeft); @@ -2202,7 +2205,7 @@ static int32_t jsonToLogicConditionNode(const SJson* pJson, void* pObj) { int32_t code = jsonToExprNode(pJson, pObj); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkLogicCondType, pNode->condType); + tjsonGetNumberValue(pJson, jkLogicCondType, pNode->condType, code);; } if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeList(pJson, jkLogicCondParameters, &pNode->pParameterList); @@ -2384,10 +2387,10 @@ static int32_t jsonToOrderByExprNode(const SJson* pJson, void* pObj) { int32_t code = jsonToNodeObject(pJson, jkOrderByExprExpr, &pNode->pExpr); if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkOrderByExprOrder, pNode->order); + tjsonGetNumberValue(pJson, jkOrderByExprOrder, pNode->order, code);; } if (TSDB_CODE_SUCCESS == code) { - code = tjsonGetNumberValue(pJson, jkOrderByExprNullOrder, pNode->nullOrder); + tjsonGetNumberValue(pJson, jkOrderByExprNullOrder, pNode->nullOrder, code);; } return code; @@ -2493,7 +2496,8 @@ static int32_t fillNodeToJson(const void* pObj, SJson* pJson) { static int32_t jsonToFillNode(const SJson* pJson, void* pObj) { SFillNode* pNode = (SFillNode*)pObj; - int32_t code = tjsonGetNumberValue(pJson, jkFillMode, pNode->mode); + int32_t code; + tjsonGetNumberValue(pJson, jkFillMode, pNode->mode, code);; if (TSDB_CODE_SUCCESS == code) { code = jsonToNodeObject(pJson, jkFillValues, &pNode->pValues); } @@ -3033,7 +3037,8 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) { static int32_t jsonToNode(const SJson* pJson, void* pObj) { SNode* pNode = (SNode*)pObj; - int32_t code = tjsonGetNumberValue(pJson, jkNodeType, pNode->type); + int32_t code; + tjsonGetNumberValue(pJson, jkNodeType, pNode->type, code);; if (TSDB_CODE_SUCCESS == code) { code = tjsonToObject(pJson, nodesNodeName(pNode->type), jsonToSpecificNode, pNode); if (TSDB_CODE_SUCCESS != code) { diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 81f55d8046..27383c0a51 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -1227,16 +1227,20 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery) { if (NULL == *pQuery) { return TSDB_CODE_OUT_OF_MEMORY; } - (*pQuery)->pTableList = taosArrayInit(taosHashGetSize(context.pTableNameHashObj), sizeof(SName)); - if (NULL == (*pQuery)->pTableList) { - return TSDB_CODE_OUT_OF_MEMORY; - } + (*pQuery)->execMode = QUERY_EXEC_MODE_SCHEDULE; (*pQuery)->haveResultSet = false; (*pQuery)->msgType = TDMT_VND_SUBMIT; (*pQuery)->pRoot = (SNode*)context.pOutput; } + if (NULL == (*pQuery)->pTableList) { + (*pQuery)->pTableList = taosArrayInit(taosHashGetSize(context.pTableNameHashObj), sizeof(SName)); + if (NULL == (*pQuery)->pTableList) { + return TSDB_CODE_OUT_OF_MEMORY; + } + } + context.pOutput->payloadType = PAYLOAD_TYPE_KV; int32_t code = skipInsertInto(&context); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index c86c1ac2e9..b7f007fce6 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1538,7 +1538,9 @@ static EDealRes checkStateExpr(SNode* pNode, void* pContext) { if (QUERY_NODE_COLUMN == nodeType(pNode)) { STranslateContext* pCxt = pContext; SColumnNode* pCol = (SColumnNode*)pNode; - if (!IS_INTEGER_TYPE(pCol->node.resType.type)) { + + int32_t type = pCol->node.resType.type; + if (!IS_INTEGER_TYPE(type) && type != TSDB_DATA_TYPE_BOOL && !IS_VAR_DATA_TYPE(type)) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE); } if (COLUMN_TYPE_TAG == pCol->colType) { diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 43aea8de7c..7183d956a9 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -91,7 +91,7 @@ static char* getSyntaxErrFormat(int32_t errCode) { case TSDB_CODE_PAR_AGG_FUNC_NESTING: return "Aggregate functions do not support nesting"; case TSDB_CODE_PAR_INVALID_STATE_WIN_TYPE: - return "Only support STATE_WINDOW on integer column"; + return "Only support STATE_WINDOW on integer/bool/varchar column"; case TSDB_CODE_PAR_INVALID_STATE_WIN_COL: return "Not support STATE_WINDOW on tag column"; case TSDB_CODE_PAR_INVALID_STATE_WIN_TABLE: diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 2652078b96..5962867869 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -184,5 +184,6 @@ int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery) { if (TSDB_CODE_SUCCESS == code) { code = calculateConstant(pCxt, pQuery); } + return code; } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 5ed7d9c1b5..6ae1b23b97 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -228,10 +228,12 @@ static void setScanWindowInfo(SScanLogicNode* pScan) { static int32_t osdOptimize(SOptimizeContext* pCxt, SLogicNode* pLogicNode) { SOsdInfo info = {0}; int32_t code = osdMatch(pCxt, pLogicNode, &info); + if (TSDB_CODE_SUCCESS == code && info.pScan) { + setScanWindowInfo((SScanLogicNode*)info.pScan); + } if (TSDB_CODE_SUCCESS == code && (NULL != info.pDsoFuncs || NULL != info.pSdrFuncs)) { info.pScan->dataRequired = osdGetDataRequired(info.pSdrFuncs); info.pScan->pDynamicScanFuncs = info.pDsoFuncs; - setScanWindowInfo((SScanLogicNode*)info.pScan); OPTIMIZE_FLAG_SET_MASK(info.pScan->node.optimizedFlag, OPTIMIZE_FLAG_OSD); pCxt->optimized = true; } diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 835d607099..edf44424e3 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -460,9 +460,13 @@ static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubp memcpy(pTableScan->scanSeq, pScanLogicNode->scanSeq, sizeof(pScanLogicNode->scanSeq)); pTableScan->scanRange = pScanLogicNode->scanRange; pTableScan->ratio = pScanLogicNode->ratio; - vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); - taosArrayPush(pCxt->pExecNodeList, &pSubplan->execNode); - pSubplan->execNodeStat.tableNum = pScanLogicNode->pVgroupList->vgroups[0].numOfTable; + if (pScanLogicNode->pVgroupList) { + vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); + pSubplan->execNodeStat.tableNum = pScanLogicNode->pVgroupList->vgroups[0].numOfTable; + } + if (pCxt->pExecNodeList) { + taosArrayPush(pCxt->pExecNodeList, &pSubplan->execNode); + } tNameGetFullDbName(&pScanLogicNode->tableName, pSubplan->dbFName); pTableScan->dataRequired = pScanLogicNode->dataRequired; pTableScan->pDynamicScanFuncs = nodesCloneList(pScanLogicNode->pDynamicScanFuncs); @@ -505,13 +509,12 @@ static int32_t createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* static int32_t createStreamScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) { - SStreamScanPhysiNode* pScan = - (SStreamScanPhysiNode*)makePhysiNode(pCxt, pScanLogicNode->pMeta->tableInfo.precision, - (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN); - if (NULL == pScan) { - return TSDB_CODE_OUT_OF_MEMORY; + int32_t res = createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); + if (res == TSDB_CODE_SUCCESS) { + ENodeType type = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN; + setNodeType(*pPhyNode, type); } - return createScanPhysiNodeFinalize(pCxt, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode); + return res; } static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, @@ -786,7 +789,7 @@ static int32_t doCreateExchangePhysiNode(SPhysiPlanContext* pCxt, SExchangeLogic } static int32_t createStreamScanPhysiNodeByExchange(SPhysiPlanContext* pCxt, SExchangeLogicNode* pExchangeLogicNode, SPhysiNode** pPhyNode) { - SStreamScanPhysiNode* pScan = (SStreamScanPhysiNode*)makePhysiNode( + SScanPhysiNode* pScan = (SScanPhysiNode*)makePhysiNode( pCxt, pExchangeLogicNode->precision, (SLogicNode*)pExchangeLogicNode, QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN); if (NULL == pScan) { return TSDB_CODE_OUT_OF_MEMORY; diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c index 4b4c079649..4c05358a13 100644 --- a/source/libs/qcom/src/queryUtil.c +++ b/source/libs/qcom/src/queryUtil.c @@ -97,7 +97,7 @@ bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTag static void* pTaskQueue = NULL; int32_t initTaskQueue() { - int32_t queueSize = tsMaxConnections * 2; + int32_t queueSize = tsMaxShellConns * 2; pTaskQueue = taosInitScheduler(queueSize, tsNumOfTaskQueueThreads, "tsc"); if (NULL == pTaskQueue) { qError("failed to init task queue"); diff --git a/source/libs/qcom/src/querymsg.c b/source/libs/qcom/src/querymsg.c index 822c214fe5..fb9319bede 100644 --- a/source/libs/qcom/src/querymsg.c +++ b/source/libs/qcom/src/querymsg.c @@ -290,6 +290,10 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isSuperTable, STabl pTableMeta->sversion = msg->sversion; pTableMeta->tversion = msg->tversion; + if (isSuperTable) { + qDebug("stable %s meta returned, suid:%" PRIx64, msg->stbName, pTableMeta->suid); + } + pTableMeta->tableInfo.numOfTags = msg->numOfTags; pTableMeta->tableInfo.precision = msg->precision; pTableMeta->tableInfo.numOfColumns = msg->numOfColumns; diff --git a/source/libs/scalar/CMakeLists.txt b/source/libs/scalar/CMakeLists.txt index 02d530533c..87f4bb9c64 100644 --- a/source/libs/scalar/CMakeLists.txt +++ b/source/libs/scalar/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories( ) target_link_libraries(scalar - PRIVATE os util common nodes function qcom + PRIVATE os util common nodes function qcom vnode ) if(${BUILD_TEST}) diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h index 1e7d1a4cbf..99e61ad1db 100644 --- a/source/libs/scalar/inc/sclInt.h +++ b/source/libs/scalar/inc/sclInt.h @@ -26,15 +26,19 @@ typedef struct SScalarCtx { int32_t code; SArray *pBlockList; /* element is SSDataBlock* */ SHashObj *pRes; /* element is SScalarParam */ + void *param; // additional parameter (meta actually) for acquire value such as tbname/tags values + SHashObj *udf2Handle; } SScalarCtx; #define SCL_DATA_TYPE_DUMMY_HASH 9000 #define SCL_DEFAULT_OP_NUM 10 +#define SCL_DEFAULT_UDF_NUM 8 #define SCL_IS_CONST_NODE(_node) ((NULL == (_node)) || (QUERY_NODE_VALUE == (_node)->type) || (QUERY_NODE_NODE_LIST == (_node)->type)) #define SCL_IS_CONST_CALC(_ctx) (NULL == (_ctx)->pBlockList) -#define SCL_IS_NULL_VALUE_NODE(_node) ((QUERY_NODE_VALUE == nodeType(_node)) && (TSDB_DATA_TYPE_NULL == ((SValueNode *)_node)->node.resType.type) && (((SValueNode *)_node)->placeholderNo <= 0)) +//#define SCL_IS_NULL_VALUE_NODE(_node) ((QUERY_NODE_VALUE == nodeType(_node)) && (TSDB_DATA_TYPE_NULL == ((SValueNode *)_node)->node.resType.type) && (((SValueNode *)_node)->placeholderNo <= 0)) +#define SCL_IS_NULL_VALUE_NODE(_node) ((QUERY_NODE_VALUE == nodeType(_node)) && (TSDB_DATA_TYPE_NULL == ((SValueNode *)_node)->node.resType.type)) #define sclFatal(...) qFatal(__VA_ARGS__) #define sclError(...) qError(__VA_ARGS__) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index d7cac69d26..c9917d8544 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -153,6 +153,18 @@ void sclFreeRes(SHashObj *res) { taosHashCleanup(res); } +void sclFreeUdfHandles(SHashObj *udf2handle) { + void *pIter = taosHashIterate(udf2handle, NULL); + while (pIter) { + UdfcFuncHandle *handle = (UdfcFuncHandle *)pIter; + if (handle) { + teardownUdf(*handle); + } + pIter = taosHashIterate(udf2handle, pIter); + } + taosHashCleanup(udf2handle); +} + void sclFreeParam(SScalarParam *param) { if (param->columnData != NULL) { colDataDestroy(param->columnData); @@ -265,6 +277,7 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t *rowNum = param->numOfRows; } + param->param = ctx->param; return TSDB_CODE_SUCCESS; } @@ -361,22 +374,28 @@ int32_t sclExecFunction(SFunctionNode *node, SScalarCtx *ctx, SScalarParam *outp if (fmIsUserDefinedFunc(node->funcId)) { UdfcFuncHandle udfHandle = NULL; - - code = setupUdf(node->functionName, &udfHandle); - if (code != 0) { - sclError("fmExecFunction error. setupUdf. function name: %s, code:%d", node->functionName, code); - goto _return; + char* udfName = node->functionName; + if (ctx->udf2Handle) { + UdfcFuncHandle *pHandle = taosHashGet(ctx->udf2Handle, udfName, strlen(udfName)); + if (pHandle) { + udfHandle = *pHandle; + } + } + if (udfHandle == NULL) { + code = setupUdf(udfName, &udfHandle); + if (code != 0) { + sclError("fmExecFunction error. setupUdf. function name: %s, code:%d", udfName, code); + goto _return; + } + if (ctx->udf2Handle) { + taosHashPut(ctx->udf2Handle, udfName, strlen(udfName), &udfHandle, sizeof(UdfcFuncHandle)); + } } code = callUdfScalarFunc(udfHandle, params, paramNum, output); if (code != 0) { sclError("fmExecFunction error. callUdfScalarFunc. function name: %s, udf code:%d", node->functionName, code); goto _return; } - code = teardownUdf(udfHandle); - if (code != 0) { - sclError("fmExecFunction error. callUdfScalarFunc. function name: %s, udf code:%d", node->functionName, code); - goto _return; - } } else { SScalarFuncExecFuncs ffpSet = {0}; code = fmGetScalarFuncExecFuncs(node->funcId, &ffpSet); @@ -890,15 +909,20 @@ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { SScalarCtx ctx = {0}; ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); if (NULL == ctx.pRes) { - sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); + sclError("taosHashInit result map failed, num:%d", SCL_DEFAULT_OP_NUM); + SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + ctx.udf2Handle = taosHashInit(SCL_DEFAULT_UDF_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + if (NULL == ctx.udf2Handle) { + sclError("taosHashInit udf to handle map failed, num:%d", SCL_DEFAULT_OP_NUM); SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - nodesRewriteExprPostOrder(&pNode, sclConstantsRewriter, (void *)&ctx); SCL_ERR_JRET(ctx.code); *pRes = pNode; _return: + sclFreeUdfHandles(ctx.udf2Handle); sclFreeRes(ctx.pRes); return code; } @@ -909,15 +933,19 @@ int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) { } int32_t code = 0; - SScalarCtx ctx = {.code = 0, .pBlockList = pBlockList}; + SScalarCtx ctx = {.code = 0, .pBlockList = pBlockList, .param = pDst->param}; // TODO: OPT performance ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); if (NULL == ctx.pRes) { - sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); + sclError("taosHashInit result map failed, num:%d", SCL_DEFAULT_OP_NUM); + SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + ctx.udf2Handle = taosHashInit(SCL_DEFAULT_UDF_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); + if (NULL == ctx.udf2Handle) { + sclError("taosHashInit udf to handle map failed, num:%d", SCL_DEFAULT_OP_NUM); SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx); SCL_ERR_JRET(ctx.code); @@ -935,6 +963,7 @@ int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) { _return: //nodesDestroyNode(pNode); + sclFreeUdfHandles(ctx.udf2Handle); sclFreeRes(ctx.pRes); return code; } diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 0161323e37..d4a88622e2 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1,10 +1,11 @@ #include "function.h" #include "scalar.h" -#include "tdatablock.h" -#include "ttime.h" #include "sclInt.h" #include "sclvector.h" +#include "tdatablock.h" #include "tjson.h" +#include "ttime.h" +#include "vnode.h" typedef float (*_float_fn)(float); typedef double (*_double_fn)(double); @@ -1512,6 +1513,21 @@ int32_t winEndTsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *p int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { ASSERT(inputNum == 1); - colDataAppend(pOutput->columnData, pOutput->numOfRows, colDataGetData(pInput->columnData, 0), false); + + SMetaReader mr = {0}; + metaReaderInit(&mr, pInput->param, 0); + + uint64_t uid = *(uint64_t *)colDataGetData(pInput->columnData, 0); + metaGetTableEntryByUid(&mr, uid); + + char str[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0}; + STR_TO_VARSTR(str, mr.me.name); + metaReaderClear(&mr); + + for(int32_t i = 0; i < pInput->numOfRows; ++i) { + colDataAppend(pOutput->columnData, pOutput->numOfRows + i, str, false); + } + + pOutput->numOfRows += pInput->numOfRows; return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/tstream.c b/source/libs/stream/src/tstream.c index 237f673a47..08093c8b18 100644 --- a/source/libs/stream/src/tstream.c +++ b/source/libs/stream/src/tstream.c @@ -154,7 +154,7 @@ int32_t streamExecTask(SStreamTask* pTask, SMsgCb* pMsgCb, const void* input, in // sink if (pTask->sinkType == TASK_SINK__TABLE) { - /*blockDebugShowData(pRes);*/ + // blockDebugShowData(pRes); pTask->tbSink.tbSinkFunc(pTask, pTask->tbSink.vnode, 0, pRes); } else if (pTask->sinkType == TASK_SINK__SMA) { pTask->smaSink.smaSink(pTask->ahandle, pTask->smaSink.smaId, pRes); diff --git a/source/libs/transport/src/transCli.c b/source/libs/transport/src/transCli.c index 718be6aa64..cd7e3beb13 100644 --- a/source/libs/transport/src/transCli.c +++ b/source/libs/transport/src/transCli.c @@ -13,7 +13,6 @@ */ #ifdef USE_UV - #include "transComm.h" typedef struct SCliConn { @@ -21,15 +20,16 @@ typedef struct SCliConn { uv_connect_t connReq; uv_stream_t* stream; uv_write_t writeReq; - void* hostThrd; - SConnBuffer readBuf; - void* data; - STransQueue cliMsgs; - queue conn; - uint64_t expireTime; - int hThrdIdx; - STransCtx ctx; + void* hostThrd; + int hThrdIdx; + + SConnBuffer readBuf; + STransQueue cliMsgs; + queue conn; + uint64_t expireTime; + + STransCtx ctx; bool broken; // link broken or not ConnStatus status; // @@ -157,13 +157,11 @@ static void cliWalkCb(uv_handle_t* handle, void* arg); transClearBuffer(&conn->readBuf); \ transFreeMsg(transContFromHead((char*)head)); \ tDebug("cli conn %p receive release request, ref: %d", conn, T_REF_VAL_GET(conn)); \ - while (T_REF_VAL_GET(conn) > 1) { \ - transUnrefCliHandle(conn); \ - } \ - if (T_REF_VAL_GET(conn) == 1) { \ + if (T_REF_VAL_GET(conn) > 1) { \ transUnrefCliHandle(conn); \ } \ destroyCmsg(pMsg); \ + addConnToPool(((SCliThrdObj*)conn->hostThrd)->pool, conn); \ return; \ } \ } while (0) @@ -707,7 +705,8 @@ SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) { void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) { uint64_t et = taosGetTimestampUs(); uint64_t el = et - pMsg->st; - tTrace("%s cli msg tran time cost: %" PRIu64 "us", ((STrans*)pThrd->pTransInst)->label, el); + tTrace("%s cli msg tran time cost: %" PRIu64 "us, threadID: %" PRId64 "", ((STrans*)pThrd->pTransInst)->label, el, + pThrd->thread); STransConnCtx* pCtx = pMsg->ctx; STrans* pTransInst = pThrd->pTransInst; @@ -1030,8 +1029,8 @@ void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STra SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[index]; - tDebug("send request at thread:%d %p, dst: %s:%d, app:%p", index, pReq, EPSET_GET_INUSE_IP(&pCtx->epSet), - EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle); + tDebug("send request at thread:%d, threadID: %" PRId64 ", msg: %p, dst: %s:%d, app:%p", index, thrd->thread, pReq, + EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle); ASSERT(transSendAsync(thrd->asyncPool, &(cliMsg->q)) == 0); } @@ -1058,8 +1057,8 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM cliMsg->type = Normal; SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[index]; - tDebug("send request at thread:%d %p, dst: %s:%d, app:%p", index, pReq, EPSET_GET_INUSE_IP(&pCtx->epSet), - EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle); + tDebug("send request at thread:%d, threadID:%" PRId64 ", msg: %p, dst: %s:%d, app:%p", index, thrd->thread, pReq, + EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle); transSendAsync(thrd->asyncPool, &(cliMsg->q)); tsem_t* pSem = pCtx->pSem; diff --git a/source/libs/transport/src/transSrv.c b/source/libs/transport/src/transSrv.c index af66d39904..fc840691b6 100644 --- a/source/libs/transport/src/transSrv.c +++ b/source/libs/transport/src/transSrv.c @@ -35,7 +35,6 @@ typedef struct SSrvConn { uv_timer_t pTimer; queue queue; - int persist; // persist connection or not SConnBuffer readBuf; // read buf, int inType; void* pTransInst; // rpc init @@ -138,6 +137,7 @@ static void destroySmsg(SSrvMsg* smsg); // check whether already read complete packet static SSrvConn* createConn(void* hThrd); static void destroyConn(SSrvConn* conn, bool clear /*clear handle or not*/); +static int reallocConnRefHandle(SSrvConn* conn); static void uvHandleQuit(SSrvMsg* msg, SWorkThrdObj* thrd); static void uvHandleRelease(SSrvMsg* msg, SWorkThrdObj* thrd); @@ -164,7 +164,7 @@ static void* transWorkerThread(void* arg); static void* transAcceptThread(void* arg); // add handle loop -static bool addHandleToWorkloop(SWorkThrdObj* pThrd,char *pipeName); +static bool addHandleToWorkloop(SWorkThrdObj* pThrd, char* pipeName); static bool addHandleToAcceptloop(void* arg); #define CONN_SHOULD_RELEASE(conn, head) \ @@ -180,6 +180,7 @@ static bool addHandleToAcceptloop(void* arg); srvMsg->msg = tmsg; \ srvMsg->type = Release; \ srvMsg->pConn = conn; \ + reallocConnRefHandle(conn); \ if (!transQueuePush(&conn->srvMsgs, srvMsg)) { \ return; \ } \ @@ -360,10 +361,14 @@ void uvOnSendCb(uv_write_t* req, int status) { tTrace("server conn %p data already was written on stream", conn); if (!transQueueEmpty(&conn->srvMsgs)) { SSrvMsg* msg = transQueuePop(&conn->srvMsgs); - if (msg->type == Release && conn->status != ConnNormal) { - conn->status = ConnNormal; - transUnrefSrvHandle(conn); - } + // if (msg->type == Release && conn->status != ConnNormal) { + // conn->status = ConnNormal; + // transUnrefSrvHandle(conn); + // reallocConnRefHandle(conn); + // destroySmsg(msg); + // transQueueClear(&conn->srvMsgs); + // return; + //} destroySmsg(msg); // send second data, just use for push if (!transQueueEmpty(&conn->srvMsgs)) { @@ -421,8 +426,15 @@ static void uvPrepareSendData(SSrvMsg* smsg, uv_buf_t* wb) { if (pConn->status == ConnNormal) { pHead->msgType = pConn->inType + 1; } else { - pHead->msgType = smsg->type == Release ? 0 : pMsg->msgType; + if (smsg->type == Release) { + pHead->msgType = 0; + pConn->status = ConnNormal; + transUnrefSrvHandle(pConn); + } else { + pHead->msgType = pMsg->msgType; + } } + pHead->release = smsg->type == Release ? 1 : 0; pHead->code = htonl(pMsg->code); @@ -517,7 +529,7 @@ void uvWorkerAsyncCb(uv_async_t* handle) { int64_t refId = transMsg.refId; SExHandle* exh2 = uvAcquireExHandle(refId); if (exh2 == NULL || exh1 != exh2) { - tTrace("server handle %p except msg, ignore it", exh1); + tTrace("server handle except msg %p, ignore it", exh1); uvReleaseExHandle(refId); destroySmsg(msg); continue; @@ -581,11 +593,12 @@ void uvOnAcceptCb(uv_stream_t* stream, int status) { if (uv_accept(stream, (uv_stream_t*)cli) == 0) { if (pObj->numOfWorkerReady < pObj->numOfThreads) { - tError("worker-threads are not ready for all, need %d instead of %d.", pObj->numOfThreads, pObj->numOfWorkerReady); + tError("worker-threads are not ready for all, need %d instead of %d.", pObj->numOfThreads, + pObj->numOfWorkerReady); uv_close((uv_handle_t*)cli, NULL); return; } - + uv_write_t* wr = (uv_write_t*)taosMemoryMalloc(sizeof(uv_write_t)); wr->data = cli; uv_buf_t buf = uv_buf_init((char*)notify, strlen(notify)); @@ -681,14 +694,14 @@ void* transAcceptThread(void* arg) { return NULL; } -void uvOnPipeConnectionCb(uv_connect_t *connect, int status) { +void uvOnPipeConnectionCb(uv_connect_t* connect, int status) { if (status != 0) { return; } SWorkThrdObj* pThrd = container_of(connect, SWorkThrdObj, connect_req); uv_read_start((uv_stream_t*)pThrd->pipe, uvAllocConnBufferCb, uvOnConnectionCb); } -static bool addHandleToWorkloop(SWorkThrdObj* pThrd,char *pipeName) { +static bool addHandleToWorkloop(SWorkThrdObj* pThrd, char* pipeName) { pThrd->loop = (uv_loop_t*)taosMemoryMalloc(sizeof(uv_loop_t)); if (0 != uv_loop_init(pThrd->loop)) { return false; @@ -787,6 +800,19 @@ static void destroyConn(SSrvConn* conn, bool clear) { // uv_shutdown(req, (uv_stream_t*)conn->pTcp, uvShutDownCb); } } +static int reallocConnRefHandle(SSrvConn* conn) { + uvReleaseExHandle(conn->refId); + uvRemoveExHandle(conn->refId); + // avoid app continue to send msg on invalid handle + SExHandle* exh = taosMemoryMalloc(sizeof(SExHandle)); + exh->handle = conn; + exh->pThrd = conn->hostThrd; + exh->refId = uvAddExHandle(exh); + uvAcquireExHandle(exh->refId); + conn->refId = exh->refId; + + return 0; +} static void uvDestroyConn(uv_handle_t* handle) { SSrvConn* conn = handle->data; if (conn == NULL) { @@ -822,7 +848,7 @@ static void uvPipeListenCb(uv_stream_t* handle, int status) { ASSERT(status == 0); SServerObj* srv = container_of(handle, SServerObj, pipeListen); - uv_pipe_t* pipe = &(srv->pipe[srv->numOfWorkerReady][0]); + uv_pipe_t* pipe = &(srv->pipe[srv->numOfWorkerReady][0]); ASSERT(0 == uv_pipe_init(srv->loop, pipe, 1)); ASSERT(0 == uv_accept((uv_stream_t*)&srv->pipeListen, (uv_stream_t*)pipe)); @@ -859,7 +885,8 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, snprintf(pipeName, sizeof(pipeName), "\\\\?\\pipe\\trans.rpc.%p-%lu", taosSafeRand(), GetCurrentProcessId()); #else char pipeName[PATH_MAX] = {0}; - snprintf(pipeName, sizeof(pipeName), "%s%spipe.trans.rpc.%08X-%lu", tsTempDir, TD_DIRSEP, taosSafeRand(), taosGetSelfPthreadId()); + snprintf(pipeName, sizeof(pipeName), "%s%spipe.trans.rpc.%08X-%lu", tsTempDir, TD_DIRSEP, taosSafeRand(), + taosGetSelfPthreadId()); #endif assert(0 == uv_pipe_bind(&srv->pipeListen, pipeName)); assert(0 == uv_listen((uv_stream_t*)&srv->pipeListen, SOMAXCONN, uvPipeListenCb)); @@ -874,7 +901,7 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads, srv->pipe[i] = (uv_pipe_t*)taosMemoryCalloc(2, sizeof(uv_pipe_t)); thrd->pipe = &(srv->pipe[i][1]); // init read - if (false == addHandleToWorkloop(thrd,pipeName)) { + if (false == addHandleToWorkloop(thrd, pipeName)) { goto End; } int err = taosThreadCreate(&(thrd->thread), NULL, transWorkerThread, (void*)(thrd)); @@ -959,6 +986,7 @@ void uvHandleQuit(SSrvMsg* msg, SWorkThrdObj* thrd) { void uvHandleRelease(SSrvMsg* msg, SWorkThrdObj* thrd) { SSrvConn* conn = msg->pConn; if (conn->status == ConnAcquire) { + reallocConnRefHandle(conn); if (!transQueuePush(&conn->srvMsgs, msg)) { return; } diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index a0c65c8ed6..f92c650965 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -54,7 +54,7 @@ int32_t walRegisterRead(SWalReadHandle *pRead, int64_t ver) { return 0; } -static int32_t walReadSeekFilePos(SWalReadHandle *pRead, int64_t fileFirstVer, int64_t ver) { +static int64_t walReadSeekFilePos(SWalReadHandle *pRead, int64_t fileFirstVer, int64_t ver) { int64_t ret = 0; TdFilePtr pIdxTFile = pRead->pReadIdxTFile; @@ -156,7 +156,7 @@ static int32_t walReadSeekVer(SWalReadHandle *pRead, int64_t ver) { void walSetReaderCapacity(SWalReadHandle *pRead, int32_t capacity) { pRead->capacity = capacity; } int32_t walFetchHead(SWalReadHandle *pRead, int64_t ver, SWalHead *pHead) { - int32_t code; + int64_t code; // TODO: valid ver if (ver > pRead->pWal->vers.commitVer) { @@ -214,23 +214,24 @@ int32_t walFetchBody(SWalReadHandle *pRead, SWalHead **ppHead) { return -1; } *ppHead = ptr; + pReadHead = &((*ppHead)->head); pRead->capacity = pReadHead->bodyLen; } if (pReadHead->bodyLen != taosReadFile(pRead->pReadLogTFile, pReadHead->body, pReadHead->bodyLen)) { + ASSERT(0); return -1; } if (pReadHead->version != ver) { - wError("unexpected wal log version: %" PRId64 ", read request version:%" PRId64 "", pRead->pHead->head.version, - ver); + wError("wal fetch body error: %" PRId64 ", read request version:%" PRId64 "", pRead->pHead->head.version, ver); pRead->curVersion = -1; terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; } if (walValidBodyCksum(*ppHead) != 0) { - wError("unexpected wal log version: % " PRId64 ", since body checksum not passed", ver); + wError("wal fetch body error: % " PRId64 ", since body checksum not passed", ver); pRead->curVersion = -1; terrno = TSDB_CODE_WAL_FILE_CORRUPTED; return -1; @@ -257,7 +258,7 @@ int32_t walReadWithHandle_s(SWalReadHandle *pRead, int64_t ver, SWalReadHead **p } int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { - int code; + int64_t code; // TODO: check wal life if (pRead->curVersion != ver) { if (walReadSeekVer(pRead, ver) < 0) { diff --git a/source/libs/wal/src/walSeek.c b/source/libs/wal/src/walSeek.c index a6f238af6b..b99206fe98 100644 --- a/source/libs/wal/src/walSeek.c +++ b/source/libs/wal/src/walSeek.c @@ -19,8 +19,8 @@ #include "tref.h" #include "walInt.h" -static int walSeekWritePos(SWal* pWal, int64_t ver) { - int code = 0; +static int64_t walSeekWritePos(SWal* pWal, int64_t ver) { + int64_t code = 0; TdFilePtr pIdxTFile = pWal->pWriteIdxTFile; TdFilePtr pLogTFile = pWal->pWriteLogTFile; @@ -45,7 +45,7 @@ static int walSeekWritePos(SWal* pWal, int64_t ver) { terrno = TAOS_SYSTEM_ERROR(errno); return -1; } - return code; + return 0; } int walSetWrite(SWal* pWal) { @@ -124,7 +124,7 @@ int walChangeWrite(SWal* pWal, int64_t ver) { } int walSeekWriteVer(SWal* pWal, int64_t ver) { - int code; + int64_t code; if (ver == pWal->vers.lastVer) { return 0; } diff --git a/source/os/src/osAtomic.c b/source/os/src/osAtomic.c index 0fe946bf68..e4d880f40a 100644 --- a/source/os/src/osAtomic.c +++ b/source/os/src/osAtomic.c @@ -36,7 +36,7 @@ int64_t interlocked_add_fetch_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_add_fetch_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)(_InterlockedExchangeAdd((int32_t volatile*)(ptr), (int32_t)val) + (int32_t)val); #else return (void*)(InterlockedExchangeAdd64((int64_t volatile*)(ptr), (int64_t)val) + (int64_t)val); @@ -56,7 +56,7 @@ int32_t interlocked_and_fetch_32(int32_t volatile* ptr, int32_t val) { } int64_t interlocked_and_fetch_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old, res; do { old = *ptr; @@ -69,7 +69,7 @@ int64_t interlocked_and_fetch_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_and_fetch_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)interlocked_and_fetch_32((int32_t volatile*)ptr, (int32_t)val); #else return (void*)interlocked_and_fetch_64((int64_t volatile*)ptr, (int64_t)val); @@ -77,7 +77,7 @@ void* interlocked_and_fetch_ptr(void* volatile* ptr, void* val) { } int64_t interlocked_fetch_and_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old; do { old = *ptr; @@ -89,7 +89,7 @@ int64_t interlocked_fetch_and_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_fetch_and_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)_InterlockedAnd((int32_t volatile*)(ptr), (int32_t)(val)); #else return (void*)_InterlockedAnd64((int64_t volatile*)(ptr), (int64_t)(val)); @@ -109,7 +109,7 @@ int32_t interlocked_or_fetch_32(int32_t volatile* ptr, int32_t val) { } int64_t interlocked_or_fetch_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old, res; do { old = *ptr; @@ -122,7 +122,7 @@ int64_t interlocked_or_fetch_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_or_fetch_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)interlocked_or_fetch_32((int32_t volatile*)ptr, (int32_t)val); #else return (void*)interlocked_or_fetch_64((int64_t volatile*)ptr, (int64_t)val); @@ -130,7 +130,7 @@ void* interlocked_or_fetch_ptr(void* volatile* ptr, void* val) { } int64_t interlocked_fetch_or_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old; do { old = *ptr; @@ -142,7 +142,7 @@ int64_t interlocked_fetch_or_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_fetch_or_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)_InterlockedOr((int32_t volatile*)(ptr), (int32_t)(val)); #else return (void*)interlocked_fetch_or_64((int64_t volatile*)(ptr), (int64_t)(val)); @@ -162,7 +162,7 @@ int32_t interlocked_xor_fetch_32(int32_t volatile* ptr, int32_t val) { } int64_t interlocked_xor_fetch_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old, res; do { old = *ptr; @@ -175,7 +175,7 @@ int64_t interlocked_xor_fetch_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_xor_fetch_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)interlocked_xor_fetch_32((int32_t volatile*)(ptr), (int32_t)(val)); #else return (void*)interlocked_xor_fetch_64((int64_t volatile*)(ptr), (int64_t)(val)); @@ -183,7 +183,7 @@ void* interlocked_xor_fetch_ptr(void* volatile* ptr, void* val) { } int64_t interlocked_fetch_xor_64(int64_t volatile* ptr, int64_t val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS int64_t old; do { old = *ptr; @@ -195,7 +195,7 @@ int64_t interlocked_fetch_xor_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_fetch_xor_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)_InterlockedXor((int32_t volatile*)(ptr), (int32_t)(val)); #else return (void*)interlocked_fetch_xor_64((int64_t volatile*)(ptr), (int64_t)(val)); @@ -211,7 +211,7 @@ int64_t interlocked_sub_fetch_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_sub_fetch_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)interlocked_sub_fetch_32((int32_t volatile*)ptr, (int32_t)val); #else return (void*)interlocked_add_fetch_64((int64_t volatile*)ptr, (int64_t)val); @@ -226,7 +226,7 @@ int64_t interlocked_fetch_sub_64(int64_t volatile* ptr, int64_t val) { } void* interlocked_fetch_sub_ptr(void* volatile* ptr, void* val) { -#ifdef _TD_WINDOWS_32 +#ifdef WINDOWS return (void*)interlocked_fetch_sub_32((int32_t volatile*)ptr, (int32_t)val); #else return (void*)interlocked_fetch_sub_64((int64_t volatile*)ptr, (int64_t)val); diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c index 425bf8b7ac..3cd05b65cd 100644 --- a/source/os/src/osFile.c +++ b/source/os/src/osFile.c @@ -109,6 +109,7 @@ void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, cha int64_t taosCopyFile(const char *from, const char *to) { #ifdef WINDOWS + assert(0); return 0; #else char buffer[4096]; @@ -152,16 +153,16 @@ int32_t taosRemoveFile(const char *path) { return remove(path); } int32_t taosRenameFile(const char *oldName, const char *newName) { #ifdef WINDOWS - int32_t code = MoveFileEx(oldName, newName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); - if (code < 0) { - // printf("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); + bool code = MoveFileEx(oldName, newName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); + if (!code) { + printf("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); } - return code; + return !code; #else int32_t code = rename(oldName, newName); if (code < 0) { - // printf("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); + printf("failed to rename file %s to %s, reason:%s", oldName, newName, strerror(errno)); } return code; @@ -169,11 +170,12 @@ int32_t taosRenameFile(const char *oldName, const char *newName) { } int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime) { -#ifdef WINDOWS - return 0; -#else struct stat fileStat; +#ifdef WINDOWS + int32_t code = _stat(path, &fileStat); +#else int32_t code = stat(path, &fileStat); +#endif if (code < 0) { return code; } @@ -187,14 +189,15 @@ int32_t taosStatFile(const char *path, int64_t *size, int32_t *mtime) { } return 0; -#endif } int32_t taosDevInoFile(const char *path, int64_t *stDev, int64_t *stIno) { -#ifdef WINDOWS - return 0; -#else + struct stat fileStat; +#ifdef WINDOWS + int32_t code = _stat(path, &fileStat); +#else int32_t code = stat(path, &fileStat); +#endif if (code < 0) { return code; } @@ -208,7 +211,6 @@ int32_t taosDevInoFile(const char *path, int64_t *stDev, int64_t *stIno) { } return 0; -#endif } void autoDelFileListAdd(const char *path) { return; } @@ -276,9 +278,6 @@ TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) { } int64_t taosCloseFile(TdFilePtr *ppFile) { -#ifdef WINDOWS - return 0; -#else if (ppFile == NULL || *ppFile == NULL) { return 0; } @@ -294,7 +293,12 @@ int64_t taosCloseFile(TdFilePtr *ppFile) { (*ppFile)->fp = NULL; } if ((*ppFile)->fd >= 0) { + #ifdef WINDOWS + HANDLE h = (HANDLE)_get_osfhandle((*ppFile)->fd); + !FlushFileBuffers(h); + #else fsync((*ppFile)->fd); + #endif close((*ppFile)->fd); (*ppFile)->fd = -1; } @@ -306,7 +310,6 @@ int64_t taosCloseFile(TdFilePtr *ppFile) { taosMemoryFree(*ppFile); *ppFile = NULL; return 0; -#endif } int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) { @@ -412,13 +415,17 @@ int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) { } int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime) { -#ifdef WINDOWS - return 0; -#else + if (pFile == NULL) { + return 0; + } assert(pFile->fd >= 0); // Please check if you have closed the file. struct stat fileStat; +#ifdef WINDOWS + int32_t code = _fstat(pFile->fd, &fileStat); +#else int32_t code = fstat(pFile->fd, &fileStat); +#endif if (code < 0) { return code; } @@ -432,7 +439,6 @@ int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int32_t *mtime) { } return 0; -#endif } int32_t taosLockFile(TdFilePtr pFile) { @@ -459,7 +465,7 @@ int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) { #ifdef WINDOWS if (pFile->fd < 0) { errno = EBADF; - printf("%s\n", "fd arg was negative"); + printf("Ftruncate file error, fd arg was negative\n"); return -1; } @@ -516,26 +522,20 @@ int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) { } int32_t taosFsyncFile(TdFilePtr pFile) { -#ifdef WINDOWS - if (pFile->fd < 0) { - errno = EBADF; - printf("%s\n", "fd arg was negative"); - return -1; - } - - HANDLE h = (HANDLE)_get_osfhandle(pFile->fd); - - return !FlushFileBuffers(h); -#else if (pFile == NULL) { return 0; } if (pFile->fp != NULL) return fflush(pFile->fp); - if (pFile->fd >= 0) return fsync(pFile->fd); - + if (pFile->fd >= 0) { + #ifdef WINDOWS + HANDLE h = (HANDLE)_get_osfhandle(pFile->fd); + return !FlushFileBuffers(h); + #else + return fsync(pFile->fd); + #endif + } return 0; -#endif } int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size) { diff --git a/source/os/src/osMemory.c b/source/os/src/osMemory.c index 7c877b463a..e3791af618 100644 --- a/source/os/src/osMemory.c +++ b/source/os/src/osMemory.c @@ -138,7 +138,7 @@ static void print_line(Dwarf_Debug dbg, Dwarf_Line line, Dwarf_Addr pc) { dwarf_linesrc(line, &linesrc, NULL); dwarf_lineno(line, &lineno, NULL); } - printf("%s:%" DW_PR_DUu "\n", linesrc, lineno); + printf("BackTrace %08" PRId64 " %s:%" DW_PR_DUu "\n", taosGetSelfPthreadId(), linesrc, lineno); if (line) dwarf_dealloc(dbg, linesrc, DW_DLA_STRING); } void taosPrintBackTrace() { diff --git a/source/os/src/osProc.c b/source/os/src/osProc.c index f92a3b3783..74f1356abf 100644 --- a/source/os/src/osProc.c +++ b/source/os/src/osProc.c @@ -19,6 +19,7 @@ int32_t taosNewProc(char **args) { #ifdef WINDOWS + assert(0); return 0; #else int32_t pid = fork(); @@ -36,6 +37,7 @@ int32_t taosNewProc(char **args) { void taosWaitProc(int32_t pid) { #ifdef WINDOWS + assert(0); #else int32_t status = -1; waitpid(pid, &status, 0); @@ -44,6 +46,7 @@ void taosWaitProc(int32_t pid) { void taosKillProc(int32_t pid) { #ifdef WINDOWS + assert(0); #else kill(pid, SIGINT); #endif @@ -51,6 +54,7 @@ void taosKillProc(int32_t pid) { bool taosProcExist(int32_t pid) { #ifdef WINDOWS + assert(0); return false; #else int32_t p = getpgid(pid); diff --git a/source/os/src/osShm.c b/source/os/src/osShm.c index 1cd51f94a0..cb09e2fb38 100644 --- a/source/os/src/osShm.c +++ b/source/os/src/osShm.c @@ -23,6 +23,7 @@ static int32_t shmids[MAX_SHMIDS] = {0}; static void taosDeleteCreatedShms() { #if defined(WINDOWS) + assert(0); #else for (int32_t i = 0; i < MAX_SHMIDS; ++i) { int32_t shmid = shmids[i] - 1; @@ -35,6 +36,7 @@ static void taosDeleteCreatedShms() { int32_t taosCreateShm(SShm* pShm, int32_t key, int32_t shmsize) { #if defined(WINDOWS) + assert(0); #else pShm->id = -1; @@ -75,6 +77,7 @@ int32_t taosCreateShm(SShm* pShm, int32_t key, int32_t shmsize) { void taosDropShm(SShm* pShm) { #if defined(WINDOWS) + assert(0); #else if (pShm->id >= 0) { if (pShm->ptr != NULL) { @@ -90,6 +93,7 @@ void taosDropShm(SShm* pShm) { int32_t taosAttachShm(SShm* pShm) { #if defined(WINDOWS) + assert(0); #else errno = 0; diff --git a/source/os/src/osSocket.c b/source/os/src/osSocket.c index 2410586287..105acb188a 100644 --- a/source/os/src/osSocket.c +++ b/source/os/src/osSocket.c @@ -285,6 +285,7 @@ int32_t taosGetSockOpt(TdSocketPtr pSocket, int32_t level, int32_t optname, void return -1; } #ifdef WINDOWS + assert(0); return 0; #else return getsockopt(pSocket->fd, level, optname, optval, (int *)optlen); @@ -642,6 +643,7 @@ int32_t taosKeepTcpAlive(TdSocketPtr pSocket) { int taosGetLocalIp(const char *eth, char *ip) { #if defined(WINDOWS) // DO NOTHAING + assert(0); return 0; #else int fd; @@ -668,6 +670,7 @@ int taosGetLocalIp(const char *eth, char *ip) { int taosValidIp(uint32_t ip) { #if defined(WINDOWS) // DO NOTHAING + assert(0); return 0; #else int ret = -1; @@ -866,6 +869,7 @@ int64_t taosCopyFds(TdSocketPtr pSrcSocket, TdSocketPtr pDestSocket, int64_t len void taosBlockSIGPIPE() { #ifdef WINDOWS + // assert(0); #else sigset_t signal_mask; sigemptyset(&signal_mask); @@ -976,14 +980,12 @@ void tinet_ntoa(char *ipstr, uint32_t ip) { } void taosIgnSIGPIPE() { -#ifdef WINDOWS -#else signal(SIGPIPE, SIG_IGN); -#endif } void taosSetMaskSIGPIPE() { #ifdef WINDOWS + // assert(0); #else sigset_t signal_mask; sigemptyset(&signal_mask); @@ -1005,6 +1007,7 @@ int32_t taosGetSocketName(TdSocketPtr pSocket, struct sockaddr *destAddr, int *a TdEpollPtr taosCreateEpoll(int32_t size) { EpollFd fd = -1; #ifdef WINDOWS + assert(0); #else fd = epoll_create(size); #endif @@ -1027,6 +1030,7 @@ int32_t taosCtlEpoll(TdEpollPtr pEpoll, int32_t epollOperate, TdSocketPtr pSocke return -1; } #ifdef WINDOWS + assert(0); #else code = epoll_ctl(pEpoll->fd, epollOperate, pSocket->fd, event); #endif @@ -1038,6 +1042,7 @@ int32_t taosWaitEpoll(TdEpollPtr pEpoll, struct epoll_event *event, int32_t maxE return -1; } #ifdef WINDOWS + assert(0); #else code = epoll_wait(pEpoll->fd, event, maxEvents, timeout); #endif diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index 348424b372..fd6172e04f 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -129,7 +129,21 @@ static void taosGetProcIOnfos() { static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) { #ifdef WINDOWS + FILETIME pre_idleTime = {0}; + FILETIME pre_kernelTime = {0}; + FILETIME pre_userTime = {0}; + FILETIME idleTime; + FILETIME kernelTime; + FILETIME userTime; + bool res = GetSystemTimes(&idleTime, &kernelTime, &userTime); + if (res) { + cpuInfo->idle = CompareFileTime(&pre_idleTime, &idleTime); + cpuInfo->system = CompareFileTime(&pre_kernelTime, &kernelTime); + cpuInfo->user = CompareFileTime(&pre_userTime, &userTime); + cpuInfo->nice = 0; + } #elif defined(_TD_DARWIN_64) + assert(0); #else TdFilePtr pFile = taosOpenFile(tsSysCpuFile, TD_FILE_READ | TD_FILE_STREAM); if (pFile == NULL) { @@ -155,7 +169,18 @@ static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) { static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) { #ifdef WINDOWS + FILETIME pre_krnlTm = {0}; + FILETIME pre_usrTm = {0}; + FILETIME creatTm, exitTm, krnlTm, usrTm; + + if (GetThreadTimes(GetCurrentThread(), &creatTm, &exitTm, &krnlTm, &usrTm)) { + cpuInfo->stime = CompareFileTime(&pre_krnlTm, &krnlTm); + cpuInfo->utime = CompareFileTime(&pre_usrTm, &usrTm); + cpuInfo->cutime = 0; + cpuInfo->cstime = 0; + } #elif defined(_TD_DARWIN_64) + assert(0); #else TdFilePtr pFile = taosOpenFile(tsProcCpuFile, TD_FILE_READ | TD_FILE_STREAM); if (pFile == NULL) { @@ -219,6 +244,7 @@ void taosGetSystemInfo() { int32_t taosGetEmail(char *email, int32_t maxLen) { #ifdef WINDOWS + // assert(0); #elif defined(_TD_DARWIN_64) const char *filepath = "/usr/local/taos/email"; @@ -250,6 +276,7 @@ int32_t taosGetEmail(char *email, int32_t maxLen) { int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen) { #ifdef WINDOWS + assert(0); #elif defined(_TD_DARWIN_64) char *line = NULL; size_t size = 0; @@ -305,6 +332,7 @@ int32_t taosGetOsReleaseName(char *releaseName, int32_t maxLen) { int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores) { #ifdef WINDOWS + assert(0); #elif defined(_TD_DARWIN_64) char *line = NULL; size_t size = 0; @@ -716,9 +744,7 @@ int32_t taosGetSystemUUID(char *uid, int32_t uidlen) { #ifdef WINDOWS GUID guid; CoCreateGuid(&guid); - - sprintf(uid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], - guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + memcpy(uid, &guid, uidlen); return 0; #elif defined(_TD_DARWIN_64) @@ -750,6 +776,7 @@ int32_t taosGetSystemUUID(char *uid, int32_t uidlen) { char *taosGetCmdlineByPID(int pid) { #ifdef WINDOWS + assert(0); return ""; #elif defined(_TD_DARWIN_64) static char cmdline[1024]; diff --git a/source/os/src/osSystem.c b/source/os/src/osSystem.c index 62c1747619..ba07b6c3dd 100644 --- a/source/os/src/osSystem.c +++ b/source/os/src/osSystem.c @@ -33,6 +33,7 @@ typedef struct FILE TdCmd; void* taosLoadDll(const char* filename) { #if defined(WINDOWS) + assert(0); return NULL; #elif defined(_TD_DARWIN_64) return NULL; @@ -51,6 +52,7 @@ void* taosLoadDll(const char* filename) { void* taosLoadSym(void* handle, char* name) { #if defined(WINDOWS) + assert(0); return NULL; #elif defined(_TD_DARWIN_64) return NULL; @@ -71,6 +73,7 @@ void* taosLoadSym(void* handle, char* name) { void taosCloseDll(void* handle) { #if defined(WINDOWS) + assert(0); return; #elif defined(_TD_DARWIN_64) return; @@ -121,6 +124,7 @@ int taosSetConsoleEcho(bool on) { void taosSetTerminalMode() { #if defined(WINDOWS) + // assert(0); #else struct termios newtio; @@ -154,7 +158,7 @@ void taosSetTerminalMode() { int32_t taosGetOldTerminalMode() { #if defined(WINDOWS) - + // assert(0); #else /* Make sure stdin is a terminal. */ if (!isatty(STDIN_FILENO)) { @@ -172,7 +176,7 @@ int32_t taosGetOldTerminalMode() { void taosResetTerminalMode() { #if defined(WINDOWS) - + // assert(0); #else if (tcsetattr(0, TCSANOW, &oldtio) != 0) { fprintf(stderr, "Fail to reset the terminal properties!\n"); diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index 8f48e0585e..11d7d9831a 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -640,13 +640,14 @@ int32_t cfgLoadFromEnvVar(SConfig *pConfig) { } int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd) { - char *buf, *name, *value, *value2, *value3; + char buf[1024], *name, *value, *value2, *value3; int32_t olen, vlen, vlen2, vlen3; int32_t index = 0; if (envCmd == NULL) return 0; while (envCmd[index]!=NULL) { - buf = taosMemoryMalloc(strlen(envCmd[index])); - taosEnvToCfg(envCmd[index], buf); + strncpy(buf, envCmd[index], sizeof(buf)-1); + buf[sizeof(buf)-1] = 0; + taosEnvToCfg(buf, buf); index++; name = value = value2 = value3 = NULL; @@ -671,8 +672,6 @@ int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd) { if (value2 != NULL && value3 != NULL && value2[0] != 0 && value3[0] != 0 && strcasecmp(name, "dataDir") == 0) { cfgSetTfsItem(pConfig, name, value, value2, value3, CFG_STYPE_ENV_CMD); } - - taosMemoryFree(buf); } uInfo("load from env cmd cfg success"); diff --git a/tests/parallel_test/collect_cases.sh b/tests/parallel_test/collect_cases.sh new file mode 100755 index 0000000000..c560598c81 --- /dev/null +++ b/tests/parallel_test/collect_cases.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +case_file=/tmp/cases.task + +function usage() { + echo "$0" + echo -e "\t -o output case file" + echo -e "\t -e enterprise edition" + echo -e "\t -h help" +} + +ent=0 +while getopts "o:eh" opt; do + case $opt in + o) + case_file=$OPTARG + ;; + e) + ent=1 + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done + +script_dir=`dirname $0` +cd $script_dir + +if [ $ent -eq 0 ]; then + echo ",,unit-test,bash test.sh" >$case_file +else + echo ",,unit-test,bash test.sh -e" >$case_file +fi +cat ../script/jenkins/basic.txt |grep -v "^#"|grep -v "^$"|sed "s/^/,,script,/" >>$case_file +grep "^python" ../system-test/fulltest.sh |sed "s/^/,,system-test,/" >>$case_file + +exit 0 + diff --git a/tests/parallel_test/container_build.sh b/tests/parallel_test/container_build.sh new file mode 100755 index 0000000000..3f23cd8b5f --- /dev/null +++ b/tests/parallel_test/container_build.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +function usage() { + echo "$0" + echo -e "\t -w work dir" + echo -e "\t -e enterprise edition" + echo -e "\t -t make thread count" + echo -e "\t -h help" +} + +ent=0 +while getopts "w:t:eh" opt; do + case $opt in + w) + WORKDIR=$OPTARG + ;; + e) + ent=1 + ;; + t) + THREAD_COUNT=$OPTARG + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done + +if [ -z "$WORKDIR" ]; then + usage + exit 1 +fi +if [ -z "$THREAD_COUNT" ]; then + THREAD_COUNT=1 +fi + +ulimit -c unlimited + +if [ $ent -eq 0 ]; then + REP_DIR=/home/TDengine + REP_MOUNT_PARAM=$WORKDIR/TDengine:/home/TDengine +else + REP_DIR=/home/TDinternal + REP_MOUNT_PARAM=$WORKDIR/TDinternal:/home/TDinternal +fi + +docker run \ + -v $REP_MOUNT_PARAM \ + --rm --ulimit core=-1 taos_test:v1.0 sh -c "cd $REP_DIR;rm -rf debug;mkdir -p debug;cd debug;cmake .. -DBUILD_TOOLS=true;make -j $THREAD_COUNT" + +ret=$? +exit $ret + diff --git a/tests/parallel_test/run.sh b/tests/parallel_test/run.sh new file mode 100755 index 0000000000..6417f41fd4 --- /dev/null +++ b/tests/parallel_test/run.sh @@ -0,0 +1,357 @@ +#!/bin/bash + +function usage() { + echo "$0" + echo -e "\t -m vm config file" + echo -e "\t -t task file" + echo -e "\t -b branch" + echo -e "\t -l log dir" + echo -e "\t -e enterprise edition" + echo -e "\t -o default timeout value" + echo -e "\t -h help" +} + +ent=0 +while getopts "m:t:b:l:o:eh" opt; do + case $opt in + m) + config_file=$OPTARG + ;; + t) + t_file=$OPTARG + ;; + b) + branch=$OPTARG + ;; + l) + log_dir=$OPTARG + ;; + e) + ent=1 + ;; + o) + timeout_param="-o $OPTARG" + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done +#config_file=$1 +if [ -z $config_file ]; then + usage + exit 1 +fi +if [ ! -f $config_file ]; then + echo "$config_file not found" + usage + exit 1 +fi +#t_file=$2 +if [ -z $t_file ]; then + usage + exit 1 +fi +if [ ! -f $t_file ]; then + echo "$t_file not found" + usage + exit 1 +fi +date_tag=`date +%Y%m%d-%H%M%S` +if [ -z $log_dir ]; then + log_dir="log/${branch}_${date_tag}" +else + log_dir="$log_dir/${branch}_${date_tag}" +fi + +hosts=() +usernames=() +passwords=() +workdirs=() +threads=() + +i=0 +while [ 1 ]; do + host=`jq .[$i].host $config_file` + if [ "$host" = "null" ]; then + break + fi + username=`jq .[$i].username $config_file` + if [ "$username" = "null" ]; then + break + fi + password=`jq .[$i].password $config_file` + if [ "$password" = "null" ]; then + password="" + fi + workdir=`jq .[$i].workdir $config_file` + if [ "$workdir" = "null" ]; then + break + fi + thread=`jq .[$i].thread $config_file` + if [ "$thread" = "null" ]; then + break + fi + hosts[i]=`echo $host|sed 's/\"$//'|sed 's/^\"//'` + usernames[i]=`echo $username|sed 's/\"$//'|sed 's/^\"//'` + passwords[i]=`echo $password|sed 's/\"$//'|sed 's/^\"//'` + workdirs[i]=`echo $workdir|sed 's/\"$//'|sed 's/^\"//'` + threads[i]=$thread + i=$(( i + 1 )) +done + + +function prepare_cases() { + cat $t_file >>$task_file + local i=0 + while [ $i -lt $1 ]; do + echo "%%FINISHED%%" >>$task_file + i=$(( i + 1 )) + done +} + +function clean_tmp() { + # clean tmp dir + local index=$1 + local ssh_script="sshpass -p ${passwords[index]} ssh -o StrictHostKeyChecking=no ${usernames[index]}@${hosts[index]}" + if [ -z ${passwords[index]} ]; then + ssh_script="ssh -o StrictHostKeyChecking=no ${usernames[index]}@${hosts[index]}" + fi + local cmd="${ssh_script} rm -rf ${workdirs[index]}/tmp" + ${cmd} +} + +function run_thread() { + local index=$1 + local thread_no=$2 + local runcase_script="sshpass -p ${passwords[index]} ssh -o StrictHostKeyChecking=no ${usernames[index]}@${hosts[index]}" + if [ -z ${passwords[index]} ]; then + runcase_script="ssh -o StrictHostKeyChecking=no ${usernames[index]}@${hosts[index]}" + fi + local count=0 + local script="${workdirs[index]}/TDengine/tests/parallel_test/run_container.sh" + if [ $ent -ne 0 ]; then + local script="${workdirs[index]}/TDinternal/community/tests/parallel_test/run_container.sh -e" + fi + local cmd="${runcase_script} ${script}" + + # script="echo" + while [ 1 ]; do + local line=`flock -x $lock_file -c "head -n1 $task_file;sed -i \"1d\" $task_file"` + if [ "x$line" = "x%%FINISHED%%" ]; then + # echo "$index . $thread_no EXIT" + break + fi + if [ -z "$line" ]; then + continue + fi + echo "$line"|grep -q "^#" + if [ $? -eq 0 ]; then + continue + fi + local case_redo_time=`echo "$line"|cut -d, -f2` + if [ -z "$case_redo_time" ]; then + case_redo_time=${DEFAULT_RETRY_TIME:-2} + fi + local exec_dir=`echo "$line"|cut -d, -f3` + local case_cmd=`echo "$line"|cut -d, -f4` + local case_file="" + echo "$case_cmd"|grep -q "\.sh" + if [ $? -eq 0 ]; then + case_file=`echo "$case_cmd"|grep -o ".*\.sh"|awk '{print $NF}'` + fi + echo "$case_cmd"|grep -q "^python3" + if [ $? -eq 0 ]; then + case_file=`echo "$case_cmd"|grep -o ".*\.py"|awk '{print $NF}'` + fi + echo "$case_cmd"|grep -q "\.sim" + if [ $? -eq 0 ]; then + case_file=`echo "$case_cmd"|grep -o ".*\.sim"|awk '{print $NF}'` + fi + if [ -z "$case_file" ]; then + case_file=`echo "$case_cmd"|awk '{print $NF}'` + fi + if [ -z "$case_file" ]; then + continue + fi + case_file="$exec_dir/${case_file}.${index}.${thread_no}.${count}" + count=$(( count + 1 )) + local case_path=`dirname "$case_file"` + if [ ! -z "$case_path" ]; then + mkdir -p $log_dir/$case_path + fi + cmd="${runcase_script} ${script} -w ${workdirs[index]} -c \"${case_cmd}\" -t ${thread_no} -d ${exec_dir} ${timeout_param}" + # echo "$thread_no $count $cmd" + local ret=0 + local redo_count=1 + start_time=`date +%s` + while [ ${redo_count} -lt 6 ]; do + if [ -f $log_dir/$case_file.log ]; then + cp $log_dir/$case_file.log $log_dir/$case_file.${redo_count}.redolog + fi + echo "${hosts[index]}-${thread_no} order:${count}, redo:${redo_count} task:${line}" >$log_dir/$case_file.log + echo -e "\e[33m >>>>> \e[0m ${case_cmd}" + date >>$log_dir/$case_file.log + # $cmd 2>&1 | tee -a $log_dir/$case_file.log + # ret=${PIPESTATUS[0]} + $cmd >>$log_dir/$case_file.log 2>&1 + ret=$? + echo "${hosts[index]} `date` ret:${ret}" >>$log_dir/$case_file.log + if [ $ret -eq 0 ]; then + break + fi + redo=0 + grep -q "wait too long for taosd start" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + grep -q "kex_exchange_identification: Connection closed by remote host" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + grep -q "ssh_exchange_identification: Connection closed by remote host" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + grep -q "kex_exchange_identification: read: Connection reset by peer" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + grep -q "Database not ready" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + grep -q "Unable to establish connection" $log_dir/$case_file.log + if [ $? -eq 0 ]; then + redo=1 + fi + if [ $redo_count -lt $case_redo_time ]; then + redo=1 + fi + if [ $redo -eq 0 ]; then + break + fi + redo_count=$(( redo_count + 1 )) + done + end_time=`date +%s` + echo >>$log_dir/$case_file.log + echo "${hosts[index]} execute time: $(( end_time - start_time ))s" >>$log_dir/$case_file.log + # echo "$thread_no ${line} DONE" + if [ $ret -ne 0 ]; then + flock -x $lock_file -c "echo \"${hosts[index]} ret:${ret} ${line}\" >>$log_dir/failed.log" + mkdir -p $log_dir/${case_file}.coredump + local remote_coredump_dir="${workdirs[index]}/tmp/thread_volume/$thread_no/coredump" + local scpcmd="sshpass -p ${passwords[index]} scp -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" + if [ -z ${passwords[index]} ]; then + scpcmd="scp -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" + fi + cmd="$scpcmd:${remote_coredump_dir}/* $log_dir/${case_file}.coredump/" + $cmd # 2>/dev/null + local case_info=`echo "$line"|cut -d, -f 3,4` + local corefile=`ls $log_dir/${case_file}.coredump/` + corefile=`find $log_dir/${case_file}.coredump/ -name "core.*"` + echo -e "$case_info \e[31m failed\e[0m" + echo "=========================log============================" + cat $log_dir/$case_file.log + echo "=====================================================" + echo -e "\e[34m log file: $log_dir/$case_file.log \e[0m" + if [ ! -z "$corefile" ]; then + echo -e "\e[34m corefiles: $corefile \e[0m" + local build_dir=$log_dir/build_${hosts[index]} + local remote_build_dir="${workdirs[index]}/TDengine/debug/build" + if [ $ent -ne 0 ]; then + remote_build_dir="${workdirs[index]}/TDinternal/debug/build" + fi + mkdir $build_dir 2>/dev/null + if [ $? -eq 0 ]; then + # scp build binary + cmd="$scpcmd:${remote_build_dir}/* ${build_dir}/" + echo "$cmd" + $cmd >/dev/null + fi + fi + # get remote sim dir + local remote_sim_dir="${workdirs[index]}/tmp/thread_volume/$thread_no" + local tarcmd="sshpass -p ${passwords[index]} ssh -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" + if [ -z ${passwords[index]} ]; then + tarcmd="ssh -o StrictHostKeyChecking=no ${usernames[index]}@${hosts[index]}" + fi + cmd="$tarcmd sh -c \"cd $remote_sim_dir; tar -czf sim.tar.gz sim\"" + $cmd + local remote_sim_tar="${workdirs[index]}/tmp/thread_volume/$thread_no/sim.tar.gz" + scpcmd="sshpass -p ${passwords[index]} scp -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" + if [ -z ${passwords[index]} ]; then + scpcmd="scp -o StrictHostKeyChecking=no -r ${usernames[index]}@${hosts[index]}" + fi + cmd="$scpcmd:${remote_sim_tar} $log_dir/${case_file}.sim.tar.gz" + $cmd + fi + done +} + +# echo "hosts: ${hosts[@]}" +# echo "usernames: ${usernames[@]}" +# echo "passwords: ${passwords[@]}" +# echo "workdirs: ${workdirs[@]}" +# echo "threads: ${threads[@]}" +# TODO: check host accessibility + +i=0 +while [ $i -lt ${#hosts[*]} ]; do + clean_tmp $i & + i=$(( i + 1 )) +done +wait + +mkdir -p $log_dir +rm -rf $log_dir/* +task_file=$log_dir/$$.task +lock_file=$log_dir/$$.lock + +i=0 +j=0 +while [ $i -lt ${#hosts[*]} ]; do + j=$(( j + threads[i] )) + i=$(( i + 1 )) +done +prepare_cases $j + +i=0 +while [ $i -lt ${#hosts[*]} ]; do + j=0 + while [ $j -lt ${threads[i]} ]; do + run_thread $i $j & + j=$(( j + 1 )) + done + i=$(( i + 1 )) +done + +wait + +rm -f $lock_file +rm -f $task_file + +# docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker rm -f +RET=0 +i=1 +if [ -f "$log_dir/failed.log" ]; then + echo "=====================================================" + while read line; do + line=`echo "$line"|cut -d, -f 3,4` + echo -e "$i. $line \e[31m failed\e[0m" >&2 + i=$(( i + 1 )) + done <$log_dir/failed.log + RET=1 +fi + +echo "${log_dir}" >&2 + +date + +exit $RET diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh new file mode 100755 index 0000000000..9705c024b8 --- /dev/null +++ b/tests/parallel_test/run_case.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +function usage() { + echo "$0" + echo -e "\t -d execution dir" + echo -e "\t -c command" + echo -e "\t -e enterprise edition" + echo -e "\t -o default timeout value" + echo -e "\t -h help" +} + +ent=0 +while getopts "d:c:o:eh" opt; do + case $opt in + d) + exec_dir=$OPTARG + ;; + c) + cmd=$OPTARG + ;; + o) + TIMEOUT_CMD="timeout $OPTARG" + ;; + e) + ent=1 + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done + +if [ -z "$exec_dir" ]; then + usage + exit 0 +fi +if [ -z "$cmd" ]; then + usage + exit 0 +fi + +if [ $ent -eq 0 ]; then + export PATH=$PATH:/home/TDengine/debug/build/bin + export LD_LIBRARY_PATH=/home/TDengine/debug/build/lib + ln -s /home/TDengine/debug/build/lib/libtaos.so /usr/lib/libtaos.so 2>/dev/null + CONTAINER_TESTDIR=/home/TDengine +else + export PATH=$PATH:/home/TDinternal/debug/build/bin + export LD_LIBRARY_PATH=/home/TDinternal/debug/build/lib + ln -s /home/TDinternal/debug/build/lib/libtaos.so /usr/lib/libtaos.so 2>/dev/null + CONTAINER_TESTDIR=/home/TDinternal/community +fi +mkdir -p /var/lib/taos/subscribe +mkdir -p /var/log/taos +mkdir -p /var/lib/taos + +cd $CONTAINER_TESTDIR/tests/$exec_dir +ulimit -c unlimited + +$TIMEOUT_CMD $cmd +RET=$? + +if [ $RET -ne 0 ]; then + pwd +fi + +exit $RET + diff --git a/tests/parallel_test/run_container.sh b/tests/parallel_test/run_container.sh new file mode 100755 index 0000000000..affd9128a4 --- /dev/null +++ b/tests/parallel_test/run_container.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +function usage() { + echo "$0" + echo -e "\t -w work dir" + echo -e "\t -d execution dir" + echo -e "\t -c command" + echo -e "\t -t thread number" + echo -e "\t -e enterprise edition" + echo -e "\t -o default timeout value" + echo -e "\t -h help" +} + +ent=0 +while getopts "w:d:c:t:o:eh" opt; do + case $opt in + w) + WORKDIR=$OPTARG + ;; + d) + exec_dir=$OPTARG + ;; + c) + cmd=$OPTARG + ;; + t) + thread_no=$OPTARG + ;; + e) + ent=1 + ;; + o) + extra_param="-o $OPTARG" + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done + +if [ -z "$WORKDIR" ]; then + usage + exit 1 +fi +if [ -z "$exec_dir" ]; then + usage + exit 1 +fi +if [ -z "$cmd" ]; then + usage + exit 1 +fi +if [ -z "$thread_no" ]; then + usage + exit 1 +fi +if [ $ent -ne 0 ]; then + # enterprise edition + extra_param="$extra_param -e" + INTERNAL_REPDIR=$WORKDIR/TDinternal + REPDIR=$INTERNAL_REPDIR/community + CONTAINER_TESTDIR=/home/TDinternal/community + SIM_DIR=/home/TDinternal/sim + REP_MOUNT_PARAM="$INTERNAL_REPDIR:/home/TDinternal" +else + # community edition + REPDIR=$WORKDIR/TDengine + CONTAINER_TESTDIR=/home/TDengine + SIM_DIR=/home/TDengine/sim + REP_MOUNT_PARAM="$REPDIR:/home/TDengine" +fi + +ulimit -c unlimited + +TMP_DIR=$WORKDIR/tmp + +MOUNT_DIR="" +rm -rf ${TMP_DIR}/thread_volume/$thread_no/sim +mkdir -p ${TMP_DIR}/thread_volume/$thread_no/sim/tsim +mkdir -p ${TMP_DIR}/thread_volume/$thread_no/coredump +rm -rf ${TMP_DIR}/thread_volume/$thread_no/coredump/* +if [ ! -d "${TMP_DIR}/thread_volume/$thread_no/$exec_dir" ]; then + subdir=`echo "$exec_dir"|cut -d/ -f1` + echo "cp -rf ${REPDIR}/tests/$subdir ${TMP_DIR}/thread_volume/$thread_no/" + cp -rf ${REPDIR}/tests/$subdir ${TMP_DIR}/thread_volume/$thread_no/ +fi +MOUNT_DIR="$TMP_DIR/thread_volume/$thread_no/$exec_dir:$CONTAINER_TESTDIR/tests/$exec_dir" +echo "$thread_no -> ${exec_dir}:$cmd" +coredump_dir=`cat /proc/sys/kernel/core_pattern | xargs dirname` + +docker run \ + -v $REP_MOUNT_PARAM \ + -v $MOUNT_DIR \ + -v "$TMP_DIR/thread_volume/$thread_no/sim:${SIM_DIR}" \ + -v ${TMP_DIR}/thread_volume/$thread_no/coredump:$coredump_dir \ + -v $WORKDIR/taos-connector-python/taos:/usr/local/lib/python3.8/site-packages/taos:ro \ + --rm --ulimit core=-1 taos_test:v1.0 $CONTAINER_TESTDIR/tests/parallel_test/run_case.sh -d "$exec_dir" -c "$cmd" $extra_param +ret=$? +exit $ret + diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index 9dcd485194..c78efb4e8d 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -30,17 +30,12 @@ class TDSimClient: "locale": "en_US.UTF-8", "charset": "UTF-8", "asyncLog": "0", - "minTablesPerVnode": "4", - "maxTablesPerVnode": "1000", - "tableIncStepPerVnode": "10000", - "maxVgroupsPerDb": "1000", - "sdbDebugFlag": "143", - "rpcDebugFlag": "135", + "rpcDebugFlag": "143", "tmrDebugFlag": "131", - "cDebugFlag": "135", - "udebugFlag": "135", - "jnidebugFlag": "135", - "qdebugFlag": "135", + "cDebugFlag": "143", + "udebugFlag": "143", + "jnidebugFlag": "143", + "qdebugFlag": "143", "telemetryReporting": "0", } @@ -115,36 +110,29 @@ class TDDnode: self.testCluster = False self.valgrind = 0 self.cfgDict = { - "numOfLogLines": "100000000", - "mnodeEqualVnodeNum": "0", "walLevel": "2", "fsync": "1000", - "statusInterval": "1", - "numOfMnodes": "3", - "numOfThreadsPerCore": "2.0", "monitor": "0", - "maxVnodeConnections": "30000", - "maxMgmtConnections": "30000", - "maxMeterConnections": "30000", "maxShellConns": "30000", "locale": "en_US.UTF-8", "charset": "UTF-8", "asyncLog": "0", - "anyIp": "0", - "telemetryReporting": "0", - "dDebugFlag": "135", - "tsdbDebugFlag": "135", - "mDebugFlag": "135", - "sdbDebugFlag": "135", - "rpcDebugFlag": "135", + "mDebugFlag": "143", + "dDebugFlag": "143", + "vDebugFlag": "143", + "tqDebugFlag": "143", + "cDebugFlag": "143", + "jniDebugFlag": "143", + "qDebugFlag": "143", + "rpcDebugFlag": "143", "tmrDebugFlag": "131", - "cDebugFlag": "135", - "httpDebugFlag": "135", - "monitorDebugFlag": "135", - "udebugFlag": "135", - "jnidebugFlag": "135", - "qdebugFlag": "135", - "maxSQLLength": "1048576" + "uDebugFlag": "143", + "sDebugFlag": "135", + "wDebugFlag": "143", + "qdebugFlag": "143", + "numOfLogLines": "100000000", + "statusInterval": "1", + "telemetryReporting": "0" } def init(self, path): diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c index ae07b3fc8e..cb914f8d6d 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -9,10 +9,12 @@ #include #include "../../../include/client/taos.h" +#define FUNCTION_TEST_IDX 1 + int32_t shortColList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_INT}; int32_t fullColList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_BOOL, TSDB_DATA_TYPE_TINYINT, TSDB_DATA_TYPE_UTINYINT, TSDB_DATA_TYPE_SMALLINT, TSDB_DATA_TYPE_USMALLINT, TSDB_DATA_TYPE_INT, TSDB_DATA_TYPE_UINT, TSDB_DATA_TYPE_BIGINT, TSDB_DATA_TYPE_UBIGINT, TSDB_DATA_TYPE_FLOAT, TSDB_DATA_TYPE_DOUBLE, TSDB_DATA_TYPE_BINARY, TSDB_DATA_TYPE_NCHAR}; -int32_t bindColTypeList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_NCHAR}; -int32_t optrIdxList[] = {0, 9}; +int32_t bindColTypeList[] = {TSDB_DATA_TYPE_TIMESTAMP, TSDB_DATA_TYPE_INT}; +int32_t optrIdxList[] = {0, 7}; typedef struct { char* oper; @@ -53,7 +55,6 @@ FuncInfo funcInfo[] = { {"count", 1}, {"sum", 1}, {"min", 1}, - {"sin", 1}, }; char *bpStbPrefix = "st"; @@ -66,6 +67,10 @@ int32_t bpDefaultStbId = 1; //char *varoperatorList[] = {">", ">=", "<", "<=", "=", "<>", "in", "not in", "like", "not like", "match", "nmatch"}; #define tListLen(x) (sizeof(x) / sizeof((x)[0])) +#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT) +#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT) +#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE) +#define IS_NUMERIC_TYPE(_t) ((IS_SIGNED_NUMERIC_TYPE(_t)) || (IS_UNSIGNED_NUMERIC_TYPE(_t)) || (IS_FLOAT_TYPE(_t))) typedef struct { int64_t* tsData; @@ -165,8 +170,11 @@ CaseCfg gCase[] = { // 22 {"insert:AUTO1-FULL", tListLen(fullColList), fullColList, TTYPE_INSERT, true, true, insertAUTOTest1, 10, 10, 2, 0, 0, 0, 1, -1}, - {"query:SUBT-COLUMN", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryColumnTest, 10, 10, 1, 3, 0, 0, 1, 2}, - {"query:SUBT-MISC", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryMiscTest, 2, 10, 1, 3, 0, 0, 1, 2}, +// {"query:SUBT-COLUMN", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryColumnTest, 10, 10, 1, 3, 0, 0, 1, 2}, +// {"query:SUBT-MISC", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryMiscTest, 10, 10, 1, 3, 0, 0, 1, 2}, + + {"query:SUBT-COLUMN", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryColumnTest, 1, 10, 1, 1, 0, 0, 1, 2}, + {"query:SUBT-MISC", tListLen(fullColList), fullColList, TTYPE_QUERY, false, false, queryMiscTest, 2, 10, 1, 1, 0, 0, 1, 2}, }; @@ -181,6 +189,7 @@ typedef struct { bool printQuerySql; bool printStmtSql; bool autoCreateTbl; + bool numericParam; int32_t rowNum; //row num for one table int32_t bindColNum; int32_t bindTagNum; @@ -207,6 +216,7 @@ CaseCtrl gCaseCtrl = { // default .printQuerySql = true, .printStmtSql = true, .autoCreateTbl = false, + .numericParam = false, .rowNum = 0, .bindColNum = 0, .bindTagNum = 0, @@ -259,26 +269,22 @@ CaseCtrl gCaseCtrl = { #if 1 CaseCtrl gCaseCtrl = { // query case with specified col&oper - .bindNullNum = 0, + .bindNullNum = 1, .printCreateTblSql = false, .printQuerySql = true, .printStmtSql = true, .rowNum = 0, .bindColNum = 0, .bindRowNum = 0, - .bindColTypeNum = 0, - .bindColTypeList = NULL, - .optrIdxListNum = 0, - .optrIdxList = NULL, + .optrIdxListNum = tListLen(optrIdxList), + .optrIdxList = optrIdxList, + .bindColTypeNum = tListLen(bindColTypeList), + .bindColTypeList = bindColTypeList, .checkParamNum = false, .printRes = true, .runTimes = 0, .caseRunIdx = -1, - .optrIdxListNum = 0, - .optrIdxList = NULL, - .bindColTypeNum = 0, - .bindColTypeList = NULL, - .caseIdx = 24, + .caseIdx = 23, .caseNum = 1, .caseRunNum = 1, }; @@ -303,11 +309,11 @@ CaseCtrl gCaseCtrl = { // query case with specified col&oper .printRes = true, .runTimes = 0, .caseRunIdx = -1, - //.optrIdxListNum = tListLen(optrIdxList), - //.optrIdxList = optrIdxList, - //.bindColTypeNum = tListLen(bindColTypeList), - //.bindColTypeList = bindColTypeList, - .caseIdx = 22, + .optrIdxListNum = tListLen(optrIdxList), + .optrIdxList = optrIdxList, + .bindColTypeNum = tListLen(bindColTypeList), + .bindColTypeList = bindColTypeList, + .caseIdx = 24, .caseNum = 1, .caseRunNum = 1, }; @@ -661,11 +667,11 @@ void bpGenerateConstInFuncSQL(BindData *data, int32_t tblIdx) { void generateQueryMiscSQL(BindData *data, int32_t tblIdx) { switch(tblIdx) { case 0: - bpGenerateConstInOpSQL(data, tblIdx); - break; - case 1: //TODO FILL TEST default: + bpGenerateConstInOpSQL(data, tblIdx); + break; + case FUNCTION_TEST_IDX: bpGenerateConstInFuncSQL(data, tblIdx); break; } @@ -709,6 +715,16 @@ void generateColDataType(BindData *data, int32_t bindIdx, int32_t colIdx, int32_ } else if (gCurCase->fullCol) { *dataType = gCurCase->colList[bindIdx]; return; + } else if (gCaseCtrl.numericParam) { + while (true) { + *dataType = rand() % (TSDB_DATA_TYPE_MAX - 1) + 1; + if (!IS_NUMERIC_TYPE(*dataType)) { + continue; + } + + break; + } + return; } else if (0 == colIdx) { *dataType = TSDB_DATA_TYPE_TIMESTAMP; return; @@ -1046,6 +1062,10 @@ int32_t prepareQueryMiscData(BindData *data, int32_t tblIdx) { data->binaryLen[i] = gVarCharLen; } + if (tblIdx == FUNCTION_TEST_IDX) { + gCaseCtrl.numericParam = true; + } + for (int b = 0; b < bindNum; b++) { for (int c = 0; c < gCurCase->bindColNum; ++c) { prepareColData(BP_BIND_COL, data, b*gCurCase->bindColNum+c, b*gCurCase->bindRowNum, c); diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 8420b91065..f6bc9f8306 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -63,6 +63,7 @@ # ---- tstream ./test.sh -f tsim/tstream/basic0.sim +./test.sh -f tsim/tstream/basic1.sim # ---- transaction ./test.sh -f tsim/trans/create_db.sim diff --git a/tests/script/tsim/query/udf.sim b/tests/script/tsim/query/udf.sim index 6290403214..b02ca79ed4 100644 --- a/tests/script/tsim/query/udf.sim +++ b/tests/script/tsim/query/udf.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c wallevel -v 2 system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode1 -c startUdfd -v 1 +system sh/cfg.sh -n dnode1 -c udf -v 1 print ========= start dnode1 as LEADER system sh/exec.sh -n dnode1 -s start @@ -94,6 +94,44 @@ endi if $data00 != 2.645751311 then return -1 endi + +sql insert into t2 values(now+4s, 4, 8)(now+5s, 5, 9); +sql select udf2(f1-f2), udf2(f1+f2) from t2; +print $rows , $data00 , $data01 +if $rows != 1 then + return -1; +endi +if $data00 != 5.656854249 then + return -1 +endi +if $data01 != 18.547236991 then + return -1 +endi + +sql select udf2(udf1(f2-f1)), udf2(udf1(f2/f1)) from t2; +print $rows , $data00 , $data01 +if $rows != 1 then + return -1 +endi +if $data00 != 176.000000000 then + return -1 +endi +if $data01 != 152.420471066 then + return -1 +endi + +sql select udf2(f2) from udf.t2 group by 1-udf1(f1); +print $rows , $data00 , $data10 +if $rows != 2 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi +if $data10 != 12.083045974 then + return -1 +endi + sql drop function udf1; sql show functions; if $rows != 1 then diff --git a/tests/script/tsim/tstream/basic1.sim b/tests/script/tsim/tstream/basic1.sim new file mode 100644 index 0000000000..3bb5943b3b --- /dev/null +++ b/tests/script/tsim/tstream/basic1.sim @@ -0,0 +1,375 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print =============== create database +sql create database test vgroups 1 +sql show databases +if $rows != 3 then + return -1 +endi + +print $data00 $data01 $data02 + +sql use test + + +sql create table t1(ts timestamp, a int, b int , c int, d double); +sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s); +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t1 values(1648791223001,2,2,3,1.1); +sql insert into t1 values(1648791233002,3,2,3,2.1); +sql insert into t1 values(1648791243003,4,2,3,3.1); +sql insert into t1 values(1648791213004,4,2,3,4.1); +sleep 1000 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +if $rows != 4 then + print ======$rows + return -1 +endi + +# row 0 +if $data01 != 2 then + print ======$data01 + return -1 +endi + +if $data02 != 2 then + print ======$data02 + return -1 +endi + +if $data03 != 5 then + print ======$data03 + return -1 +endi + +if $data04 != 2 then + print ======$data04 + return -1 +endi + +if $data05 != 3 then + print ======$data05 + return -1 +endi + +# row 1 +if $data11 != 1 then + print ======$data11 + return -1 +endi + +if $data12 != 1 then + print ======$data12 + return -1 +endi + +if $data13 != 2 then + print ======$data13 + return -1 +endi + +if $data14 != 2 then + print ======$data14 + return -1 +endi + +if $data15 != 3 then + print ======$data15 + return -1 +endi + +# row 2 +if $data21 != 1 then + print ======$data21 + return -1 +endi + +if $data22 != 1 then + print ======$data22 + return -1 +endi + +if $data23 != 3 then + print ======$data23 + return -1 +endi + +if $data24 != 2 then + print ======$data24 + return -1 +endi + +if $data25 != 3 then + print ======$data25 + return -1 +endi + +# row 3 +if $data31 != 1 then + print ======$data31 + return -1 +endi + +if $data32 != 1 then + print ======$data32 + return -1 +endi + +if $data33 != 4 then + print ======$data33 + return -1 +endi + +if $data34 != 2 then + print ======$data34 + return -1 +endi + +if $data35 != 3 then + print ======$data35 + return -1 +endi + +sql insert into t1 values(1648791223001,12,14,13,11.1); +sleep 100 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +if $rows != 4 then + print ======$rows + return -1 +endi + +# row 0 +if $data01 != 2 then + print ======$data01 + return -1 +endi + +if $data02 != 2 then + print ======$data02 + return -1 +endi + +if $data03 != 5 then + print ======$data03 + return -1 +endi + +if $data04 != 2 then + print ======$data04 + return -1 +endi + +if $data05 != 3 then + print ======$data05 + return -1 +endi + +# row 1 +if $data11 != 1 then + print ======$data11 + return -1 +endi + +if $data12 != 1 then + print ======$data12 + return -1 +endi + +if $data13 != 12 then + print ======$data13 + return -1 +endi + +if $data14 != 14 then + print ======$data14 + return -1 +endi + +if $data15 != 13 then + print ======$data15 + return -1 +endi + +# row 2 +if $data21 != 1 then + print ======$data21 + return -1 +endi + +if $data22 != 1 then + print ======$data22 + return -1 +endi + +if $data23 != 3 then + print ======$data23 + return -1 +endi + +if $data24 != 2 then + print ======$data24 + return -1 +endi + +if $data25 != 3 then + print ======$data25 + return -1 +endi + +# row 3 +if $data31 != 1 then + print ======$data31 + return -1 +endi + +if $data32 != 1 then + print ======$data32 + return -1 +endi + +if $data33 != 4 then + print ======$data33 + return -1 +endi + +if $data34 != 2 then + print ======$data34 + return -1 +endi + +if $data35 != 3 then + print ======$data35 + return -1 +endi + +sql insert into t1 values(1648791223002,12,14,13,11.1); +sleep 100 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +# row 1 +if $data11 != 2 then + print ======$data11 + return -1 +endi + +if $data12 != 2 then + print ======$data12 + return -1 +endi + +if $data13 != 24 then + print ======$data13 + return -1 +endi + +if $data14 != 14 then + print ======$data14 + return -1 +endi + +if $data15 != 13 then + print ======$data15 + return -1 +endi + +sql insert into t1 values(1648791223003,12,14,13,11.1); +sleep 100 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +# row 1 +if $data11 != 3 then + print ======$data11 + return -1 +endi + +if $data12 != 3 then + print ======$data12 + return -1 +endi + +if $data13 != 36 then + print ======$data13 + return -1 +endi + +if $data14 != 14 then + print ======$data14 + return -1 +endi + +if $data15 != 13 then + print ======$data15 + return -1 +endi + +sql insert into t1 values(1648791223001,1,1,1,1.1); +sql insert into t1 values(1648791223002,2,2,2,2.1); +sql insert into t1 values(1648791223003,3,3,3,3.1); +sleep 100 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +# row 1 +if $data11 != 3 then + print ======$data11 + return -1 +endi + +if $data12 != 3 then + print ======$data12 + return -1 +endi + +if $data13 != 6 then + print ======$data13 + return -1 +endi + +if $data14 != 3 then + print ======$data14 + return -1 +endi + +if $data15 != 1 then + print ======$data15 + return -1 +endi + +sql insert into t1 values(1648791233003,3,2,3,2.1); +sql insert into t1 values(1648791233002,5,6,7,8.1); +sql insert into t1 values(1648791233002,3,2,3,2.1); +sleep 100 +sql select _wstartts, c1, c2 ,c3 ,c4, c5 from streamt; + +# row 2 +if $data21 != 2 then + print ======$data21 + return -1 +endi + +if $data22 != 2 then + print ======$data22 + return -1 +endi + +if $data23 != 6 then + print ======$data23 + return -1 +endi + +if $data24 != 2 then + print ======$data24 + return -1 +endi + +if $data25 != 3 then + print ======$data25 + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/system-test/0-others/taosShellNetChk.py b/tests/system-test/0-others/taosShellNetChk.py index 524268101a..bbaeacf328 100644 --- a/tests/system-test/0-others/taosShellNetChk.py +++ b/tests/system-test/0-others/taosShellNetChk.py @@ -138,7 +138,8 @@ class TDTestCase: if "2: service ok" in retVal: tdLog.info("taos -k success") else: - tdLog.exit("taos -k fail") + tdLog.info(retVal) + tdLog.exit("taos -k fail 1") # stop taosd tdDnodes.stop(1) @@ -149,7 +150,8 @@ class TDTestCase: if "0: unavailable" in retVal: tdLog.info("taos -k success") else: - tdLog.exit("taos -k fail") + tdLog.info(retVal) + tdLog.exit("taos -k fail 2") # restart taosd tdDnodes.start(1) @@ -158,7 +160,8 @@ class TDTestCase: if "2: service ok" in retVal: tdLog.info("taos -k success") else: - tdLog.exit("taos -k fail") + tdLog.info(retVal) + tdLog.exit("taos -k fail 3") tdLog.printNoPrefix("================================ parameter: -n") # stop taosd diff --git a/tests/system-test/0-others/user_control.py b/tests/system-test/0-others/user_control.py new file mode 100644 index 0000000000..78aefd5e9e --- /dev/null +++ b/tests/system-test/0-others/user_control.py @@ -0,0 +1,348 @@ +import taos +import sys +import inspect +import traceback + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + + +PRIVILEGES_ALL = "ALL" +PRIVILEGES_READ = "READ" +PRIVILEGES_WRITE = "WRITE" + +class TDconnect: + def __init__(self, + host = None, + port = None, + user = None, + password = None, + database = None, + config = None, + ) -> None: + self._conn = None + self._host = host + self._user = user + self._password = password + self._database = database + self._port = port + self._config = config + + def __enter__(self): + self._conn = taos.connect( + host =self._host, + port =self._port, + user =self._user, + password=self._password, + database=self._database, + config =self._config + ) + + self.cursor = self._conn.cursor() + return self + + def error(self, sql): + expectErrNotOccured = True + try: + self.cursor.execute(sql) + except BaseException: + expectErrNotOccured = False + + if expectErrNotOccured: + caller = inspect.getframeinfo(inspect.stack()[1][0]) + tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured" ) + else: + self.queryRows = 0 + self.queryCols = 0 + self.queryResult = None + tdLog.info(f"sql:{sql}, expect error occured") + + def query(self, sql, row_tag=None): + # sourcery skip: raise-from-previous-error, raise-specific-error + self.sql = sql + try: + self.cursor.execute(sql) + self.queryResult = self.cursor.fetchall() + self.queryRows = len(self.queryResult) + self.queryCols = len(self.cursor.description) + except Exception as e: + caller = inspect.getframeinfo(inspect.stack()[1][0]) + tdLog.notice(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, {repr(e)}") + traceback.print_exc() + raise Exception(repr(e)) + if row_tag: + return self.queryResult + return self.queryRows + + def __exit__(self, types, values, trace): + if self._conn: + self.cursor.close() + self._conn.close() + +def taos_connect( + host = "127.0.0.1", + port = 6030, + user = "root", + passwd = "taosdata", + database= None, + config = None +): + return TDconnect( + host = host, + port=port, + user=user, + password=passwd, + database=database, + config=config + ) + +class TDTestCase: + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + + @property + def __user_list(self): + return [f"user_test{i}" for i in range(self.users_count) ] + + @property + def __passwd_list(self): + return [f"taosdata{i}" for i in range(self.users_count) ] + + @property + def __privilege(self): + return [ PRIVILEGES_ALL, PRIVILEGES_READ, PRIVILEGES_WRITE ] + + def __priv_level(self, dbname=None): + return f"{dbname}.*" if dbname else "*.*" + + + def create_user_current(self): + users = self.__user_list + passwds = self.__passwd_list + for i in range(self.users_count): + tdSql.execute(f"create user {users[i]} pass '{passwds[i]}' ") + + tdSql.query("show users") + tdSql.checkRows(self.users_count + 1) + + def create_user_err(self): + sqls = [ + "create users u1 pass 'u1passwd' ", + "create user '' pass 'u1passwd' ", + "create user pass 'u1passwd' ", + "create user u1 pass u1passwd ", + "create user u1 password 'u1passwd' ", + "create user u1 pass u1passwd ", + "create user u1 pass '' ", + "create user u1 pass ' ' ", + "create user u1 pass ", + "create user u1 u2 pass 'u1passwd' 'u2passwd' ", + "create user u1 u2 pass 'u1passwd', 'u2passwd' ", + "create user u1, u2 pass 'u1passwd', 'u2passwd' ", + "create user u1, u2 pass 'u1passwd' 'u2passwd' ", + # length of user_name must <= 23 + "create user u12345678901234567890123 pass 'u1passwd' " , + # length of passwd must <= 128 + "create user u1 pass 'u12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678' " , + # password must have not " ' ~ ` \ + "create user u1 pass 'u1passwd\\' " , + "create user u1 pass 'u1passwd~' " , + "create user u1 pass 'u1passwd\"' " , + "create user u1 pass 'u1passwd\'' " , + "create user u1 pass 'u1passwd`' " , + # must after create a user named u1 + "create user u1 pass 'u1passwd' " , + ] + + tdSql.execute("create user u1 pass 'u1passwd' ") + for sql in sqls: + tdSql.error(sql) + + tdSql.execute("DROP USER u1") + + def __alter_pass_sql(self, user, passwd): + return f'''ALTER USER {user} PASS '{passwd}' ''' + + def alter_pass_current(self): + self.__init_pass = True + for count, i in enumerate(range(self.users_count)): + if self.__init_pass: + tdSql.query(self.__alter_pass_sql(self.__user_list[i], f"new{self.__passwd_list[i]}")) + self.__init_pass = count != self.users_count - 1 + else: + tdSql.query(self.__alter_pass_sql(self.__user_list[i], self.__passwd_list[i] ) ) + self.__init_pass = count == self.users_count - 1 + + def alter_pass_err(self): # sourcery skip: remove-redundant-fstring + sqls = [ + f"alter users {self.__user_list[0]} pass 'newpass' " , + f"alter user {self.__user_list[0]} pass '' " , + f"alter user {self.__user_list[0]} pass ' ' " , + f"alter user anyuser pass 'newpass' " , + f"alter user {self.__user_list[0]} pass " , + f"alter user {self.__user_list[0]} password 'newpass' " , + ] + for sql in sqls: + tdSql.error(sql) + + + def grant_user_privileges(self, privilege, dbname=None, user_name="root"): + return f"GRANT {privilege} ON {self.__priv_level(dbname)} TO {user_name} " + + def test_user_create(self): + self.create_user_current() + self.create_user_err() + + def test_alter_pass(self): + self.alter_pass_current() + self.alter_pass_err() + + def user_login(self, user, passwd): + login_except = False + try: + with taos_connect(user=user, passwd=passwd) as conn: + cursor = conn.cursor + except BaseException: + login_except = True + cursor = None + return login_except, cursor + + def login_currrent(self, user, passwd): + login_except, _ = self.user_login(user, passwd) + if login_except: + tdLog.exit(f"connect failed, user: {user} and pass: {passwd} do not match!") + else: + tdLog.info("connect successfully, user and pass matched!") + + + def login_err(self, user, passwd): + login_except, _ = self.user_login(user, passwd) + if login_except: + tdLog.info("connect failed, except error occured!") + else: + tdLog.exit("connect successfully, except error not occrued!") + + def __drop_user(self, user): + return f"DROP USER {user}" + + def drop_user_current(self): + for user in self.__user_list: + tdSql.query(self.__drop_user(user)) + + def drop_user_error(self): + sqls = [ + f"DROP {self.__user_list[0]}", + f"DROP user {self.__user_list[0]} {self.__user_list[1]}", + f"DROP user {self.__user_list[0]} , {self.__user_list[1]}", + f"DROP users {self.__user_list[0]} {self.__user_list[1]}", + f"DROP users {self.__user_list[0]} , {self.__user_list[1]}", + # "DROP user root", + "DROP user abcde", + "DROP user ALL", + ] + + for sql in sqls: + tdSql.error(sql) + + def test_drop_user(self): + # must drop err first + self.drop_user_error() + self.drop_user_current() + + def run(self): + + # 默认只有 root 用户 + tdLog.printNoPrefix("==========step0: init, user list only has root account") + tdSql.query("show users") + tdSql.checkData(0, 0, "root") + tdSql.checkData(0, 1, "super") + + # root用户权限 + # 创建用户测试 + tdLog.printNoPrefix("==========step1: create user test") + self.users_count = 5 + self.test_user_create() + + # 查看用户 + tdLog.printNoPrefix("==========step2: show user test") + tdSql.query("show users") + tdSql.checkRows(self.users_count + 1) + + # 密码登录认证 + self.login_currrent(self.__user_list[0], self.__passwd_list[0]) + self.login_err(self.__user_list[0], f"new{self.__passwd_list[0]}") + + # 修改密码 + tdLog.printNoPrefix("==========step3: alter user pass test") + self.test_alter_pass() + + # 密码修改后的登录认证 + tdLog.printNoPrefix("==========step4: check login test") + self.login_err(self.__user_list[0], self.__passwd_list[0]) + self.login_currrent(self.__user_list[0], f"new{self.__passwd_list[0]}") + + tdDnodes.stop(1) + tdDnodes.start(1) + + tdSql.query("show users") + tdSql.checkRows(self.users_count + 1) + + # 普通用户权限 + # 密码登录 + # _, user = self.user_login(self.__user_list[0], f"new{self.__passwd_list[0]}") + with taos_connect(user=self.__user_list[0], passwd=f"new{self.__passwd_list[0]}") as user: + # user = conn + # 不能创建用户 + tdLog.printNoPrefix("==========step5: normal user can not create user") + user.error("create use utest1 pass 'utest1pass'") + # 可以查看用户 + tdLog.printNoPrefix("==========step6: normal user can show user") + user.query("show users") + assert user.queryRows == self.users_count + 1 + # 不可以修改其他用户的密码 + tdLog.printNoPrefix("==========step7: normal user can not alter other user pass") + user.error(self.__alter_pass_sql(self.__user_list[1], self.__passwd_list[1] )) + user.error(self.__alter_pass_sql("root", "taosdata_root" )) + # 可以修改自己的密码 + tdLog.printNoPrefix("==========step8: normal user can alter owner pass") + user.query(self.__alter_pass_sql(self.__user_list[0], self.__passwd_list[0])) + # 不可以删除用户,包括自己 + tdLog.printNoPrefix("==========step9: normal user can not drop any user ") + user.error(f"drop user {self.__user_list[0]}") + user.error(f"drop user {self.__user_list[1]}") + user.error("drop user root") + + # root删除用户测试 + tdLog.printNoPrefix("==========step10: super user drop normal user") + self.test_drop_user() + + tdSql.query("show users") + tdSql.checkRows(1) + tdSql.checkData(0, 0, "root") + tdSql.checkData(0, 1, "super") + + tdDnodes.stop(1) + tdDnodes.start(1) + + # 删除后无法登录 + self.login_err(self.__user_list[0], self.__passwd_list[0]) + self.login_err(self.__user_list[0], f"new{self.__passwd_list[0]}") + self.login_err(self.__user_list[1], self.__passwd_list[1]) + self.login_err(self.__user_list[1], f"new{self.__passwd_list[1]}") + + tdSql.query("show users") + tdSql.checkRows(1) + tdSql.checkData(0, 0, "root") + tdSql.checkData(0, 1, "super") + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/between.py b/tests/system-test/2-query/between.py index e8bde3c11c..3b9465dd26 100644 --- a/tests/system-test/2-query/between.py +++ b/tests/system-test/2-query/between.py @@ -45,16 +45,16 @@ class TDTestCase: tdLog.printNoPrefix("==========step3:query timestamp type") - # tdSql.query("select * from t1 where ts between now()-1m and now()+10m") - # tdSql.checkRows(10) - # tdSql.query("select * from t1 where ts between '2021-01-01 00:00:00.000' and '2121-01-01 00:00:00.000'") + tdSql.query("select * from t1 where ts between now()-1m and now()+10m") + tdSql.checkRows(10) + tdSql.query("select * from t1 where ts between '2021-01-01 00:00:00.000' and '2121-01-01 00:00:00.000'") # tdSql.checkRows(11) - # tdSql.query("select * from t1 where ts between '1969-01-01 00:00:00.000' and '1969-12-31 23:59:59.999'") + tdSql.query("select * from t1 where ts between '1969-01-01 00:00:00.000' and '1969-12-31 23:59:59.999'") # tdSql.checkRows(0) - # tdSql.query("select * from t1 where ts between -2793600 and 31507199") - # tdSql.checkRows(0) - # tdSql.query("select * from t1 where ts between 1609430400000 and 4765104000000") - # tdSql.checkRows(11) + tdSql.query("select * from t1 where ts between -2793600 and 31507199") + tdSql.checkRows(0) + tdSql.query("select * from t1 where ts between 1609430400000 and 4765104000000") + tdSql.checkRows(11) tdLog.printNoPrefix("==========step4:query int type") @@ -68,11 +68,11 @@ class TDTestCase: tdSql.checkRows(0) # tdSql.query("select * from t1 where c1 between 0x64 and 0x69") # tdSql.checkRows(6) - # tdSql.query("select * from t1 where c1 not between 100 and 106") - # tdSql.checkRows(11) + tdSql.query("select * from t1 where c1 not between 100 and 106") + tdSql.checkRows(11) tdSql.query(f"select * from t1 where c1 between {2**31-2} and {2**31+1}") tdSql.checkRows(1) - tdSql.error(f"select * from t2 where c1 between null and {1-2**31}") + tdSql.query(f"select * from t2 where c1 between null and {1-2**31}") # tdSql.checkRows(3) tdSql.query(f"select * from t2 where c1 between {-2**31} and {1-2**31}") tdSql.checkRows(1) @@ -88,12 +88,12 @@ class TDTestCase: tdSql.query("select * from t1 where c2 between 'DC3' and 'SYN'") tdSql.checkRows(0) tdSql.query("select * from t1 where c2 not between 0.1 and 0.2") - # tdSql.checkRows(11) + tdSql.checkRows(11) tdSql.query(f"select * from t1 where c2 between {pow(10,38)*3.4} and {pow(10,38)*3.4+1}") # tdSql.checkRows(1) tdSql.query(f"select * from t2 where c2 between {-3.4*10**38-1} and {-3.4*10**38}") # tdSql.checkRows(2) - tdSql.error(f"select * from t2 where c2 between null and {-3.4*10**38}") + tdSql.query(f"select * from t2 where c2 between null and {-3.4*10**38}") # tdSql.checkRows(3) tdLog.printNoPrefix("==========step6:query bigint type") @@ -101,7 +101,7 @@ class TDTestCase: tdSql.query(f"select * from t1 where c3 between {2**31} and {2**31+10}") tdSql.checkRows(10) tdSql.query(f"select * from t1 where c3 between {-2**63} and {2**63}") - # tdSql.checkRows(11) + tdSql.checkRows(11) tdSql.query(f"select * from t1 where c3 between {2**31+10} and {2**31}") tdSql.checkRows(0) tdSql.query("select * from t1 where c3 between 'a' and 'z'") @@ -112,7 +112,7 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query(f"select * from t2 where c3 between {-2**63} and {1-2**63}") # tdSql.checkRows(3) - tdSql.error(f"select * from t2 where c3 between null and {1-2**63}") + tdSql.query(f"select * from t2 where c3 between null and {1-2**63}") # tdSql.checkRows(2) tdLog.printNoPrefix("==========step7:query double type") @@ -129,10 +129,10 @@ class TDTestCase: tdSql.query("select * from t1 where c4 not between 1 and 2") # tdSql.checkRows(0) tdSql.query(f"select * from t1 where c4 between {1.7*10**308} and {1.7*10**308+1}") - # tdSql.checkRows(1) + tdSql.checkRows(1) tdSql.query(f"select * from t2 where c4 between {-1.7*10**308-1} and {-1.7*10**308}") # tdSql.checkRows(3) - tdSql.error(f"select * from t2 where c4 between null and {-1.7*10**308}") + tdSql.query(f"select * from t2 where c4 between null and {-1.7*10**308}") # tdSql.checkRows(3) tdLog.printNoPrefix("==========step8:query smallint type") @@ -151,7 +151,7 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query("select * from t2 where c5 between -32768 and -32767") tdSql.checkRows(1) - tdSql.error("select * from t2 where c5 between null and -32767") + tdSql.query("select * from t2 where c5 between null and -32767") # tdSql.checkRows(1) tdLog.printNoPrefix("==========step9:query tinyint type") @@ -170,21 +170,21 @@ class TDTestCase: tdSql.checkRows(1) tdSql.query("select * from t2 where c6 between -128 and -127") tdSql.checkRows(1) - tdSql.error("select * from t2 where c6 between null and -127") + tdSql.query("select * from t2 where c6 between null and -127") # tdSql.checkRows(3) tdLog.printNoPrefix("==========step10:invalid query type") - # tdSql.query("select * from supt where location between 'beijing' and 'shanghai'") - # tdSql.checkRows(23) - # # 非0值均解析为1,因此"between 负值 and o"解析为"between 1 and 0" - # tdSql.query("select * from supt where isused between 0 and 1") - # tdSql.checkRows(23) - # tdSql.query("select * from supt where isused between -1 and 0") - # tdSql.checkRows(0) - # tdSql.error("select * from supt where isused between false and true") - # tdSql.query("select * from supt where family between '拖拉机' and '自行车'") - # tdSql.checkRows(23) + tdSql.query("select * from supt where location between 'beijing' and 'shanghai'") + tdSql.checkRows(23) + # 非0值均解析为1,因此"between 负值 and o"解析为"between 1 and 0" + tdSql.query("select * from supt where isused between 0 and 1") + tdSql.checkRows(23) + tdSql.query("select * from supt where isused between -1 and 0") + tdSql.checkRows(0) + tdSql.error("select * from supt where isused between false and true") + tdSql.query("select * from supt where family between '拖拉机' and '自行车'") + tdSql.checkRows(23) tdLog.printNoPrefix("==========step11:query HEX/OCT/BIN type") diff --git a/tests/system-test/2-query/join.py b/tests/system-test/2-query/join.py index 289dd3d62d..8fc131e581 100644 --- a/tests/system-test/2-query/join.py +++ b/tests/system-test/2-query/join.py @@ -28,7 +28,7 @@ class TDTestCase: def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") - tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), True) def __query_condition(self,tbname): query_condition = [] diff --git a/tests/system-test/2-query/timezone.py b/tests/system-test/2-query/timezone.py index 1f3dac90c6..ff55ab31bf 100644 --- a/tests/system-test/2-query/timezone.py +++ b/tests/system-test/2-query/timezone.py @@ -15,8 +15,16 @@ class TDTestCase: def run(self): # sourcery skip: extract-duplicate-method tdSql.prepare() # get system timezone - time_zone = os.popen('timedatectl | grep zone').read( - ).strip().split(':')[1].lstrip() + time_zone_arr = os.popen('timedatectl | grep zone').read( + ).strip().split(':') + if len(time_zone_arr) > 1: + time_zone = time_zone_arr[1].lstrip() + else: + # possibly in a docker container + time_zone_1 = os.popen('ls -l /etc/localtime|awk -F/ \'{print $(NF-1) "/" $NF}\'').read().strip() + time_zone_2 = os.popen('date "+(%Z, %z)"').read().strip() + time_zone = time_zone_1 + " " + time_zone_2 + print("expected time zone: " + time_zone) tdLog.printNoPrefix("==========step1:create tables==========") tdSql.execute( diff --git a/tests/system-test/7-tmq/basic5.py b/tests/system-test/7-tmq/basic5.py index 8a1932f05c..65840349ba 100644 --- a/tests/system-test/7-tmq/basic5.py +++ b/tests/system-test/7-tmq/basic5.py @@ -114,7 +114,7 @@ class TDTestCase: def tmqCase1(self, cfgPath, buildPath): - tdLog.printNoPrefix("======== test scenario 1: ") + tdLog.printNoPrefix("======== test case 1: Produce while consume") tdLog.info("step 1: create database, stb, ctb and insert data") # create and start thread parameterDict = {'cfg': '', \ @@ -122,8 +122,8 @@ class TDTestCase: 'vgroups': 1, \ 'stbName': 'stb', \ 'ctbNum': 10, \ - 'rowsPerTbl': 100, \ - 'batchNum': 10, \ + 'rowsPerTbl': 1000, \ + 'batchNum': 100, \ 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 parameterDict['cfg'] = cfgPath prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) @@ -163,8 +163,7 @@ class TDTestCase: tdSql.query("create table consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)") consumerId = 0 - expectmsgcnt = (parameterDict["rowsPerTbl"] / parameterDict["batchNum"] ) * parameterDict["ctbNum"] - expectmsgcnt1 = expectmsgcnt + parameterDict["ctbNum"] + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] topicList = topicFromStb ifcheckdata = 0 keyList = 'group.id:cgrp1,\ @@ -172,7 +171,7 @@ class TDTestCase: auto.commit.interval.ms:6000,\ auto.offset.reset:earliest' sql = "insert into consumeinfo values " - sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectmsgcnt1, ifcheckdata) + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) tdSql.query(sql) tdLog.info("check stb if there are data") @@ -209,18 +208,19 @@ class TDTestCase: else: time.sleep(5) - expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] - + tdLog.info("consumer result: %d, %d"%(tdSql.getData(0 , 2), tdSql.getData(0 , 3))) tdSql.checkData(0 , 1, consumerId) - tdSql.checkData(0 , 2, expectmsgcnt) + # mulit rows and mulit tables in one sql, this num of msg is not sure + #tdSql.checkData(0 , 2, expectmsgcnt) tdSql.checkData(0 , 3, expectrowcnt) tdSql.query("drop topic %s"%topicFromStb) tdSql.query("drop topic %s"%topicFromCtb) - + + tdLog.printNoPrefix("======== test case 1 end ...... ") def tmqCase2(self, cfgPath, buildPath): - tdLog.printNoPrefix("======== test scenario 2: add child table with consuming ") + tdLog.printNoPrefix("======== test case 2: add child table with consuming ") # create and start thread parameterDict = {'cfg': '', \ 'dbName': 'db2', \ @@ -275,9 +275,9 @@ class TDTestCase: tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + rowsOfNewCtb = 1000 consumerId = 0 - expectmsgcnt = (parameterDict["rowsPerTbl"] / parameterDict["batchNum"] ) * parameterDict["ctbNum"] - expectmsgcnt1 = expectmsgcnt + parameterDict["ctbNum"] + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + rowsOfNewCtb topicList = topicFromStb ifcheckdata = 0 keyList = 'group.id:cgrp1,\ @@ -285,7 +285,7 @@ class TDTestCase: auto.commit.interval.ms:6000,\ auto.offset.reset:earliest' sql = "insert into consumeinfo values " - sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectmsgcnt1, ifcheckdata) + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) tdSql.query(sql) tdLog.info("check stb if there are data") @@ -312,7 +312,6 @@ class TDTestCase: # create new child table and insert data newCtbName = 'newctb' - rowsOfNewCtb = 1000 tdSql.query("create table %s.%s using %s.%s tags(9999)"%(parameterDict["dbName"], newCtbName, parameterDict["dbName"], parameterDict["stbName"])) startTs = parameterDict["startTs"] for j in range(rowsOfNewCtb): @@ -332,14 +331,135 @@ class TDTestCase: else: time.sleep(5) - expectmsgcnt += rowsOfNewCtb - expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + rowsOfNewCtb - tdSql.checkData(0 , 1, consumerId) - tdSql.checkData(0 , 2, expectmsgcnt) tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicFromStb) + tdSql.query("drop topic %s"%topicFromCtb) - tdLog.printNoPrefix("======== test scenario 2 end ...... ") + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def tmqCase3(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 3: tow topics, each contains a stable, \ + but at the beginning, no ctables in the stable of one topic,\ + after starting consumer, create ctables ") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db2', \ + 'vgroups': 1, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 10000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + # wait db ready + while 1: + tdSql.query("show databases") + if tdSql.getRows() == 4: + print (tdSql.getData(0,0), tdSql.getData(1,0),tdSql.getData(2,0),) + break + else: + time.sleep(1) + + tdSql.query("use %s"%parameterDict['dbName']) + # wait stb ready + while 1: + tdSql.query("show %s.stables"%parameterDict['dbName']) + if tdSql.getRows() == 1: + break + else: + time.sleep(1) + + tdLog.info("create topics from super table") + topicFromStb = 'topic_stb_column2' + topicFromCtb = 'topic_ctb_column2' + + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s" %(topicFromStb, parameterDict['dbName'], parameterDict['stbName'])) + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s_0" %(topicFromCtb, parameterDict['dbName'], parameterDict['stbName'])) + + time.sleep(1) + tdSql.query("show topics") + topic1 = tdSql.getData(0 , 0) + topic2 = tdSql.getData(1 , 0) + tdLog.info("show topics: %s, %s"%(topic1, topic2)) + if topic1 != topicFromStb and topic1 != topicFromCtb: + tdLog.exit("topic error1") + if topic2 != topicFromStb and topic2 != topicFromCtb: + tdLog.exit("topic error2") + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + rowsOfNewCtb = 1000 + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + rowsOfNewCtb + topicList = topicFromStb + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into consumeinfo values " + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + tdLog.info("check stb if there are data") + while 1: + tdSql.query("select count(*) from %s"%parameterDict["stbName"]) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + countOfStb = tdSql.getData(0, 0) + if countOfStb != 0: + tdLog.info("count from stb: %d"%countOfStb) + break + else: + time.sleep(1) + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + shellCmd = 'nohup ' + buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, parameterDict["dbName"], showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + # create new child table and insert data + newCtbName = 'newctb' + tdSql.query("create table %s.%s using %s.%s tags(9999)"%(parameterDict["dbName"], newCtbName, parameterDict["dbName"], parameterDict["stbName"])) + startTs = parameterDict["startTs"] + for j in range(rowsOfNewCtb): + sql = "insert into %s.%s values (%d, %d, 'tmqrow_%d') "%(parameterDict["dbName"], newCtbName, startTs + j, j, j) + tdSql.execute(sql) + tdLog.debug("insert data into new child table ............ [OK]") + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from consumeresult") + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdSql.checkData(0 , 1, consumerId) + tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicFromStb) + tdSql.query("drop topic %s"%topicFromCtb) + + tdLog.printNoPrefix("======== test case 3 end ...... ") def run(self): tdSql.prepare() @@ -353,7 +473,7 @@ class TDTestCase: tdLog.info("cfgPath: %s" % cfgPath) self.tmqCase1(cfgPath, buildPath) - #self.tmqCase2(cfgPath, buildPath) + self.tmqCase2(cfgPath, buildPath) #self.tmqCase3(cfgPath, buildPath) def stop(self): diff --git a/tests/system-test/7-tmq/subscribeDb.py b/tests/system-test/7-tmq/subscribeDb.py new file mode 100644 index 0000000000..b8d3abca5c --- /dev/null +++ b/tests/system-test/7-tmq/subscribeDb.py @@ -0,0 +1,400 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + #rpcDebugFlagVal = '143' + #clientCfgDict = {'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #clientCfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #updatecfgDict = {'clientCfg': {}, 'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #updatecfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #print ("===================: ", updatecfgDict) + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def newcur(self,cfg,host,port): + user = "root" + password = "taosdata" + con=taos.connect(host=host, user=user, password=password, config=cfg ,port=port) + cur=con.cursor() + print(cur) + return cur + + def startTmqSimProcess(self,buildPath,cfgPath,pollDelay,dbName,showMsg,showRow,cdbName,valgrind=0): + shellCmd = 'nohup ' + if valgrind == 1: + logFile = cfgPath + '/../log/valgrind-tmq.log' + shellCmd = 'nohup valgrind --log-file=' + logFile + shellCmd += '--tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes ' + + shellCmd += buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, dbName, showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + def create_tables(self,tsql, dbName,vgroups,stbName,ctbNum,rowsPerTbl): + tsql.execute("create database if not exists %s vgroups %d"%(dbName, vgroups)) + tsql.execute("use %s" %dbName) + tsql.execute("create table if not exists %s (ts timestamp, c1 bigint, c2 binary(16)) tags(t1 int)"%stbName) + pre_create = "create table" + sql = pre_create + #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + for i in range(ctbNum): + sql += " %s_%d using %s tags(%d)"%(stbName,i,stbName,i+1) + if (i > 0) and (i%100 == 0): + tsql.execute(sql) + sql = pre_create + if sql != pre_create: + tsql.execute(sql) + + event.set() + tdLog.debug("complete to create database[%s], stable[%s] and %d child tables" %(dbName, stbName, ctbNum)) + return + + def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s_%d values "%(stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s_%d values " %(stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def prepareEnv(self, **parameterDict): + print ("input parameters:") + print (parameterDict) + # create new connector for my thread + tsql=self.newcur(parameterDict['cfg'], 'localhost', 6030) + self.create_tables(tsql,\ + parameterDict["dbName"],\ + parameterDict["vgroups"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"]) + + self.insert_data(tsql,\ + parameterDict["dbName"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"],\ + parameterDict["batchNum"],\ + parameterDict["startTs"]) + return + + def tmqCase1(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 1: Produce while one consume to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db1', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 200, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdLog.info("consumer result: %d, %d"%(tdSql.getData(0 , 2), tdSql.getData(0 , 3))) + tdSql.checkData(0 , 1, consumerId) + # mulit rows and mulit tables in one sql, this num of msg is not sure + #tdSql.checkData(0 , 2, expectmsgcnt) + tdSql.checkData(0 , 3, expectrowcnt+1) + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 2: Produce while two consumers to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db2', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + consumerId = 1 + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 2: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if totalConsumeRows != expectrowcnt + 2: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def tmqCase3(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 3: Produce while one consumers to subscribe one db, include 2 stb") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + parameterDict2 = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb2', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread2 = threading.Thread(target=self.prepareEnv, kwargs=parameterDict2) + prepareEnvThread2.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + parameterDict2["rowsPerTbl"] * parameterDict2["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + # consumerId = 1 + # sql = "insert into %s.consumeinfo values "%cdbName + # sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + # tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + prepareEnvThread2.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + #consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + #actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + #tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + #totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if actConsumeRows0 != expectrowcnt + 1: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def run(self): + tdSql.prepare() + + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + cfgPath = buildPath + "/../sim/psim/cfg" + tdLog.info("cfgPath: %s" % cfgPath) + + #self.tmqCase1(cfgPath, buildPath) + self.tmqCase2(cfgPath, buildPath) + #self.tmqCase3(cfgPath, buildPath) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/99-TDcase/TD-15554.py b/tests/system-test/99-TDcase/TD-15554.py new file mode 100644 index 0000000000..d7b2856b41 --- /dev/null +++ b/tests/system-test/99-TDcase/TD-15554.py @@ -0,0 +1,489 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + + #clientCfgDict = {'qdebugflag':'143'} + #updatecfgDict = {'clientCfg': {}, 'qdebugflag':'143'} + #updatecfgDict["clientCfg"] = clientCfgDict + #print ("===================: ", updatecfgDict) + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def newcur(self,cfg,host,port): + user = "root" + password = "taosdata" + con=taos.connect(host=host, user=user, password=password, config=cfg ,port=port) + cur=con.cursor() + print(cur) + return cur + + def create_tables(self,tsql, dbName,vgroups,stbName,ctbNum,rowsPerTbl): + tsql.execute("create database if not exists %s vgroups %d"%(dbName, vgroups)) + tsql.execute("use %s" %dbName) + tsql.execute("create table if not exists %s (ts timestamp, c1 bigint, c2 binary(16)) tags(t1 int)"%stbName) + pre_create = "create table" + sql = pre_create + #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + for i in range(ctbNum): + sql += " %s_%d using %s tags(%d)"%(stbName,i,stbName,i+1) + if (i > 0) and (i%100 == 0): + tsql.execute(sql) + sql = pre_create + if sql != pre_create: + tsql.execute(sql) + + tdLog.debug("complete to create database[%s], stable[%s] and %d child tables" %(dbName, stbName, ctbNum)) + return + + def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s_%d values "%(stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s_%d values " %(stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def prepareEnv(self, **parameterDict): + print ("input parameters:") + print (parameterDict) + # create new connector for my thread + tsql=self.newcur(parameterDict['cfg'], 'localhost', 6030) + self.create_tables(tsql,\ + parameterDict["dbName"],\ + parameterDict["vgroups"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"]) + + self.insert_data(tsql,\ + parameterDict["dbName"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"],\ + parameterDict["batchNum"],\ + parameterDict["startTs"]) + return + + + def tmqCase1(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 1: Produce while consume") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db', \ + 'vgroups': 1, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 1000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + time.sleep(2) + + # wait stb ready + while 1: + tdSql.query("show %s.stables"%parameterDict['dbName']) + if tdSql.getRows() == 1: + break + else: + time.sleep(1) + + tdLog.info("create topics from super table") + topicFromStb = 'topic_stb_column' + topicFromCtb = 'topic_ctb_column' + + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s" %(topicFromStb, parameterDict['dbName'], parameterDict['stbName'])) + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s_0" %(topicFromCtb, parameterDict['dbName'], parameterDict['stbName'])) + + time.sleep(1) + tdSql.query("show topics") + #tdSql.checkRows(2) + topic1 = tdSql.getData(0 , 0) + topic2 = tdSql.getData(1 , 0) + + tdLog.info("show topics: %s, %s"%(topic1, topic2)) + if topic1 != topicFromStb and topic1 != topicFromCtb: + tdLog.exit("topic error1") + if topic2 != topicFromStb and topic2 != topicFromCtb: + tdLog.exit("topic error2") + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)") + tdSql.query("create table consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)") + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicFromStb + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into consumeinfo values " + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + tdLog.info("check stb if there are data") + while 1: + tdSql.query("select count(*) from %s"%parameterDict["stbName"]) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + countOfStb = tdSql.getData(0, 0) + if countOfStb != 0: + tdLog.info("count from stb: %d"%countOfStb) + break + else: + time.sleep(1) + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + shellCmd = 'nohup ' + buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, parameterDict["dbName"], showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from consumeresult") + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdLog.info("consumer result: %d, %d"%(tdSql.getData(0 , 2), tdSql.getData(0 , 3))) + tdSql.checkData(0 , 1, consumerId) + # mulit rows and mulit tables in one sql, this num of msg is not sure + #tdSql.checkData(0 , 2, expectmsgcnt) + tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicFromStb) + tdSql.query("drop topic %s"%topicFromCtb) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 2: add child table with consuming ") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db2', \ + 'vgroups': 1, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 10000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + # wait db ready + while 1: + tdSql.query("show databases") + if tdSql.getRows() == 4: + print (tdSql.getData(0,0), tdSql.getData(1,0),tdSql.getData(2,0),) + break + else: + time.sleep(1) + + tdSql.query("use %s"%parameterDict['dbName']) + # wait stb ready + while 1: + tdSql.query("show %s.stables"%parameterDict['dbName']) + if tdSql.getRows() == 1: + break + else: + time.sleep(1) + + tdLog.info("create topics from super table") + topicFromStb = 'topic_stb_column2' + topicFromCtb = 'topic_ctb_column2' + + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s" %(topicFromStb, parameterDict['dbName'], parameterDict['stbName'])) + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s_0" %(topicFromCtb, parameterDict['dbName'], parameterDict['stbName'])) + + time.sleep(1) + tdSql.query("show topics") + topic1 = tdSql.getData(0 , 0) + topic2 = tdSql.getData(1 , 0) + tdLog.info("show topics: %s, %s"%(topic1, topic2)) + if topic1 != topicFromStb and topic1 != topicFromCtb: + tdLog.exit("topic error1") + if topic2 != topicFromStb and topic2 != topicFromCtb: + tdLog.exit("topic error2") + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + rowsOfNewCtb = 1000 + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + rowsOfNewCtb + topicList = topicFromStb + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into consumeinfo values " + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + tdLog.info("check stb if there are data") + while 1: + tdSql.query("select count(*) from %s"%parameterDict["stbName"]) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + countOfStb = tdSql.getData(0, 0) + if countOfStb != 0: + tdLog.info("count from stb: %d"%countOfStb) + break + else: + time.sleep(1) + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + shellCmd = 'nohup ' + buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, parameterDict["dbName"], showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + # create new child table and insert data + newCtbName = 'newctb' + tdSql.query("create table %s.%s using %s.%s tags(9999)"%(parameterDict["dbName"], newCtbName, parameterDict["dbName"], parameterDict["stbName"])) + startTs = parameterDict["startTs"] + for j in range(rowsOfNewCtb): + sql = "insert into %s.%s values (%d, %d, 'tmqrow_%d') "%(parameterDict["dbName"], newCtbName, startTs + j, j, j) + tdSql.execute(sql) + tdLog.debug("insert data into new child table ............ [OK]") + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from consumeresult") + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdSql.checkData(0 , 1, consumerId) + tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicFromStb) + tdSql.query("drop topic %s"%topicFromCtb) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def tmqCase3(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 3: tow topics, each contains a stable, \ + but at the beginning, no ctables in the stable of one topic,\ + after starting consumer, create ctables ") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 1, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 30000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + # wait db ready + while 1: + tdSql.query("show databases") + if tdSql.getRows() == 4: + print (tdSql.getData(0,0), tdSql.getData(1,0),tdSql.getData(2,0),) + break + else: + time.sleep(1) + + tdSql.query("use %s"%parameterDict['dbName']) + # wait stb ready + while 1: + tdSql.query("show %s.stables"%parameterDict['dbName']) + if tdSql.getRows() == 1: + break + else: + time.sleep(1) + + tdLog.info("create stable2 for the seconde topic") + parameterDict2 = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 1, \ + 'stbName': 'stb2', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 30000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict2['cfg'] = cfgPath + tdSql.execute("create stable if not exists %s.%s (ts timestamp, c1 bigint, c2 binary(16)) tags(t1 int)"%(parameterDict2['dbName'], parameterDict2['stbName'])) + + tdLog.info("create topics from super table") + topicFromStb = 'topic_stb_column3' + topicFromStb2 = 'topic_stb_column32' + + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s" %(topicFromStb, parameterDict['dbName'], parameterDict['stbName'])) + tdSql.execute("create topic %s as select ts, c1, c2 from %s.%s" %(topicFromStb2, parameterDict2['dbName'], parameterDict2['stbName'])) + + tdSql.query("show topics") + topic1 = tdSql.getData(0 , 0) + topic2 = tdSql.getData(1 , 0) + tdLog.info("show topics: %s, %s"%(topic1, topic2)) + if topic1 != topicFromStb and topic1 != topicFromStb2: + tdLog.exit("topic error1") + if topic2 != topicFromStb and topic2 != topicFromStb2: + tdLog.exit("topic error2") + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + parameterDict2["rowsPerTbl"] * parameterDict2["ctbNum"] + topicList = topicFromStb + ',' + topicFromStb2 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into consumeinfo values " + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + tdLog.info("check stb if there are data") + while 1: + tdSql.query("select count(*) from %s"%parameterDict["stbName"]) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + countOfStb = tdSql.getData(0, 0) + if countOfStb != 0: + tdLog.info("count from stb: %d"%countOfStb) + break + else: + time.sleep(1) + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + shellCmd = 'nohup ' + buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, parameterDict["dbName"], showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + # start the second thread to create new child table and insert data + prepareEnvThread2 = threading.Thread(target=self.prepareEnv, kwargs=parameterDict2) + prepareEnvThread2.start() + + # wait for data ready + prepareEnvThread.join() + prepareEnvThread2.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from consumeresult") + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdSql.checkData(0 , 1, consumerId) + tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicFromStb) + tdSql.query("drop topic %s"%topicFromStb2) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def run(self): + tdSql.prepare() + + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + cfgPath = buildPath + "/../sim/psim/cfg" + tdLog.info("cfgPath: %s" % cfgPath) + + #self.tmqCase1(cfgPath, buildPath) + #self.tmqCase2(cfgPath, buildPath) + self.tmqCase3(cfgPath, buildPath) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/99-TDcase/TD-15557.py b/tests/system-test/99-TDcase/TD-15557.py new file mode 100644 index 0000000000..e005985fe0 --- /dev/null +++ b/tests/system-test/99-TDcase/TD-15557.py @@ -0,0 +1,405 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + #rpcDebugFlagVal = '143' + #clientCfgDict = {'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #clientCfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #updatecfgDict = {'clientCfg': {}, 'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #updatecfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #print ("===================: ", updatecfgDict) + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def newcur(self,cfg,host,port): + user = "root" + password = "taosdata" + con=taos.connect(host=host, user=user, password=password, config=cfg ,port=port) + cur=con.cursor() + print(cur) + return cur + + def startTmqSimProcess(self,buildPath,cfgPath,pollDelay,dbName,showMsg,showRow,cdbName,valgrind): + shellCmd = 'nohup ' + if valgrind == 1: + logFile = cfgPath + '/../log/valgrind-tmq.log' + shellCmd = 'nohup valgrind --log-file=' + logFile + shellCmd += '--tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes ' + + shellCmd += buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, dbName, showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + def create_tables(self,tsql, dbName,vgroups,stbName,ctbNum,rowsPerTbl): + tsql.execute("create database if not exists %s vgroups %d"%(dbName, vgroups)) + tsql.execute("use %s" %dbName) + tsql.execute("create table if not exists %s (ts timestamp, c1 bigint, c2 binary(16)) tags(t1 int)"%stbName) + pre_create = "create table" + sql = pre_create + #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + for i in range(ctbNum): + sql += " %s_%d using %s tags(%d)"%(stbName,i,stbName,i+1) + if (i > 0) and (i%100 == 0): + tsql.execute(sql) + sql = pre_create + if sql != pre_create: + tsql.execute(sql) + + event.set() + tdLog.debug("complete to create database[%s], stable[%s] and %d child tables" %(dbName, stbName, ctbNum)) + return + + def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s_%d values "%(stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s_%d values " %(stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def prepareEnv(self, **parameterDict): + print ("input parameters:") + print (parameterDict) + # create new connector for my thread + tsql=self.newcur(parameterDict['cfg'], 'localhost', 6030) + self.create_tables(tsql,\ + parameterDict["dbName"],\ + parameterDict["vgroups"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"]) + + self.insert_data(tsql,\ + parameterDict["dbName"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"],\ + parameterDict["batchNum"],\ + parameterDict["startTs"]) + return + + def tmqCase1(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 1: Produce while one consume to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db1', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 10000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + valgrind = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName,valgrind) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdLog.info("consumer result: %d, %d"%(tdSql.getData(0 , 2), tdSql.getData(0 , 3))) + tdSql.checkData(0 , 1, consumerId) + # mulit rows and mulit tables in one sql, this num of msg is not sure + #tdSql.checkData(0 , 2, expectmsgcnt) + tdSql.checkData(0 , 3, expectrowcnt) + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 2: Produce while two consumers to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db2', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + consumerId = 1 + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + + valgrind = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName,valgrind) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 2: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def tmqCase3(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 3: Produce while one consumers to subscribe one db, include 2 stb") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + parameterDict2 = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb2', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread2 = threading.Thread(target=self.prepareEnv, kwargs=parameterDict2) + prepareEnvThread2.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + parameterDict2["rowsPerTbl"] * parameterDict2["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + # consumerId = 1 + # sql = "insert into %s.consumeinfo values "%cdbName + # sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + # tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + valgrind = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName,valgrind) + + # wait for data ready + prepareEnvThread.join() + prepareEnvThread2.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + #consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + #actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + #tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + #totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if actConsumeRows0 != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def run(self): + tdSql.prepare() + + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + cfgPath = buildPath + "/../sim/psim/cfg" + tdLog.info("cfgPath: %s" % cfgPath) + + self.tmqCase1(cfgPath, buildPath) + #self.tmqCase2(cfgPath, buildPath) + #self.tmqCase3(cfgPath, buildPath) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/99-TDcase/TD-15563.py b/tests/system-test/99-TDcase/TD-15563.py new file mode 100644 index 0000000000..b8d3abca5c --- /dev/null +++ b/tests/system-test/99-TDcase/TD-15563.py @@ -0,0 +1,400 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + #rpcDebugFlagVal = '143' + #clientCfgDict = {'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #clientCfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #updatecfgDict = {'clientCfg': {}, 'serverPort': '', 'firstEp': '', 'secondEp':'', 'rpcDebugFlag':'135', 'fqdn':''} + #updatecfgDict["rpcDebugFlag"] = rpcDebugFlagVal + #print ("===================: ", updatecfgDict) + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def newcur(self,cfg,host,port): + user = "root" + password = "taosdata" + con=taos.connect(host=host, user=user, password=password, config=cfg ,port=port) + cur=con.cursor() + print(cur) + return cur + + def startTmqSimProcess(self,buildPath,cfgPath,pollDelay,dbName,showMsg,showRow,cdbName,valgrind=0): + shellCmd = 'nohup ' + if valgrind == 1: + logFile = cfgPath + '/../log/valgrind-tmq.log' + shellCmd = 'nohup valgrind --log-file=' + logFile + shellCmd += '--tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all --num-callers=20 -v --workaround-gcc296-bugs=yes ' + + shellCmd += buildPath + '/build/bin/tmq_sim -c ' + cfgPath + shellCmd += " -y %d -d %s -g %d -r %d -w %s "%(pollDelay, dbName, showMsg, showRow, cdbName) + shellCmd += "> /dev/null 2>&1 &" + tdLog.info(shellCmd) + os.system(shellCmd) + + def create_tables(self,tsql, dbName,vgroups,stbName,ctbNum,rowsPerTbl): + tsql.execute("create database if not exists %s vgroups %d"%(dbName, vgroups)) + tsql.execute("use %s" %dbName) + tsql.execute("create table if not exists %s (ts timestamp, c1 bigint, c2 binary(16)) tags(t1 int)"%stbName) + pre_create = "create table" + sql = pre_create + #tdLog.debug("doing create one stable %s and %d child table in %s ..." %(stbname, count ,dbname)) + for i in range(ctbNum): + sql += " %s_%d using %s tags(%d)"%(stbName,i,stbName,i+1) + if (i > 0) and (i%100 == 0): + tsql.execute(sql) + sql = pre_create + if sql != pre_create: + tsql.execute(sql) + + event.set() + tdLog.debug("complete to create database[%s], stable[%s] and %d child tables" %(dbName, stbName, ctbNum)) + return + + def insert_data(self,tsql,dbName,stbName,ctbNum,rowsPerTbl,batchNum,startTs): + tdLog.debug("start to insert data ............") + tsql.execute("use %s" %dbName) + pre_insert = "insert into " + sql = pre_insert + + #tdLog.debug("doing insert data into stable:%s rows:%d ..."%(stbName, allRows)) + for i in range(ctbNum): + sql += " %s_%d values "%(stbName,i) + for j in range(rowsPerTbl): + sql += "(%d, %d, 'tmqrow_%d') "%(startTs + j, j, j) + if (j > 0) and ((j%batchNum == 0) or (j == rowsPerTbl - 1)): + tsql.execute(sql) + if j < rowsPerTbl - 1: + sql = "insert into %s_%d values " %(stbName,i) + else: + sql = "insert into " + #end sql + if sql != pre_insert: + #print("insert sql:%s"%sql) + tsql.execute(sql) + tdLog.debug("insert data ............ [OK]") + return + + def prepareEnv(self, **parameterDict): + print ("input parameters:") + print (parameterDict) + # create new connector for my thread + tsql=self.newcur(parameterDict['cfg'], 'localhost', 6030) + self.create_tables(tsql,\ + parameterDict["dbName"],\ + parameterDict["vgroups"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"]) + + self.insert_data(tsql,\ + parameterDict["dbName"],\ + parameterDict["stbName"],\ + parameterDict["ctbNum"],\ + parameterDict["rowsPerTbl"],\ + parameterDict["batchNum"],\ + parameterDict["startTs"]) + return + + def tmqCase1(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 1: Produce while one consume to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db1', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 200, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + tdLog.info("consumer result: %d, %d"%(tdSql.getData(0 , 2), tdSql.getData(0 , 3))) + tdSql.checkData(0 , 1, consumerId) + # mulit rows and mulit tables in one sql, this num of msg is not sure + #tdSql.checkData(0 , 2, expectmsgcnt) + tdSql.checkData(0 , 3, expectrowcnt+1) + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 2: Produce while two consumers to subscribe one db") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db2', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + consumerId = 1 + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 2: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if totalConsumeRows != expectrowcnt + 2: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def tmqCase3(self, cfgPath, buildPath): + tdLog.printNoPrefix("======== test case 3: Produce while one consumers to subscribe one db, include 2 stb") + tdLog.info("step 1: create database, stb, ctb and insert data") + # create and start thread + parameterDict = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + tdSql.execute("create database if not exists %s vgroups %d" %(parameterDict['dbName'], parameterDict['vgroups'])) + + prepareEnvThread = threading.Thread(target=self.prepareEnv, kwargs=parameterDict) + prepareEnvThread.start() + + parameterDict2 = {'cfg': '', \ + 'dbName': 'db3', \ + 'vgroups': 4, \ + 'stbName': 'stb2', \ + 'ctbNum': 10, \ + 'rowsPerTbl': 100000, \ + 'batchNum': 100, \ + 'startTs': 1640966400000} # 2022-01-01 00:00:00.000 + parameterDict['cfg'] = cfgPath + + prepareEnvThread2 = threading.Thread(target=self.prepareEnv, kwargs=parameterDict2) + prepareEnvThread2.start() + + tdLog.info("create topics from db") + topicName1 = 'topic_db1' + + tdSql.execute("create topic %s as %s" %(topicName1, parameterDict['dbName'])) + + tdLog.info("create consume info table and consume result table") + cdbName = parameterDict["dbName"] + tdSql.query("create table %s.consumeinfo (ts timestamp, consumerid int, topiclist binary(1024), keylist binary(1024), expectmsgcnt bigint, ifcheckdata int)"%cdbName) + tdSql.query("create table %s.consumeresult (ts timestamp, consumerid int, consummsgcnt bigint, consumrowcnt bigint, checkresult int)"%cdbName) + + consumerId = 0 + expectrowcnt = parameterDict["rowsPerTbl"] * parameterDict["ctbNum"] + parameterDict2["rowsPerTbl"] * parameterDict2["ctbNum"] + topicList = topicName1 + ifcheckdata = 0 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:false,\ + auto.commit.interval.ms:6000,\ + auto.offset.reset:earliest' + sql = "insert into %s.consumeinfo values "%cdbName + sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + tdSql.query(sql) + + # consumerId = 1 + # sql = "insert into %s.consumeinfo values "%cdbName + # sql += "(now, %d, '%s', '%s', %d, %d)"%(consumerId, topicList, keyList, expectrowcnt, ifcheckdata) + # tdSql.query(sql) + + event.wait() + + tdLog.info("start consume processor") + pollDelay = 5 + showMsg = 1 + showRow = 1 + self.startTmqSimProcess(buildPath,cfgPath,pollDelay,parameterDict["dbName"],showMsg, showRow, cdbName) + + # wait for data ready + prepareEnvThread.join() + prepareEnvThread2.join() + + tdLog.info("insert process end, and start to check consume result") + while 1: + tdSql.query("select * from %s.consumeresult"%cdbName) + #tdLog.info("row: %d, %l64d, %l64d"%(tdSql.getData(0, 1),tdSql.getData(0, 2),tdSql.getData(0, 3)) + if tdSql.getRows() == 1: + break + else: + time.sleep(5) + + consumerId0 = tdSql.getData(0 , 1) + #consumerId1 = tdSql.getData(1 , 1) + actConsumeRows0 = tdSql.getData(0 , 3) + #actConsumeRows1 = tdSql.getData(1 , 3) + + tdLog.info("consumer %d rows: %d"%(consumerId0, actConsumeRows0)) + #tdLog.info("consumer %d rows: %d"%(consumerId1, actConsumeRows1)) + + #totalConsumeRows = actConsumeRows0 + actConsumeRows1 + if actConsumeRows0 != expectrowcnt + 1: + tdLog.exit("tmq consume rows error!") + + tdSql.query("drop topic %s"%topicName1) + + tdLog.printNoPrefix("======== test case 3 end ...... ") + + def run(self): + tdSql.prepare() + + buildPath = self.getBuildPath() + if (buildPath == ""): + tdLog.exit("taosd not found!") + else: + tdLog.info("taosd found in %s" % buildPath) + cfgPath = buildPath + "/../sim/psim/cfg" + tdLog.info("cfgPath: %s" % cfgPath) + + #self.tmqCase1(cfgPath, buildPath) + self.tmqCase2(cfgPath, buildPath) + #self.tmqCase3(cfgPath, buildPath) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 817f814873..c80206abbc 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -8,6 +8,8 @@ python3 ./test.py -f 0-others/taosShellNetChk.py python3 ./test.py -f 0-others/telemetry.py python3 ./test.py -f 0-others/taosdMonitor.py +python3 ./test.py -f 0-others/user_control.py + #python3 ./test.py -f 2-query/between.py python3 ./test.py -f 2-query/distinct.py python3 ./test.py -f 2-query/varchar.py @@ -53,5 +55,3 @@ python3 ./test.py -f 2-query/arctan.py # python3 ./test.py -f 2-query/query_cols_tags_and_or.py python3 ./test.py -f 7-tmq/basic5.py - - diff --git a/tests/test/c/tmqSim.c b/tests/test/c/tmqSim.c index bc3aa091c3..1228d6174c 100644 --- a/tests/test/c/tmqSim.c +++ b/tests/test/c/tmqSim.c @@ -98,12 +98,24 @@ static void printHelp() { } void initLogFile() { - // FILE *fp = fopen(g_stConfInfo.resultFileName, "a"); - char file[256]; - sprintf(file, "%s/../log/tmqlog.txt", configDir); - TdFilePtr pFile = taosOpenFile(file, TD_FILE_TEXT | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); + time_t now; + struct tm curTime; + char filename[256]; + + now = taosTime(NULL); + taosLocalTime(&now, &curTime); + sprintf(filename,"%s/../log/tmqlog_%04d-%02d-%02d %02d-%02d-%02d.txt", + configDir, + curTime.tm_year+1900, + curTime.tm_mon+1, + curTime.tm_mday, + curTime.tm_hour, + curTime.tm_min, + curTime.tm_sec); + //sprintf(filename, "%s/../log/tmqlog.txt", configDir); + TdFilePtr pFile = taosOpenFile(filename, TD_FILE_TEXT | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_STREAM); if (NULL == pFile) { - fprintf(stderr, "Failed to open %s for save result\n", "./tmqlog.txt"); + fprintf(stderr, "Failed to open %s for save result\n", filename); exit(-1); } g_fp = pFile; @@ -167,7 +179,7 @@ void parseArgument(int32_t argc, char* argv[]) { } else if (strcmp(argv[i], "-y") == 0) { g_stConfInfo.consumeDelay = atol(argv[++i]); } else { - printf("%s unknow para: %s %s", GREEN, argv[++i], NC); + pError("%s unknow para: %s %s", GREEN, argv[++i], NC); exit(-1); } } @@ -247,7 +259,7 @@ int queryDB(TAOS* taos, char* command) { } static void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets, void* param) { - printf("tmq_commit_cb_print() commit %d\n", resp); + pError("tmq_commit_cb_print() commit %d\n", resp); } void build_consumer(SThreadInfo* pInfo) { @@ -306,7 +318,7 @@ int32_t saveConsumeResult(SThreadInfo* pInfo) { TAOS_RES* pRes = taos_query(pConn, sqlStr); if (taos_errno(pRes) != 0) { - printf("error in save consumeinfo, reason:%s\n", taos_errstr(pRes)); + pError("error in save consumeinfo, reason:%s\n", taos_errstr(pRes)); taos_free_result(pRes); exit(-1); } @@ -333,8 +345,8 @@ void loop_consume(SThreadInfo* pInfo) { totalMsgs++; - if (totalMsgs >= pInfo->expectMsgCnt) { - taosFprintfFile(g_fp, "==== totalMsgs >= pInfo->expectMsgCnt, so break\n"); + if (totalRows >= pInfo->expectMsgCnt) { + taosFprintfFile(g_fp, "==== totalRows >= pInfo->expectMsgCnt, so break\n"); break; } } else { @@ -363,7 +375,7 @@ void* consumeThreadFunc(void* param) { tmq_resp_err_t err = tmq_subscribe(pInfo->tmq, pInfo->topicList); if (err) { - printf("tmq_subscribe() fail, reason: %s\n", tmq_err2str(err)); + pError("tmq_subscribe() fail, reason: %s\n", tmq_err2str(err)); exit(-1); } @@ -376,14 +388,14 @@ void* consumeThreadFunc(void* param) { err = tmq_unsubscribe(pInfo->tmq); if (err) { - printf("tmq_unsubscribe() fail, reason: %s\n", tmq_err2str(err)); + pError("tmq_unsubscribe() fail, reason: %s\n", tmq_err2str(err)); pInfo->consumeMsgCnt = -1; return NULL; } err = tmq_consumer_close(pInfo->tmq); if (err) { - printf("tmq_consumer_close() fail, reason: %s\n", tmq_err2str(err)); + pError("tmq_consumer_close() fail, reason: %s\n", tmq_err2str(err)); exit(-1); } pInfo->tmq = NULL; @@ -439,7 +451,7 @@ int32_t getConsumeInfo() { sprintf(sqlStr, "select * from %s.consumeinfo", g_stConfInfo.cdbName); TAOS_RES* pRes = taos_query(pConn, sqlStr); if (taos_errno(pRes) != 0) { - printf("error in get consumeinfo, reason:%s\n", taos_errstr(pRes)); + pError("error in get consumeinfo, reason:%s\n", taos_errstr(pRes)); taosFprintfFile(g_fp, "error in get consumeinfo, reason:%s\n", taos_errstr(pRes)); taosCloseFile(&g_fp); taos_free_result(pRes); diff --git a/tests/unit-test/test.sh b/tests/unit-test/test.sh new file mode 100755 index 0000000000..4122597717 --- /dev/null +++ b/tests/unit-test/test.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +function usage() { + echo "$0" + echo -e "\t -e enterprise edition" + echo -e "\t -h help" +} + +ent=0 +while getopts "eh" opt; do + case $opt in + e) + ent=1 + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option: -$OPTARG" + usage + exit 0 + ;; + esac +done + +script_dir=`dirname $0` +cd ${script_dir} +PWD=`pwd` + +if [ $ent -eq 0 ]; then + cd ../../debug +else + cd ../../../debug +fi + +ctest -j8 +ret=$? +exit $ret + diff --git a/tools/shell/src/shellArguments.c b/tools/shell/src/shellArguments.c index 13f8cde3e3..1639fd1ca6 100644 --- a/tools/shell/src/shellArguments.c +++ b/tools/shell/src/shellArguments.c @@ -332,7 +332,7 @@ int32_t shellParseArgs(int32_t argc, char *argv[]) { shellInitArgs(argc, argv); shell.info.clientVersion = "Welcome to the TDengine shell from %s, Client Version:%s\n" - "Copyright (c) 2020 by TAOS Data, Inc. All rights reserved.\n\n"; + "Copyright (c) 2022 by TAOS Data, Inc. All rights reserved.\n\n"; shell.info.promptHeader = "taos> "; shell.info.promptContinue = " -> "; shell.info.promptSize = 6; diff --git a/tools/shell/src/shellCommand.c b/tools/shell/src/shellCommand.c index f4f7c893c4..ef71f3fce6 100644 --- a/tools/shell/src/shellCommand.c +++ b/tools/shell/src/shellCommand.c @@ -53,79 +53,6 @@ static void shellResetCommand(SShellCmd *cmd, const char s[]); static void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos); static void shellShowOnScreen(SShellCmd *cmd); -#if defined(_TD_WINDOWS_64) || defined(_TD_WINDOWS_32) -// static void shellPrintContinuePrompt() { printf("%s", shell.args.promptContinue); } -// static void shellPrintPrompt() { printf("%s", shell.args.promptHeader); } - -void shellUpdateBuffer(SShellCmd *cmd) { - if (shellRegexMatch(cmd->buffer, "(\\s+$)|(^$)", REG_EXTENDED)) strcat(cmd->command, " "); - strcat(cmd->buffer, cmd->command); - - memset(cmd->command, 0, SHELL_MAX_COMMAND_SIZE); - cmd->cursorOffset = 0; -} - -int shellIsReadyGo(SShellCmd *cmd) { - char *total = taosMemoryMalloc(SHELL_MAX_COMMAND_SIZE); - memset(total, 0, SHELL_MAX_COMMAND_SIZE); - sprintf(total, "%s%s", cmd->buffer, cmd->command); - - char *reg_str = - "(^.*;\\s*$)|(^\\s*$)|(^\\s*exit\\s*$)|(^\\s*q\\s*$)|(^\\s*quit\\s*$)|(^" - "\\s*clear\\s*$)"; - if (shellRegexMatch(total, reg_str, REG_EXTENDED | REG_ICASE)) { - taosMemoryFree(total); - return 1; - } - - taosMemoryFree(total); - return 0; -} - -void shellInsertChar(SShellCmd *cmd, char c) { - if (cmd->cursorOffset >= SHELL_MAX_COMMAND_SIZE) { - fprintf(stdout, "sql is larger than %d bytes", SHELL_MAX_COMMAND_SIZE); - return; - } - cmd->command[cmd->cursorOffset++] = c; -} - -int32_t shellReadCommand(char command[]) { - SShellCmd cmd; - memset(&cmd, 0, sizeof(cmd)); - cmd.buffer = (char *)taosMemoryCalloc(1, SHELL_MAX_COMMAND_SIZE); - cmd.command = (char *)taosMemoryCalloc(1, SHELL_MAX_COMMAND_SIZE); - - // Read input. - char c; - while (1) { - c = getchar(); - - switch (c) { - case '\n': - case '\r': - if (shellIsReadyGo(&cmd)) { - sprintf(command, "%s%s", cmd.buffer, cmd.command); - taosMemoryFree(cmd.buffer); - cmd.buffer = NULL; - taosMemoryFree(cmd.command); - cmd.command = NULL; - return 0; - } else { - // shellPrintContinuePrompt(); - shellUpdateBuffer(&cmd); - } - break; - default: - shellInsertChar(&cmd, c); - } - } - - return 0; -} - -#else - int32_t shellCountPrefixOnes(uint8_t c) { uint8_t mask = 127; mask = ~mask; @@ -181,7 +108,10 @@ void shellInsertChar(SShellCmd *cmd, char *c, int32_t size) { cmd->cursorOffset += size; cmd->screenOffset += taosWcharWidth(wc); cmd->endOffset += taosWcharWidth(wc); +#ifdef WINDOWS +#else shellShowOnScreen(cmd); +#endif } void shellBackspaceChar(SShellCmd *cmd) { @@ -371,17 +301,33 @@ void shellResetCommand(SShellCmd *cmd, const char s[]) { shellShowOnScreen(cmd); } -void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos) { + +void shellGetScreenSize(int32_t *ws_col, int32_t *ws_row) { +#ifdef WINDOWS + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + if (ws_col != NULL) *ws_col = csbi.srWindow.Right - csbi.srWindow.Left + 1; + if (ws_row != NULL) *ws_row = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; +#else struct winsize w; if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) { // fprintf(stderr, "No stream device, and use default value(col 120, row 30)\n"); - w.ws_col = 120; - w.ws_row = 30; + if (ws_col != NULL) *ws_col = 120; + if (ws_row != NULL) *ws_row = 30; + } else { + if (ws_col != NULL) *ws_col = w.ws_col; + if (ws_row != NULL) *ws_row = w.ws_row; } +#endif +} - int32_t cursor_x = cursor_pos / w.ws_col; - int32_t cursor_y = cursor_pos % w.ws_col; - int32_t command_x = ecmd_pos / w.ws_col; +void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos) { + int32_t ws_col; + shellGetScreenSize(&ws_col, NULL); + + int32_t cursor_x = cursor_pos / ws_col; + int32_t cursor_y = cursor_pos % ws_col; + int32_t command_x = ecmd_pos / ws_col; shellPositionCursor(cursor_y, LEFT); shellPositionCursor(command_x - cursor_x, DOWN); fprintf(stdout, "\033[2K"); @@ -393,12 +339,8 @@ void shellClearScreen(int32_t ecmd_pos, int32_t cursor_pos) { } void shellShowOnScreen(SShellCmd *cmd) { - struct winsize w; - if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) { - // fprintf(stderr, "No stream device\n"); - w.ws_col = 120; - w.ws_row = 30; - } + int32_t ws_col; + shellGetScreenSize(&ws_col, NULL); TdWchar wc; int32_t size = 0; @@ -411,8 +353,7 @@ void shellShowOnScreen(SShellCmd *cmd) { } else { sprintf(total_string, "%s%s", shell.info.promptContinue, cmd->command); } - - int32_t remain_column = w.ws_col; + int32_t remain_column = ws_col; for (char *str = total_string; size < cmd->commandSize + PSIZE;) { int32_t ret = taosMbToWchar(&wc, str, MB_CUR_MAX); if (ret < 0) break; @@ -425,10 +366,10 @@ void shellShowOnScreen(SShellCmd *cmd) { } else { if (remain_column == width) { printf("%lc\n\r", wc); - remain_column = w.ws_col; + remain_column = ws_col; } else { printf("\n\r%lc", wc); - remain_column = w.ws_col - width; + remain_column = ws_col - width; } } @@ -436,17 +377,16 @@ void shellShowOnScreen(SShellCmd *cmd) { } taosMemoryFree(total_string); - // Position the cursor int32_t cursor_pos = cmd->screenOffset + PSIZE; int32_t ecmd_pos = cmd->endOffset + PSIZE; - int32_t cursor_x = cursor_pos / w.ws_col; - int32_t cursor_y = cursor_pos % w.ws_col; - // int32_t cursor_y = cursor % w.ws_col; - int32_t command_x = ecmd_pos / w.ws_col; - int32_t command_y = ecmd_pos % w.ws_col; - // int32_t command_y = (command.size() + PSIZE) % w.ws_col; + int32_t cursor_x = cursor_pos / ws_col; + int32_t cursor_y = cursor_pos % ws_col; + // int32_t cursor_y = cursor % ws_col; + int32_t command_x = ecmd_pos / ws_col; + int32_t command_y = ecmd_pos % ws_col; + // int32_t command_y = (command.size() + PSIZE) % ws_col; shellPositionCursor(command_y, LEFT); shellPositionCursor(command_x, UP); shellPositionCursor(cursor_x, DOWN); @@ -490,7 +430,11 @@ int32_t shellReadCommand(char *command) { case 3: printf("\n"); shellResetCommand(&cmd, ""); - kill(0, SIGINT); + #ifdef WINDOWS + raise(SIGINT); + #else + kill(0, SIGINT); + #endif break; case 4: // EOF or Ctrl+D printf("\n"); @@ -503,7 +447,10 @@ int32_t shellReadCommand(char *command) { break; case '\n': case '\r': + #ifdef WINDOWS + #else printf("\n"); + #endif if (shellIsReadyGo(&cmd)) { sprintf(command, "%s%s", cmd.buffer, cmd.command); taosMemoryFreeClear(cmd.buffer); @@ -608,5 +555,3 @@ int32_t shellReadCommand(char *command) { return 0; } - -#endif \ No newline at end of file diff --git a/tools/shell/src/shellEngine.c b/tools/shell/src/shellEngine.c index 21fd3d0359..1e832c0c46 100644 --- a/tools/shell/src/shellEngine.c +++ b/tools/shell/src/shellEngine.c @@ -29,11 +29,11 @@ static void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD static int32_t shellDumpResultToFile(const char *fname, TAOS_RES *tres); static void shellPrintNChar(const char *str, int32_t length, int32_t width); static void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t length, int32_t precision); -static int32_t shellVerticalPrintResult(TAOS_RES *tres); +static int32_t shellVerticalPrintResult(TAOS_RES *tres, const char *sql); static int32_t shellCalcColWidth(TAOS_FIELD *field, int32_t precision); static void shellPrintHeader(TAOS_FIELD *fields, int32_t *width, int32_t num_fields); -static int32_t shellHorizontalPrintResult(TAOS_RES *tres); -static int32_t shellDumpResult(TAOS_RES *tres, char *fname, int32_t *error_no, bool vertical); +static int32_t shellHorizontalPrintResult(TAOS_RES *tres, const char *sql); +static int32_t shellDumpResult(TAOS_RES *tres, char *fname, int32_t *error_no, bool vertical, const char *sql); static void shellReadHistory(); static void shellWriteHistory(); static void shellPrintError(TAOS_RES *tres, int64_t st); @@ -121,7 +121,7 @@ int32_t shellRunCommand(char *command) { char quote = 0, *cmd = command; for (char c = *command++; c != 0; c = *command++) { if (c == '\\' && (*command == '\'' || *command == '"' || *command == '`')) { - command ++; + command++; continue; } @@ -190,7 +190,7 @@ void shellRunSingleCommandImp(char *command) { if (pFields != NULL) { // select and show kinds of commands int32_t error_no = 0; - int32_t numOfRows = shellDumpResult(pSql, fname, &error_no, printMode); + int32_t numOfRows = shellDumpResult(pSql, fname, &error_no, printMode, command); if (numOfRows < 0) return; et = taosGetTimestampUs(); @@ -272,6 +272,7 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i return; } + int n; char buf[TSDB_MAX_BYTES_PER_ROW]; switch (field->type) { case TSDB_DATA_TYPE_BOOL: @@ -280,20 +281,37 @@ void shellDumpFieldToFile(TdFilePtr pFile, const char *val, TAOS_FIELD *field, i case TSDB_DATA_TYPE_TINYINT: taosFprintfFile(pFile, "%d", *((int8_t *)val)); break; + case TSDB_DATA_TYPE_UTINYINT: + taosFprintfFile(pFile, "%u", *((uint8_t *)val)); + break; case TSDB_DATA_TYPE_SMALLINT: taosFprintfFile(pFile, "%d", *((int16_t *)val)); break; + case TSDB_DATA_TYPE_USMALLINT: + taosFprintfFile(pFile, "%u", *((uint16_t *)val)); + break; case TSDB_DATA_TYPE_INT: taosFprintfFile(pFile, "%d", *((int32_t *)val)); break; + case TSDB_DATA_TYPE_UINT: + taosFprintfFile(pFile, "%u", *((uint32_t *)val)); + break; case TSDB_DATA_TYPE_BIGINT: taosFprintfFile(pFile, "%" PRId64, *((int64_t *)val)); break; + case TSDB_DATA_TYPE_UBIGINT: + taosFprintfFile(pFile, "%" PRIu64, *((uint64_t *)val)); + break; case TSDB_DATA_TYPE_FLOAT: taosFprintfFile(pFile, "%.5f", GET_FLOAT_VAL(val)); break; case TSDB_DATA_TYPE_DOUBLE: - taosFprintfFile(pFile, "%.9f", GET_DOUBLE_VAL(val)); + n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.9f", length, GET_DOUBLE_VAL(val)); + if (n > TMAX(25, length)) { + taosFprintfFile(pFile, "%*.15e", length, GET_DOUBLE_VAL(val)); + } else { + taosFprintfFile(pFile, "%s", buf); + } break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: @@ -435,6 +453,7 @@ void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t return; } + int n; char buf[TSDB_MAX_BYTES_PER_ROW]; switch (field->type) { case TSDB_DATA_TYPE_BOOL: @@ -468,7 +487,12 @@ void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t printf("%*.5f", width, GET_FLOAT_VAL(val)); break; case TSDB_DATA_TYPE_DOUBLE: - printf("%*.9f", width, GET_DOUBLE_VAL(val)); + n = snprintf(buf, TSDB_MAX_BYTES_PER_ROW, "%*.9f", width, GET_DOUBLE_VAL(val)); + if (n > TMAX(25, width)) { + printf("%*.15e", width, GET_DOUBLE_VAL(val)); + } else { + printf("%s", buf); + } break; case TSDB_DATA_TYPE_BINARY: case TSDB_DATA_TYPE_NCHAR: @@ -483,7 +507,16 @@ void shellPrintField(const char *val, TAOS_FIELD *field, int32_t width, int32_t } } -int32_t shellVerticalPrintResult(TAOS_RES *tres) { +bool shellIsLimitQuery(const char *sql) { + //todo refactor + if (strcasestr(sql, " limit ") != NULL) { + return true; + } + + return false; +} + +int32_t shellVerticalPrintResult(TAOS_RES *tres, const char *sql) { TAOS_ROW row = taos_fetch_row(tres); if (row == NULL) { return 0; @@ -503,7 +536,7 @@ int32_t shellVerticalPrintResult(TAOS_RES *tres) { uint64_t resShowMaxNum = UINT64_MAX; - if (shell.args.commands == NULL && shell.args.file[0] == 0) { + if (shell.args.commands == NULL && shell.args.file[0] == 0 && !shellIsLimitQuery(sql)) { resShowMaxNum = SHELL_DEFAULT_RES_SHOW_NUM; } @@ -525,8 +558,13 @@ int32_t shellVerticalPrintResult(TAOS_RES *tres) { putchar('\n'); } } else if (showMore) { - printf("[100 Rows showed, and more rows are fetching but will not be showed. You can ctrl+c to stop or wait.]\n"); - printf("[You can add limit statement to get more or redirect results to specific file to get all.]\n"); + printf("\n"); + printf(" Notice: The result shows only the first %d rows.\n", SHELL_DEFAULT_RES_SHOW_NUM); + printf(" You can use the `LIMIT` clause to get fewer result to show.\n"); + printf(" Or use '>>' to redirect the whole set of the result to a specified file.\n"); + printf("\n"); + printf(" You can use Ctrl+C to stop the underway fetching.\n"); + printf("\n"); showMore = 0; } @@ -618,7 +656,7 @@ void shellPrintHeader(TAOS_FIELD *fields, int32_t *width, int32_t num_fields) { putchar('\n'); } -int32_t shellHorizontalPrintResult(TAOS_RES *tres) { +int32_t shellHorizontalPrintResult(TAOS_RES *tres, const char *sql) { TAOS_ROW row = taos_fetch_row(tres); if (row == NULL) { return 0; @@ -637,7 +675,7 @@ int32_t shellHorizontalPrintResult(TAOS_RES *tres) { uint64_t resShowMaxNum = UINT64_MAX; - if (shell.args.commands == NULL && shell.args.file[0] == 0) { + if (shell.args.commands == NULL && shell.args.file[0] == 0 && !shellIsLimitQuery(sql)) { resShowMaxNum = SHELL_DEFAULT_RES_SHOW_NUM; } @@ -655,8 +693,13 @@ int32_t shellHorizontalPrintResult(TAOS_RES *tres) { } putchar('\n'); } else if (showMore) { - printf("[100 Rows showed, and more rows are fetching but will not be showed. You can ctrl+c to stop or wait.]\n"); - printf("[You can add limit statement to show more or redirect results to specific file to get all.]\n"); + printf("\n"); + printf(" Notice: The result shows only the first %d rows.\n", SHELL_DEFAULT_RES_SHOW_NUM); + printf(" You can use the `LIMIT` clause to get fewer result to show.\n"); + printf(" Or use '>>' to redirect the whole set of the result to a specified file.\n"); + printf("\n"); + printf(" You can use Ctrl+C to stop the underway fetching.\n"); + printf("\n"); showMore = 0; } @@ -667,14 +710,14 @@ int32_t shellHorizontalPrintResult(TAOS_RES *tres) { return numOfRows; } -int32_t shellDumpResult(TAOS_RES *tres, char *fname, int32_t *error_no, bool vertical) { +int32_t shellDumpResult(TAOS_RES *tres, char *fname, int32_t *error_no, bool vertical, const char *sql) { int32_t numOfRows = 0; if (fname != NULL) { numOfRows = shellDumpResultToFile(fname, tres); } else if (vertical) { - numOfRows = shellVerticalPrintResult(tres); + numOfRows = shellVerticalPrintResult(tres, sql); } else { - numOfRows = shellHorizontalPrintResult(tres); + numOfRows = shellHorizontalPrintResult(tres, sql); } *error_no = taos_errno(tres); diff --git a/tools/shell/src/shellNettest.c b/tools/shell/src/shellNettest.c index 345b85d896..3355c20109 100644 --- a/tools/shell/src/shellNettest.c +++ b/tools/shell/src/shellNettest.c @@ -119,7 +119,7 @@ static void shellWorkAsServer() { memcpy(rpcInit.localFqdn, tsLocalFqdn, strlen(tsLocalFqdn)); rpcInit.localPort = pArgs->port; rpcInit.label = "CHK"; - rpcInit.numOfThreads = tsNumOfRpcThreads; + rpcInit.numOfThreads = 2; rpcInit.cfp = (RpcCfp)shellProcessMsg; rpcInit.sessions = 10; rpcInit.connType = TAOS_CONN_SERVER; diff --git a/tools/taos-tools b/tools/taos-tools index 0ae9f872c2..0aad27d725 160000 --- a/tools/taos-tools +++ b/tools/taos-tools @@ -1 +1 @@ -Subproject commit 0ae9f872c26d5da8cb61aa9eb00b5c7aeba10ec4 +Subproject commit 0aad27d725f4ee6b18daf1db0c07d933aed16eea