diff --git a/contrib/test/craft/CMakeLists.txt b/contrib/test/craft/CMakeLists.txt index e0f6ae64bd3e9c998db15c1006cebf1b15702f5b..d4d5a6365f36a084552b41e4d9198a66c8fbc24e 100644 --- a/contrib/test/craft/CMakeLists.txt +++ b/contrib/test/craft/CMakeLists.txt @@ -1,2 +1,2 @@ add_executable(simulate_vnode "simulate_vnode.c") -target_link_libraries(simulate_vnode PUBLIC craft lz4 uv_a) \ No newline at end of file +target_link_libraries(simulate_vnode craft lz4 uv_a) \ No newline at end of file diff --git a/contrib/test/traft/single_node/CMakeLists.txt b/contrib/test/traft/single_node/CMakeLists.txt index 666ce271b856d405b9b9e6e07014f69fb6b709f8..84b65978b9cfa8ed7e0bd6ce5203dd09a16d8fea 100644 --- a/contrib/test/traft/single_node/CMakeLists.txt +++ b/contrib/test/traft/single_node/CMakeLists.txt @@ -3,4 +3,4 @@ target_sources(singleNode PRIVATE "singleNode.c" ) -target_link_libraries(singleNode PUBLIC traft lz4 uv_a) +target_link_libraries(singleNode traft lz4 uv_a) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 71a9f9f4c59e288dc304bd7887f4ef454fa41284..51e1e996dc2d6f634e185a843a71bb3c24d91634 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,11 +2,7 @@ aux_source_directory(src TMQ_DEMO_SRC) add_executable(tmq ${TMQ_DEMO_SRC}) target_link_libraries( - tmq - PUBLIC taos - #PUBLIC util - #PUBLIC common - #PUBLIC os + tmq taos ) target_include_directories( tmq diff --git a/include/common/taosdef.h b/include/common/taosdef.h index 66cb0bb4ba5c48e6320455a94d5b6778c283fbe4..69c2618ac88935e37427b97fae36a4df564f73cf 100644 --- a/include/common/taosdef.h +++ b/include/common/taosdef.h @@ -51,6 +51,10 @@ typedef enum { } ECheckItemType; typedef enum { TD_ROW_DISCARD_UPDATE = 0, TD_ROW_OVERWRITE_UPDATE = 1, TD_ROW_PARTIAL_UPDATE = 2 } TDUpdateConfig; +typedef enum { + TSDB_STATIS_OK = 0, // statis part exist and load successfully + TSDB_STATIS_NONE = 1, // statis part not exist +} ETsdbStatisStatus; extern char *qtypeStr[]; diff --git a/include/common/tglobal.h b/include/common/tglobal.h index e09f6d11bdea1f3dbf5a08ab37d3086c9c1d2ed4..2261170e63a097695fc91d69f1ab3f7ebba6cc52 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -52,6 +52,13 @@ extern bool tsEnableSlaveQuery; extern bool tsPrintAuth; extern int64_t tsTickPerDay[3]; +// monitor +extern bool tsEnableMonitor; +extern int32_t tsMonitorInterval; +extern char tsMonitorFqdn[]; +extern uint16_t tsMonitorPort; +extern int32_t tsMonitorMaxLogs; + // query buffer management extern int32_t tsQueryBufferSize; // maximum allowed usage buffer size in MB for each data node during query processing extern int64_t tsQueryBufferSizeBytes; // maximum allowed usage buffer size in byte for each data node diff --git a/include/common/tmsg.h b/include/common/tmsg.h index ab0472a575d9f1fbcd0ca4542564aaafa790417d..25d668e788357b596588f1282d0b8747242ac02f 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -739,6 +739,9 @@ typedef struct { int32_t maxRows; int32_t commitTime; int32_t fsyncPeriod; + uint32_t hashBegin; + uint32_t hashEnd; + int8_t hashMethod; int8_t walLevel; int8_t precision; int8_t compression; @@ -749,6 +752,7 @@ typedef struct { int8_t selfIndex; int8_t streamMode; SReplica replicas[TSDB_MAX_REPLICA]; + } SCreateVnodeReq, SAlterVnodeReq; int32_t tSerializeSCreateVnodeReq(void* buf, int32_t bufLen, SCreateVnodeReq* pReq); diff --git a/include/common/ttime.h b/include/common/ttime.h index a4b2aa6673c4413225ff0bfdd5b58851f400d2b0..b71426e31261c15486b320dac9040ecc84324414 100644 --- a/include/common/ttime.h +++ b/include/common/ttime.h @@ -52,6 +52,8 @@ void deltaToUtcInitOnce(); int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision); +void taosFormatUtcTime(char *buf, int32_t bufLen, int64_t time, int32_t precision); + #ifdef __cplusplus } #endif diff --git a/include/dnode/mnode/mnode.h b/include/dnode/mnode/mnode.h index 2680bb83edfca41187150f3f04daf4fa7c369017..d295e772e898e62bce7e9b822309a79640368a0d 100644 --- a/include/dnode/mnode/mnode.h +++ b/include/dnode/mnode/mnode.h @@ -16,6 +16,8 @@ #ifndef _TD_MND_H_ #define _TD_MND_H_ +#include "monitor.h" + #ifdef __cplusplus extern "C" { #endif @@ -30,20 +32,6 @@ typedef int32_t (*PutReqToMWriteQFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef int32_t (*PutReqToMReadQFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); typedef void (*SendRedirectRspFp)(SDnode *pDnode, struct SRpcMsg *rpcMsg); -typedef struct SMnodeLoad { - int64_t numOfDnode; - int64_t numOfMnode; - int64_t numOfVgroup; - int64_t numOfDatabase; - int64_t numOfSuperTable; - int64_t numOfChildTable; - int64_t numOfNormalTable; - int64_t numOfColumn; - int64_t totalPoints; - int64_t totalStorage; - int64_t compStorage; -} SMnodeLoad; - typedef struct { int32_t dnodeId; int64_t clusterId; @@ -92,13 +80,16 @@ int32_t mndAlter(SMnode *pMnode, const SMnodeOpt *pOption); void mndDestroy(const char *path); /** - * @brief Get mnode statistics info. + * @brief Get mnode monitor info. * * @param pMnode The mnode object. - * @param pLoad Statistics of the mnode. + * @param pClusterInfo + * @param pVgroupInfo + * @param pGrantInfo * @return int32_t 0 for success, -1 for failure. */ -int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad); +int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo, + SMonGrantInfo *pGrantInfo); /** * @brief Get user authentication info. diff --git a/include/libs/monitor/monitor.h b/include/libs/monitor/monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..4b7c6a9bc9dd1128ad63be772766cead1a650d62 --- /dev/null +++ b/include/libs/monitor/monitor.h @@ -0,0 +1,155 @@ +/* + * 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_MONITOR_H_ +#define _TD_MONITOR_H_ + +#include "tarray.h" +#include "tdef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int32_t dnode_id; + char dnode_ep[TSDB_EP_LEN]; +} SMonBasicInfo; + +typedef struct { + int32_t dnode_id; + char dnode_ep[TSDB_EP_LEN]; + char status[8]; +} SMonDnodeDesc; + +typedef struct { + int32_t mnode_id; + char mnode_ep[TSDB_EP_LEN]; + char role[8]; +} SMonMnodeDesc; + +typedef struct { + char first_ep[TSDB_EP_LEN]; + int32_t first_ep_dnode_id; + char version[12]; + float master_uptime; // day + int32_t monitor_interval; // sec + int32_t vgroups_total; + int32_t vgroups_alive; + int32_t vnodes_total; + int32_t vnodes_alive; + int32_t connections_total; + SArray *dnodes; // array of SMonDnodeDesc + SArray *mnodes; // array of SMonMnodeDesc +} SMonClusterInfo; + +typedef struct { + int32_t dnode_id; + int8_t vnode_online; + char vnode_role[8]; +} SMonVnodeDesc; + +typedef struct { + int32_t vgroup_id; + SMonVnodeDesc vnodes[TSDB_MAX_REPLICA]; +} SMonVgroupDesc; + +typedef struct { + char database_name[TSDB_DB_NAME_LEN]; + int32_t tables_num; + int8_t status; + SArray *vgroups; // array of SMonVgroupDesc +} SMonVgroupInfo; + +typedef struct { + int32_t expire_time; + int32_t timeseries_used; + int32_t timeseries_total; +} SMonGrantInfo; + +typedef struct { + float uptime; // day + float cpu_engine; + float cpu_system; + float cpu_cores; + float mem_engine; // MB + float mem_system; // MB + float mem_total; // MB + float disk_engine; // GB + float disk_used; // GB + float disk_total; // GB + float net_in; // Kb/s + float net_out; // Kb/s + float io_read; // Mb/s + float io_write; // Mb/s + float io_read_disk; // Mb/s + float io_write_disk; // Mb/s + int32_t req_select; + float req_select_rate; + int32_t req_insert; + int32_t req_insert_success; + float req_insert_rate; + int32_t req_insert_batch; + int32_t req_insert_batch_success; + float req_insert_batch_rate; + int32_t errors; + int32_t vnodes_num; + int32_t masters; + int32_t has_mnode; +} SMonDnodeInfo; + +typedef struct { + char name[TSDB_FILENAME_LEN]; + int32_t level; + SDiskSize size; +} SMonDiskDesc; + +typedef struct { + SArray *disks; // array of SMonDiskDesc +} SMonDiskInfo; + +typedef struct { + int64_t ts; + int8_t level; + char content[1024]; +} SMonLogItem; + +typedef struct SMonInfo SMonInfo; + +typedef struct { + const char *server; + uint16_t port; + int32_t maxLogs; +} SMonCfg; + +int32_t monInit(const SMonCfg *pCfg); +void monCleanup(); +void monAddLogItem(SMonLogItem *pItem); + +SMonInfo *monCreateMonitorInfo(); +void monSetBasicInfo(SMonInfo *pMonitor, SMonBasicInfo *pInfo); +void monSetClusterInfo(SMonInfo *pMonitor, SMonClusterInfo *pInfo); +void monSetVgroupInfo(SMonInfo *pMonitor, SMonVgroupInfo *pInfo); +void monSetGrantInfo(SMonInfo *pMonitor, SMonGrantInfo *pInfo); +void monSetDnodeInfo(SMonInfo *pMonitor, SMonDnodeInfo *pInfo); +void monSetDiskInfo(SMonInfo *pMonitor, SMonDiskInfo *pInfo); +void monSendReport(SMonInfo *pMonitor); +void monCleanupMonitorInfo(SMonInfo *pMonitor); + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_MONITOR_H_*/ diff --git a/include/libs/scheduler/scheduler.h b/include/libs/scheduler/scheduler.h index e856adaf3163c40a107d27d5a9aaaf015cc733d3..b2080cb65553765ae5c547d91a8762f531b9ff7c 100644 --- a/include/libs/scheduler/scheduler.h +++ b/include/libs/scheduler/scheduler.h @@ -23,8 +23,6 @@ extern "C" { #include "catalog.h" #include "planner.h" -struct SSchJob; - typedef struct SSchedulerCfg { uint32_t maxJobNum; } SSchedulerCfg; @@ -72,7 +70,7 @@ int32_t schedulerInit(SSchedulerCfg *cfg); * @param nodeList Qnode/Vnode address list, element is SQueryNodeAddr * @return */ -int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes); +int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, int64_t *pJob, const char* sql, SQueryResult *pRes); /** * Process the query job, generated according to the query physical plan. @@ -80,7 +78,7 @@ int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, str * @param pNodeList Qnode/Vnode address list, element is SQueryNodeAddr * @return */ -int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, struct SSchJob** pJob); +int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, int64_t *pJob); /** * Fetch query result from the remote query executor @@ -88,7 +86,7 @@ int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDa * @param data * @return */ -int32_t schedulerFetchRows(struct SSchJob *pJob, void **data); +int32_t schedulerFetchRows(int64_t job, void **data); /** @@ -102,7 +100,7 @@ int32_t schedulerFetchRows(struct SSchJob *pJob, void **data); * Free the query job * @param pJob */ -void schedulerFreeJob(void *pJob); +void schedulerFreeJob(int64_t job); void schedulerDestroy(void); diff --git a/include/os/osSysinfo.h b/include/os/osSysinfo.h index 35ac032a8a65d4d530893478d7051cee2bd5565b..bf9d7662e6aed4b979142c18615a7881b289389c 100644 --- a/include/os/osSysinfo.h +++ b/include/os/osSysinfo.h @@ -42,7 +42,6 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage); bool taosGetTotalSysMemoryKB(uint64_t *kb); bool taosGetProcMemory(float *memoryUsedMB); // bool taosGetSysMemory(float *memoryUsedMB); // -void taosGetDisk(); int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize); bool taosReadProcIO(int64_t *rchars, int64_t *wchars); bool taosGetProcIO(float *readKB, float *writeKB); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 79909a569606758f9adc33a036881830fab6ffa7..c93ea1aabee2c0b509a919a760618608b4c7bd35 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -171,7 +171,7 @@ typedef struct SRequestSendRecvBody { void* fp; SShowReqInfo showInfo; // todo this attribute will be removed after the query framework being completed. SDataBuf requestMsg; - struct SSchJob* pQueryJob; // query job, created according to sql query DAG. + int64_t queryJob; // query job, created according to sql query DAG. struct SQueryDag* pDag; // the query dag, generated according to the sql statement. SReqResultInfo resInfo; } SRequestSendRecvBody; diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 3c6a49c3db25cbcc4a7b5f76d6081728a5a6f129..a0ba668f8a5ed9acea98fa3c7c3808bc1748fe51 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -227,10 +227,10 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag, SArray* pNodeList) { void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter; SQueryResult res = {.code = 0, .numOfRows = 0, .msgSize = ERROR_MSG_BUF_DEFAULT_SIZE, .msg = pRequest->msgBuf}; - int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.pQueryJob, pRequest->sqlstr, &res); + int32_t code = schedulerExecJob(pTransporter, pNodeList, pDag, &pRequest->body.queryJob, pRequest->sqlstr, &res); if (code != TSDB_CODE_SUCCESS) { - if (pRequest->body.pQueryJob != NULL) { - schedulerFreeJob(pRequest->body.pQueryJob); + if (pRequest->body.queryJob != 0) { + schedulerFreeJob(pRequest->body.queryJob); } pRequest->code = code; @@ -240,8 +240,8 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryDag* pDag, SArray* pNodeList) if (TSDB_SQL_INSERT == pRequest->type || TSDB_SQL_CREATE_TABLE == pRequest->type) { pRequest->body.resInfo.numOfRows = res.numOfRows; - if (pRequest->body.pQueryJob != NULL) { - schedulerFreeJob(pRequest->body.pQueryJob); + if (pRequest->body.queryJob != 0) { + schedulerFreeJob(pRequest->body.queryJob); } } @@ -494,7 +494,7 @@ void* doFetchRow(SRequestObj* pRequest) { } SReqResultInfo* pResInfo = &pRequest->body.resInfo; - int32_t code = schedulerFetchRows(pRequest->body.pQueryJob, (void**)&pResInfo->pData); + int32_t code = schedulerFetchRows(pRequest->body.queryJob, (void**)&pResInfo->pData); if (code != TSDB_CODE_SUCCESS) { pRequest->code = code; return NULL; diff --git a/source/common/CMakeLists.txt b/source/common/CMakeLists.txt index 04e5a36e863e4b27007afffdfa17883b726c0598..1e4ad95504e18dd2bf1dbc337f73156c8926e8c0 100644 --- a/source/common/CMakeLists.txt +++ b/source/common/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src COMMON_SRC) -add_library(common ${COMMON_SRC}) +add_library(common STATIC ${COMMON_SRC}) target_include_directories( common PUBLIC "${CMAKE_SOURCE_DIR}/include/common" diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index d66895888b60d4c7d265079513ab5415b3ed9507..5998b7c9ce62938df64715b2f6666ab2f01b3c38 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -46,6 +46,13 @@ int32_t tsMaxBinaryDisplayWidth = 30; bool tsEnableSlaveQuery = 1; bool tsPrintAuth = 0; +// monitor +bool tsEnableMonitor = 1; +int32_t tsMonitorInterval = 5; +char tsMonitorFqdn[TSDB_FQDN_LEN] = {0}; +uint16_t tsMonitorPort = 6043; +int32_t tsMonitorMaxLogs = 100; + /* * denote if the server needs to compress response message at the application layer to client, including query rsp, * metricmeta rsp, and multi-meter query rsp message body. The client compress the submit message to server. @@ -314,6 +321,13 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "printAuth", tsPrintAuth, 0) != 0) return -1; if (cfgAddBool(pCfg, "slaveQuery", tsEnableSlaveQuery, 0) != 0) return -1; if (cfgAddBool(pCfg, "deadLockKillQuery", tsDeadLockKillQuery, 0) != 0) return -1; + + if (cfgAddBool(pCfg, "monitor", tsEnableMonitor, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "monitorInterval", tsMonitorInterval, 1, 360000, 0) != 0) return -1; + if (cfgAddString(pCfg, "monitorFqdn", tsMonitorFqdn, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "monitorPort", tsMonitorPort, 1, 65056, 0) != 0) return -1; + if (cfgAddInt32(pCfg, "monitorMaxLogs", tsMonitorMaxLogs, 1, 1000000, 0) != 0) return -1; + return 0; } @@ -345,7 +359,7 @@ static void taosSetServerLogCfg(SConfig *pCfg) { } static void taosSetClientCfg(SConfig *pCfg) { - tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_EP_LEN); + tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN); tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32; snprintf(tsLocalEp, sizeof(tsLocalEp), "%s:%u", tsLocalFqdn, tsServerPort); @@ -425,6 +439,12 @@ static void taosSetServerCfg(SConfig *pCfg) { tsEnableSlaveQuery = cfgGetItem(pCfg, "slaveQuery")->bval; tsDeadLockKillQuery = cfgGetItem(pCfg, "deadLockKillQuery")->bval; + tsEnableMonitor = cfgGetItem(pCfg, "monitor")->bval; + tsMonitorInterval = cfgGetItem(pCfg, "monitorInterval")->i32; + tstrncpy(tsMonitorFqdn, cfgGetItem(pCfg, "monitorFqdn")->str, TSDB_FQDN_LEN); + tsMonitorPort = (uint16_t)cfgGetItem(pCfg, "monitorPort")->i32; + tsMonitorMaxLogs = cfgGetItem(pCfg, "monitorMaxLogs")->i32; + if (tsQueryBufferSize >= 0) { tsQueryBufferSizeBytes = tsQueryBufferSize * 1048576UL; } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index d8c850c6afa9588c21f3151f07513e0268a918a8..ae31dff3109cf732e165d68d7f6d9bb196a381a3 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -2112,6 +2112,9 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR if (tEncodeI32(&encoder, pReq->maxRows) < 0) return -1; if (tEncodeI32(&encoder, pReq->commitTime) < 0) return -1; if (tEncodeI32(&encoder, pReq->fsyncPeriod) < 0) return -1; + if (tEncodeU32(&encoder, pReq->hashBegin) < 0) return -1; + if (tEncodeU32(&encoder, pReq->hashEnd) < 0) return -1; + if (tEncodeI8(&encoder, pReq->hashMethod) < 0) return -1; if (tEncodeI8(&encoder, pReq->walLevel) < 0) return -1; if (tEncodeI8(&encoder, pReq->precision) < 0) return -1; if (tEncodeI8(&encoder, pReq->compression) < 0) return -1; @@ -2152,6 +2155,9 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq * if (tDecodeI32(&decoder, &pReq->maxRows) < 0) return -1; if (tDecodeI32(&decoder, &pReq->commitTime) < 0) return -1; if (tDecodeI32(&decoder, &pReq->fsyncPeriod) < 0) return -1; + if (tDecodeU32(&decoder, &pReq->hashBegin) < 0) return -1; + if (tDecodeU32(&decoder, &pReq->hashEnd) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->hashMethod) < 0) return -1; if (tDecodeI8(&decoder, &pReq->walLevel) < 0) return -1; if (tDecodeI8(&decoder, &pReq->precision) < 0) return -1; if (tDecodeI8(&decoder, &pReq->compression) < 0) return -1; diff --git a/source/common/src/tname.c b/source/common/src/tname.c index e061862856702c8015470afb496bd5e6734e49b6..fb77417cacada36969672621fa78daff8ed29ebb 100644 --- a/source/common/src/tname.c +++ b/source/common/src/tname.c @@ -22,6 +22,7 @@ bool tscValidateTableNameLength(size_t len) { return len < TSDB_TABLE_NAME_LEN; } +#if 0 // TODO refactor SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters) { if (numOfFilters == 0 || src == NULL) { @@ -46,7 +47,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil return pFilter; } - +#endif #if 0 int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t slidingTime, int64_t intervalTime, char timeUnit, int16_t precision) { if (slidingTime == 0) { diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index 460c4a6fc08ea07b77a9feec970a87be501e7fd7..7a318c2eb8debb2857787dec5c97662b949c3183 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -627,3 +627,50 @@ const char* fmtts(int64_t ts) { return buf; } + +void taosFormatUtcTime(char* buf, int32_t bufLen, int64_t t, int32_t precision) { + char ts[40] = {0}; + struct tm* ptm; + + int32_t fractionLen; + char* format = NULL; + time_t quot = 0; + long mod = 0; + + switch (precision) { + case TSDB_TIME_PRECISION_MILLI: { + quot = t / 1000; + fractionLen = 5; + format = ".%03" PRId64; + mod = t % 1000; + break; + } + + case TSDB_TIME_PRECISION_MICRO: { + quot = t / 1000000; + fractionLen = 8; + format = ".%06" PRId64; + mod = t % 1000000; + break; + } + + case TSDB_TIME_PRECISION_NANO: { + quot = t / 1000000000; + fractionLen = 11; + format = ".%09" PRId64; + mod = t % 1000000000; + break; + } + + default: + fractionLen = 0; + assert(false); + } + + ptm = localtime("); + int32_t length = (int32_t)strftime(ts, 40, "%Y-%m-%dT%H:%M:%S", ptm); + length += snprintf(ts + length, fractionLen, format, mod); + length += (int32_t)strftime(ts + length, 40 - length, "%z", ptm); + + tstrncpy(buf, ts, bufLen); +} \ No newline at end of file diff --git a/source/dnode/bnode/CMakeLists.txt b/source/dnode/bnode/CMakeLists.txt index a284437450bce68edc6142ae346022fb3bf27bb6..f51969f6bf23b9b4951d3d0dfbf5cc93e5ce18bd 100644 --- a/source/dnode/bnode/CMakeLists.txt +++ b/source/dnode/bnode/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src BNODE_SRC) -add_library(bnode ${BNODE_SRC}) +add_library(bnode STATIC ${BNODE_SRC}) target_include_directories( bnode PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/bnode" diff --git a/source/dnode/mgmt/daemon/CMakeLists.txt b/source/dnode/mgmt/daemon/CMakeLists.txt index e07c15c95a3bc9b4fee58255a9174472732684fe..3238bbf3f07279e590350d060bb1a8d4ad47c7ef 100644 --- a/source/dnode/mgmt/daemon/CMakeLists.txt +++ b/source/dnode/mgmt/daemon/CMakeLists.txt @@ -6,4 +6,4 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) -target_link_libraries(taosd dnode util os) +target_link_libraries(taosd dnode) diff --git a/source/dnode/mgmt/impl/CMakeLists.txt b/source/dnode/mgmt/impl/CMakeLists.txt index 171f9649fb97b4968c642fadfbd42f5f44e35080..c99a4055274f274f87cb030fa07a20263d67f88d 100644 --- a/source/dnode/mgmt/impl/CMakeLists.txt +++ b/source/dnode/mgmt/impl/CMakeLists.txt @@ -1,17 +1,7 @@ aux_source_directory(src DNODE_SRC) add_library(dnode STATIC ${DNODE_SRC}) target_link_libraries( - dnode - PUBLIC cjson - PUBLIC mnode - PUBLIC vnode - PUBLIC qnode - PUBLIC snode - PUBLIC bnode - PUBLIC wal - PUBLIC sync - PUBLIC taos - PUBLIC tfs + dnode cjson mnode vnode qnode snode bnode wal sync taos tfs monitor ) target_include_directories( dnode diff --git a/source/dnode/mgmt/impl/inc/dndInt.h b/source/dnode/mgmt/impl/inc/dndInt.h index 417bc1e0411b4e185d7602aea9e02735ef1a1027..9fabe40186d7a15b117901f2652522fa72cd91ef 100644 --- a/source/dnode/mgmt/impl/inc/dndInt.h +++ b/source/dnode/mgmt/impl/inc/dndInt.h @@ -36,6 +36,7 @@ extern "C" { #include "ttime.h" #include "tworker.h" #include "tglobal.h" +#include "monitor.h" #include "dnode.h" diff --git a/source/dnode/mgmt/impl/inc/dndMnode.h b/source/dnode/mgmt/impl/inc/dndMnode.h index dafbae10ad589fff719c6311c7be707f69d698b9..0f03bb3832fb7c66bf651bdec18ec6ca196643d9 100644 --- a/source/dnode/mgmt/impl/inc/dndMnode.h +++ b/source/dnode/mgmt/impl/inc/dndMnode.h @@ -32,6 +32,9 @@ int32_t dndProcessCreateMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg); int32_t dndProcessAlterMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg); int32_t dndProcessDropMnodeReq(SDnode *pDnode, SRpcMsg *pRpcMsg); +int32_t dndGetMnodeMonitorInfo(SDnode *pDnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo, + SMonGrantInfo *pGrantInfo); + #ifdef __cplusplus } #endif diff --git a/source/dnode/mgmt/impl/src/dndEnv.c b/source/dnode/mgmt/impl/src/dndEnv.c index 9467b56e6b58982980c5668b2a95eea78b1f666a..2539443b41e0d2bd49d9f38b1e909165f85fdcb1 100644 --- a/source/dnode/mgmt/impl/src/dndEnv.c +++ b/source/dnode/mgmt/impl/src/dndEnv.c @@ -21,6 +21,7 @@ #include "dndSnode.h" #include "dndTransport.h" #include "dndVnodes.h" +#include "monitor.h" #include "sync.h" #include "tfs.h" #include "wal.h" @@ -140,7 +141,7 @@ static int32_t dndInitDir(SDnode *pDnode, SDnodeObjCfg *pCfg) { return 0; } -static void dndCloseImp(SDnode *pDnode) { +static void dndCloseDir(SDnode *pDnode) { tfree(pDnode->dir.mnode); tfree(pDnode->dir.vnodes); tfree(pDnode->dir.dnode); @@ -260,7 +261,7 @@ void dndClose(SDnode *pDnode) { dndCleanupMgmt(pDnode); tfsClose(pDnode->pTfs); - dndCloseImp(pDnode); + dndCloseDir(pDnode); free(pDnode); dInfo("dnode object is closed, data:%p", pDnode); } @@ -289,11 +290,7 @@ int32_t dndInit() { } SVnodeOpt vnodeOpt = { - .sver = tsVersion, - .nthreads = tsNumOfCommitThreads, - .putReqToVQueryQFp = dndPutReqToVQueryQ, - .sendReqToDnodeFp = dndSendReqToDnode - }; + .nthreads = tsNumOfCommitThreads, .putReqToVQueryQFp = dndPutReqToVQueryQ, .sendReqToDnodeFp = dndSendReqToDnode}; if (vnodeInit(&vnodeOpt) != 0) { dError("failed to init vnode since %s", terrstr()); @@ -301,6 +298,13 @@ int32_t dndInit() { return -1; } + SMonCfg monCfg = {.maxLogs = tsMonitorMaxLogs, .port = tsMonitorPort, .server = tsMonitorFqdn}; + if (monInit(&monCfg) != 0) { + dError("failed to init monitor since %s", terrstr()); + dndCleanup(); + return -1; + } + dInfo("dnode env is initialized"); return 0; } @@ -314,19 +318,8 @@ void dndCleanup() { walCleanUp(); vnodeCleanup(); rpcCleanup(); + monCleanup(); taosStopCacheRefreshWorker(); dInfo("dnode env is cleaned up"); } - -// OTHER FUNCTIONS =================================== -void taosGetDisk() { -#if 0 - const double unit = 1024 * 1024 * 1024; - - SDiskSize diskSize = tfsGetSize(pTfs); - - tfsUpdateSize(&fsMeta); - -#endif -} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/src/dndMgmt.c b/source/dnode/mgmt/impl/src/dndMgmt.c index 8f18222ab663e27f6e022d8a080ba0147e7750fb..4bf8b8204303eb9c1849b63603073df7bd2e9811 100644 --- a/source/dnode/mgmt/impl/src/dndMgmt.c +++ b/source/dnode/mgmt/impl/src/dndMgmt.c @@ -22,6 +22,7 @@ #include "dndTransport.h" #include "dndVnodes.h" #include "dndWorker.h" +#include "monitor.h" static void dndProcessMgmtQueue(SDnode *pDnode, SRpcMsg *pMsg); @@ -473,19 +474,62 @@ void dndProcessStartupReq(SDnode *pDnode, SRpcMsg *pReq) { rpcSendResponse(&rpcRsp); } +void dndGetBasicInfo(SDnode *pDnode, SMonBasicInfo *pInfo) { + pInfo->dnode_id = dndGetDnodeId(pDnode); + tstrncpy(pInfo->dnode_ep, tsLocalEp, TSDB_EP_LEN); +} + +static void dndSendMonitorReport(SDnode *pDnode) { + if (!tsEnableMonitor || tsMonitorFqdn[0] == 0) return; + SMonInfo *pMonitor = monCreateMonitorInfo(); + if (pMonitor == NULL) return; + + dTrace("pDnode:%p, send monitor report to %s:%u", pDnode, tsMonitorFqdn, tsMonitorPort); + + SMonBasicInfo basicInfo = {0}; + dndGetBasicInfo(pDnode, &basicInfo); + monSetBasicInfo(pMonitor, &basicInfo); + + SMonClusterInfo clusterInfo = {0}; + SMonVgroupInfo vgroupInfo = {0}; + SMonGrantInfo grantInfo = {0}; + if (dndGetMnodeMonitorInfo(pDnode, &clusterInfo, &vgroupInfo, &grantInfo) == 0) { + monSetClusterInfo(pMonitor, &clusterInfo); + monSetVgroupInfo(pMonitor, &vgroupInfo); + monSetGrantInfo(pMonitor, &grantInfo); + } + + monSendReport(pMonitor); + monCleanupMonitorInfo(pMonitor); +} + static void *dnodeThreadRoutine(void *param) { SDnode *pDnode = param; SDnodeMgmt *pMgmt = &pDnode->dmgmt; - int32_t ms = tsStatusInterval * 1000; + int64_t lastStatusTime = taosGetTimestampMs(); + int64_t lastMonitorTime = lastStatusTime; setThreadName("dnode-hb"); while (true) { pthread_testcancel(); - taosMsleep(ms); + taosMsleep(200); + if (dndGetStat(pDnode) != DND_STAT_RUNNING || pMgmt->dropped) { + continue; + } - if (dndGetStat(pDnode) == DND_STAT_RUNNING && !pMgmt->statusSent && !pMgmt->dropped) { + int64_t curTime = taosGetTimestampMs(); + + float statusInterval = (curTime - lastStatusTime) / 1000.0f; + if (statusInterval >= tsStatusInterval && !pMgmt->statusSent) { dndSendStatusReq(pDnode); + lastStatusTime = curTime; + } + + float monitorInterval = (curTime - lastMonitorTime) / 1000.0f; + if (monitorInterval >= tsMonitorInterval) { + dndSendMonitorReport(pDnode); + lastMonitorTime = curTime; } } } diff --git a/source/dnode/mgmt/impl/src/dndMnode.c b/source/dnode/mgmt/impl/src/dndMnode.c index e1b16a188fd0fb826e67cce952ad024229a4b0de..6cb117867fddd0d713d2493d0e7d83f9337d04a2 100644 --- a/source/dnode/mgmt/impl/src/dndMnode.c +++ b/source/dnode/mgmt/impl/src/dndMnode.c @@ -630,3 +630,13 @@ int32_t dndGetUserAuthFromMnode(SDnode *pDnode, char *user, char *spi, char *enc dTrace("user:%s, retrieve auth spi:%d encrypt:%d", user, *spi, *encrypt); return code; } + +int32_t dndGetMnodeMonitorInfo(SDnode *pDnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo, + SMonGrantInfo *pGrantInfo) { + SMnode *pMnode = dndAcquireMnode(pDnode); + if (pMnode == NULL) return -1; + + int32_t code = mndGetMonitorInfo(pMnode, pClusterInfo, pVgroupInfo, pGrantInfo); + dndReleaseMnode(pDnode, pMnode); + return code; +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/src/dndVnodes.c b/source/dnode/mgmt/impl/src/dndVnodes.c index f20493aa7ffae8c9a2f3c2119e645bd46389f682..2767461f1201531222ea8fbfae5408832112ecb8 100644 --- a/source/dnode/mgmt/impl/src/dndVnodes.c +++ b/source/dnode/mgmt/impl/src/dndVnodes.c @@ -523,6 +523,9 @@ static void dndGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) { pCfg->walCfg.rollPeriod = 128; pCfg->walCfg.segSize = 128; pCfg->walCfg.vgId = pCreate->vgId; + pCfg->hashBegin = pCreate->hashBegin; + pCfg->hashEnd = pCreate->hashEnd; + pCfg->hashMethod = pCreate->hashMethod; } static void dndGenerateWrapperCfg(SDnode *pDnode, SCreateVnodeReq *pCreate, SWrapperCfg *pCfg) { diff --git a/source/dnode/mgmt/impl/test/sut/CMakeLists.txt b/source/dnode/mgmt/impl/test/sut/CMakeLists.txt index d20c680fad3066e03a0ba6d93ab577b48e959755..3a993986fe6e7ae08b4c9c9bf308a1828a500df7 100644 --- a/source/dnode/mgmt/impl/test/sut/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/sut/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src SUT_SRC) -add_library(sut STATIC ${SUT_SRC}) +add_library(sut STATIC STATIC ${SUT_SRC}) target_link_libraries( sut PUBLIC dnode diff --git a/source/dnode/mnode/impl/CMakeLists.txt b/source/dnode/mnode/impl/CMakeLists.txt index 3aad002d4054bb0158d77ffb16bce4b20b958a99..514bba19f48cf1625c9d4b74c8aabb6a296ace15 100644 --- a/source/dnode/mnode/impl/CMakeLists.txt +++ b/source/dnode/mnode/impl/CMakeLists.txt @@ -1,18 +1,12 @@ aux_source_directory(src MNODE_SRC) -add_library(mnode ${MNODE_SRC}) +add_library(mnode STATIC ${MNODE_SRC}) target_include_directories( mnode PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/mnode" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mnode - PRIVATE scheduler - PRIVATE sdb - PRIVATE wal - PRIVATE transport - PRIVATE cjson - PRIVATE sync + mnode scheduler sdb wal transport cjson sync monitor ) if(${BUILD_TEST}) diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index 54595fb10533bdd3942688a450a17b0eacf6b6b2..929d47184bf8d9805ce56771ba6ef88925dfdbd2 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -21,11 +21,11 @@ #include "sdb.h" #include "tcache.h" #include "tep.h" +#include "tglobal.h" #include "tqueue.h" #include "ttime.h" -#include "wal.h" #include "version.h" -#include "tglobal.h" +#include "wal.h" #ifdef __cplusplus extern "C" { @@ -38,6 +38,20 @@ typedef int32_t (*ShowMetaFp)(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaRsp *p typedef int32_t (*ShowRetrieveFp)(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int32_t rows); typedef void (*ShowFreeIterFp)(SMnode *pMnode, void *pIter); +typedef struct SMnodeLoad { + int64_t numOfDnode; + int64_t numOfMnode; + int64_t numOfVgroup; + int64_t numOfDatabase; + int64_t numOfSuperTable; + int64_t numOfChildTable; + int64_t numOfNormalTable; + int64_t numOfColumn; + int64_t totalPoints; + int64_t totalStorage; + int64_t compStorage; +} SMnodeLoad; + typedef struct { const char *name; MndInitFp initFp; @@ -104,7 +118,9 @@ int32_t mndSendReqToMnode(SMnode *pMnode, SRpcMsg *pMsg); void mndSendRedirectRsp(SMnode *pMnode, SRpcMsg *pMsg); void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp); -uint64_t mndGenerateUid(char *name, int32_t len) ; +uint64_t mndGenerateUid(char *name, int32_t len); + +int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index b437b444177d5594c2c637b2741fe367b0305674..f7b177f170daa28f499d7b8a8d9fd22fcc98562c 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -215,6 +215,9 @@ void *mndBuildCreateVnodeReq(SMnode *pMnode, SDnodeObj *pDnode, SDbObj *pDb, SVg createReq.replica = pVgroup->replica; createReq.selfIndex = -1; createReq.streamMode = pVgroup->streamMode; + createReq.hashBegin = pVgroup->hashBegin; + createReq.hashEnd = pVgroup->hashEnd; + createReq.hashMethod = pDb->hashMethod; for (int32_t v = 0; v < pVgroup->replica; ++v) { SReplica *pReplica = &createReq.replicas[v]; diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index 90d66a80fdc943837b6e990164552de43f4b1272..c95857a2d4d8e418a0e23484b6ae6a20e5ac9205 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -22,6 +22,7 @@ #include "mndDb.h" #include "mndDnode.h" #include "mndFunc.h" +#include "mndInfoSchema.h" #include "mndMnode.h" #include "mndOffset.h" #include "mndProfile.h" @@ -36,7 +37,6 @@ #include "mndTrans.h" #include "mndUser.h" #include "mndVgroup.h" -#include "mndInfoSchema.h" #define MQ_TIMER_MS 3000 #define TRNAS_TIMER_MS 6000 @@ -400,6 +400,11 @@ int32_t mndGetLoad(SMnode *pMnode, SMnodeLoad *pLoad) { return 0; } +int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo, + SMonGrantInfo *pGrantInfo) { + return 0; + } + SMnodeMsg *mndInitMsg(SMnode *pMnode, SRpcMsg *pRpcMsg) { SMnodeMsg *pMsg = taosAllocateQitem(sizeof(SMnodeMsg)); if (pMsg == NULL) { @@ -505,10 +510,9 @@ void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp) { } } - // Note: uid 0 is reserved uint64_t mndGenerateUid(char *name, int32_t len) { - int32_t hashval = MurmurHash3_32(name, len); + int32_t hashval = MurmurHash3_32(name, len); do { int64_t us = taosGetTimestampUs(); diff --git a/source/dnode/mnode/sdb/CMakeLists.txt b/source/dnode/mnode/sdb/CMakeLists.txt index b6620f8be480f8ce81606b45f2610d6d36cb64f9..168d5063c2ace0c5cf3c675f78347053abcb482a 100644 --- a/source/dnode/mnode/sdb/CMakeLists.txt +++ b/source/dnode/mnode/sdb/CMakeLists.txt @@ -1,13 +1,10 @@ aux_source_directory(src MNODE_SRC) -add_library(sdb ${MNODE_SRC}) +add_library(sdb STATIC ${MNODE_SRC}) target_include_directories( sdb PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/mnode/sdb" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - sdb - PRIVATE os - PRIVATE common - PRIVATE util + sdb os common util ) \ No newline at end of file diff --git a/source/dnode/qnode/CMakeLists.txt b/source/dnode/qnode/CMakeLists.txt index f6f78f7357f7e769b1d0b12325c1a4852c4bcc6c..92cd8fcb5ce166b7318b6750277802bca421f986 100644 --- a/source/dnode/qnode/CMakeLists.txt +++ b/source/dnode/qnode/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src QNODE_SRC) -add_library(qnode ${QNODE_SRC}) +add_library(qnode STATIC ${QNODE_SRC}) target_include_directories( qnode PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/qnode" diff --git a/source/dnode/snode/CMakeLists.txt b/source/dnode/snode/CMakeLists.txt index a94dd9edd8055a330d5ff733e9804942dc4f3ef8..dafd5d659416b04f027e85aa33122c6371e6d153 100644 --- a/source/dnode/snode/CMakeLists.txt +++ b/source/dnode/snode/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src SNODE_SRC) -add_library(snode ${SNODE_SRC}) +add_library(snode STATIC ${SNODE_SRC}) target_include_directories( snode PUBLIC "${CMAKE_SOURCE_DIR}/include/dnode/snode" diff --git a/source/dnode/vnode/inc/tsdb.h b/source/dnode/vnode/inc/tsdb.h index 677ca9c3367a85045318bd1d09f75d0fa725f188..6bc89ddd66e919afb642bc6db47ffe269719e007 100644 --- a/source/dnode/vnode/inc/tsdb.h +++ b/source/dnode/vnode/inc/tsdb.h @@ -27,12 +27,12 @@ extern "C" { typedef struct SDataStatis { int16_t colId; - int64_t sum; - int64_t max; - int64_t min; int16_t maxIndex; int16_t minIndex; int16_t numOfNull; + int64_t sum; + int64_t max; + int64_t min; } SDataStatis; typedef struct STable { @@ -53,6 +53,8 @@ typedef struct STsdb STsdb; typedef struct STsdbCfg { int8_t precision; + int8_t update; + int8_t compression; uint64_t lruCacheSize; int32_t daysPerFile; int32_t minRowsPerFileBlock; @@ -60,8 +62,6 @@ typedef struct STsdbCfg { int32_t keep; int32_t keep1; int32_t keep2; - int8_t update; - int8_t compression; } STsdbCfg; // query condition to build multi-table data block iterator diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 31f04e840ac2a82fc95dac80461cd5efb5c07d27..7718e0886da0fc72418a1cf6569f65def57719ac 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -57,13 +57,12 @@ typedef struct { SMetaCfg metaCfg; STqCfg tqCfg; SWalCfg walCfg; + uint32_t hashBegin; + uint32_t hashEnd; + int8_t hashMethod; } SVnodeCfg; typedef struct { - int32_t sver; - const char *timezone; - const char *locale; - const char *charset; uint16_t nthreads; // number of commit threads. 0 for no threads and a schedule queue should be given (TODO) PutReqToVQueryQFp putReqToVQueryQFp; SendReqToDnodeFp sendReqToDnodeFp; diff --git a/source/dnode/vnode/src/inc/tsdbFS.h b/source/dnode/vnode/src/inc/tsdbFS.h index af432aa9d9f836ada62d6ff59c7cd9566b145336..dab697ce8bd39ea9c7497dd73e08bd94b553fffa 100644 --- a/source/dnode/vnode/src/inc/tsdbFS.h +++ b/source/dnode/vnode/src/inc/tsdbFS.h @@ -18,8 +18,6 @@ #include "tsdbFile.h" -#define TSDB_FS_VERSION 0 - // ================== TSDB global config extern bool tsdbForceKeepFile; diff --git a/source/dnode/vnode/src/inc/tsdbFile.h b/source/dnode/vnode/src/inc/tsdbFile.h index 15c8d512d6d54beca9871da0021b5881e4a5a1f9..bbeb6c6a0f70b241a6857df29141bdd4400349ba 100644 --- a/source/dnode/vnode/src/inc/tsdbFile.h +++ b/source/dnode/vnode/src/inc/tsdbFile.h @@ -44,7 +44,37 @@ #define TSDB_FILE_IS_OK(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_OK) #define TSDB_FILE_IS_BAD(tf) (TSDB_FILE_STATE(tf) == TSDB_FILE_STATE_BAD) -typedef enum { TSDB_FILE_HEAD = 0, TSDB_FILE_DATA, TSDB_FILE_LAST, TSDB_FILE_MAX, TSDB_FILE_META } TSDB_FILE_T; +typedef enum { + TSDB_FILE_HEAD = 0, // .head + TSDB_FILE_DATA, // .data + TSDB_FILE_LAST, // .last + TSDB_FILE_SMAD, // .smad(Block-wise SMA) + TSDB_FILE_SMAL, // .smal(Block-wise SMA) + TSDB_FILE_MAX, // + TSDB_FILE_META, // meta + TSDB_FILE_TSMA, // .tsma.${sma_index_name}, Time-range-wise SMA + TSDB_FILE_RSMA, // .rsma.${sma_index_name}, Time-range-wise Rollup SMA +} TSDB_FILE_T; + +typedef enum { + TSDB_FS_VER_0 = 0, + TSDB_FS_VER_MAX, +} ETsdbFsVer; + +#define TSDB_LATEST_FVER TSDB_FS_VER_0 // latest version for DFile +#define TSDB_LATEST_SFS_VER TSDB_FS_VER_0 // latest version for 'current' file + +static FORCE_INLINE uint32_t tsdbGetDFSVersion(TSDB_FILE_T fType) { // latest version for DFile + switch (fType) { + case TSDB_FILE_HEAD: // .head + case TSDB_FILE_DATA: // .data + case TSDB_FILE_LAST: // .last + case TSDB_FILE_SMAD: // .smad(Block-wise SMA) + case TSDB_FILE_SMAL: // .smal(Block-wise SMA) + default: + return TSDB_LATEST_FVER; + } +} #if 0 // =============== SMFile @@ -169,6 +199,7 @@ static FORCE_INLINE int64_t tsdbReadMFile(SMFile* pMFile, void* buf, int64_t nby // =============== SDFile typedef struct { uint32_t magic; + uint32_t fver; uint32_t len; uint32_t totalBlocks; uint32_t totalSubBlocks; @@ -188,7 +219,7 @@ void tsdbInitDFile(STsdb *pRepo, SDFile* pDFile, SDiskID did, int fid, uint32_t void tsdbInitDFileEx(SDFile* pDFile, SDFile* pODFile); int tsdbEncodeSDFile(void** buf, SDFile* pDFile); void* tsdbDecodeSDFile(STsdb *pRepo, void* buf, SDFile* pDFile); -int tsdbCreateDFile(STsdb *pRepo, SDFile* pDFile, bool updateHeader); +int tsdbCreateDFile(STsdb *pRepo, SDFile* pDFile, bool updateHeader, TSDB_FILE_T fType); int tsdbUpdateDFileHeader(SDFile* pDFile); int tsdbLoadDFileHeader(SDFile* pDFile, SDFInfo* pInfo); int tsdbParseDFilename(const char* fname, int* vid, int* fid, TSDB_FILE_T* ftype, uint32_t* version); @@ -292,12 +323,18 @@ static FORCE_INLINE int tsdbCopyDFile(SDFile* pSrc, SDFile* pDest) { // =============== SDFileSet typedef struct { - int fid; - int state; - SDFile files[TSDB_FILE_MAX]; + int fid; + int8_t state; // -128~127 + uint8_t ver; // 0~255, DFileSet version + uint16_t reserve; + SDFile files[TSDB_FILE_MAX]; } SDFileSet; +#define TSDB_LATEST_FSET_VER 0 + #define TSDB_FSET_FID(s) ((s)->fid) +#define TSDB_FSET_STATE(s) ((s)->state) +#define TSDB_FSET_VER(s) ((s)->ver) #define TSDB_DFILE_IN_SET(s, t) ((s)->files + (t)) #define TSDB_FSET_LEVEL(s) TSDB_FILE_LEVEL(TSDB_DFILE_IN_SET(s, 0)) #define TSDB_FSET_ID(s) TSDB_FILE_ID(TSDB_DFILE_IN_SET(s, 0)) diff --git a/source/dnode/vnode/src/inc/tsdbReadImpl.h b/source/dnode/vnode/src/inc/tsdbReadImpl.h index 8ecb4e4a6ebe7a8b15a7eeef8cb6d48e5eb8d889..16eb55967caac0697b2b35088b9b4473c86ba8a2 100644 --- a/source/dnode/vnode/src/inc/tsdbReadImpl.h +++ b/source/dnode/vnode/src/inc/tsdbReadImpl.h @@ -36,6 +36,7 @@ typedef struct { TSKEY maxKey; } SBlockIdx; +#ifdef TD_REFACTOR_3 typedef struct { int64_t last : 1; int64_t offset : 63; @@ -49,22 +50,35 @@ typedef struct { TSKEY keyLast; } SBlock; +#else + +typedef enum { + TSDB_SBLK_VER_0 = 0, + TSDB_SBLK_VER_MAX, +} ESBlockVer; + +#define SBlockVerLatest TSDB_SBLK_VER_0 + typedef struct { - int64_t last : 1; - int64_t offset : 63; - int32_t algorithm : 8; - int32_t numOfRows : 24; - uint8_t reserve0; + uint8_t last : 1; + uint8_t blkVer : 7; uint8_t numOfSubBlocks; int16_t numOfCols; // not including timestamp column - uint32_t len : 32; // data block length + uint32_t len; // data block length uint32_t keyLen : 24; // key column length, keyOffset = offset+sizeof(SBlockData)+sizeof(SBlockCol)*numOfCols - uint32_t reserve1 : 8; - uint64_t blkVer : 8; - uint64_t aggrOffset : 56; + uint32_t reserve : 8; + int32_t algorithm : 8; + int32_t numOfRows : 24; + int64_t offset; + uint64_t aggrStat : 1; + uint64_t aggrOffset : 63; TSKEY keyFirst; TSKEY keyLast; -} SBlock_3; +} SBlockV0; + +#define SBlock SBlockV0 // latest SBlock definition + +#endif typedef struct { int32_t delimiter; // For recovery usage @@ -73,6 +87,7 @@ typedef struct { SBlock blocks[]; } SBlockInfo; +#ifdef TD_REFACTOR_3 typedef struct { int16_t colId; uint16_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM @@ -89,17 +104,50 @@ typedef struct { uint8_t offsetH; char padding[1]; } SBlockCol; +#else +typedef struct { + int16_t colId; + uint8_t bitmap : 1; // 0: has bitmap if has NULL/NORM rows, 1: no bitmap if all rows are NORM + uint8_t reserve : 7; + uint8_t type; + int32_t len; + uint32_t offset; +} SBlockColV0; + +#define SBlockCol SBlockColV0 // latest SBlockCol definition + +typedef struct { + int16_t colId; + int16_t maxIndex; + int16_t minIndex; + int16_t numOfNull; + int64_t sum; + int64_t max; + int64_t min; +} SAggrBlkColV0; + +#define SAggrBlkCol SAggrBlkColV0 // latest SAggrBlkCol definition + +#endif // Code here just for back-ward compatibility static FORCE_INLINE void tsdbSetBlockColOffset(SBlockCol *pBlockCol, uint32_t offset) { +#ifdef TD_REFACTOR_3 pBlockCol->offset = offset & ((((uint32_t)1) << 24) - 1); pBlockCol->offsetH = (uint8_t)(offset >> 24); +#else + pBlockCol->offset = offset; +#endif } static FORCE_INLINE uint32_t tsdbGetBlockColOffset(SBlockCol *pBlockCol) { +#ifdef TD_REFACTOR_3 uint32_t offset1 = pBlockCol->offset; uint32_t offset2 = pBlockCol->offsetH; return (offset1 | (offset2 << 24)); +#else + return pBlockCol->offset; +#endif } typedef struct { @@ -109,31 +157,57 @@ typedef struct { SBlockCol cols[]; } SBlockData; +typedef void SAggrBlkData; // SBlockCol cols[]; + struct SReadH { - STsdb * pRepo; - SDFileSet rSet; // FSET to read - SArray * aBlkIdx; // SBlockIdx array - STable * pTable; // table to read - SBlockIdx * pBlkIdx; // current reading table SBlockIdx - int cidx; - SBlockInfo *pBlkInfo; - SBlockData *pBlkData; // Block info - SDataCols * pDCols[2]; - void * pBuf; // buffer - void * pCBuf; // compression buffer + STsdb * pRepo; + SDFileSet rSet; // FSET to read + SArray * aBlkIdx; // SBlockIdx array + STable * pTable; // table to read + SBlockIdx * pBlkIdx; // current reading table SBlockIdx + int cidx; + SBlockInfo * pBlkInfo; + SBlockData * pBlkData; // Block info + SAggrBlkData *pAggrBlkData; // Aggregate Block info + SDataCols * pDCols[2]; + void * pBuf; // buffer + void * pCBuf; // compression buffer + void * pExBuf; // extra buffer }; -#define TSDB_READ_REPO(rh) ((rh)->pRepo) -#define TSDB_READ_REPO_ID(rh) REPO_ID(TSDB_READ_REPO(rh)) -#define TSDB_READ_FSET(rh) (&((rh)->rSet)) -#define TSDB_READ_TABLE(rh) ((rh)->pTable) +#define TSDB_READ_REPO(rh) ((rh)->pRepo) +#define TSDB_READ_REPO_ID(rh) REPO_ID(TSDB_READ_REPO(rh)) +#define TSDB_READ_FSET(rh) (&((rh)->rSet)) +#define TSDB_READ_TABLE(rh) ((rh)->pTable) #define TSDB_READ_HEAD_FILE(rh) TSDB_DFILE_IN_SET(TSDB_READ_FSET(rh), TSDB_FILE_HEAD) #define TSDB_READ_DATA_FILE(rh) TSDB_DFILE_IN_SET(TSDB_READ_FSET(rh), TSDB_FILE_DATA) #define TSDB_READ_LAST_FILE(rh) TSDB_DFILE_IN_SET(TSDB_READ_FSET(rh), TSDB_FILE_LAST) -#define TSDB_READ_BUF(rh) ((rh)->pBuf) -#define TSDB_READ_COMP_BUF(rh) ((rh)->pCBuf) +#define TSDB_READ_SMAD_FILE(rh) TSDB_DFILE_IN_SET(TSDB_READ_FSET(rh), TSDB_FILE_SMAD) +#define TSDB_READ_SMAL_FILE(rh) TSDB_DFILE_IN_SET(TSDB_READ_FSET(rh), TSDB_FILE_SMAL) +#define TSDB_READ_BUF(rh) ((rh)->pBuf) +#define TSDB_READ_COMP_BUF(rh) ((rh)->pCBuf) +#define TSDB_READ_EXBUF(rh) ((rh)->pExBuf) + +#define TSDB_BLOCK_STATIS_SIZE(ncols, blkVer) \ + (sizeof(SBlockData) + sizeof(SBlockColV##blkVer) * (ncols) + sizeof(TSCKSUM)) + +static FORCE_INLINE size_t tsdbBlockStatisSize(int nCols, uint32_t blkVer) { + switch (blkVer) { + case TSDB_SBLK_VER_0: + default: + return TSDB_BLOCK_STATIS_SIZE(nCols, 0); + } +} -#define TSDB_BLOCK_STATIS_SIZE(ncols) (sizeof(SBlockData) + sizeof(SBlockCol) * (ncols) + sizeof(TSCKSUM)) +#define TSDB_BLOCK_AGGR_SIZE(ncols, blkVer) (sizeof(SAggrBlkColV##blkVer) * (ncols) + sizeof(TSCKSUM)) + +static FORCE_INLINE size_t tsdbBlockAggrSize(int nCols, uint32_t blkVer) { + switch (blkVer) { + case TSDB_SBLK_VER_0: + default: + return TSDB_BLOCK_AGGR_SIZE(nCols, 0); + } +} int tsdbInitReadH(SReadH *pReadh, STsdb *pRepo); void tsdbDestroyReadH(SReadH *pReadh); @@ -147,7 +221,7 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo int tsdbLoadBlockStatis(SReadH *pReadh, SBlock *pBlock); int tsdbEncodeSBlockIdx(void **buf, SBlockIdx *pIdx); void *tsdbDecodeSBlockIdx(void *buf, SBlockIdx *pIdx); -void tsdbGetBlockStatis(SReadH *pReadh, SDataStatis *pStatis, int numOfCols); +void tsdbGetBlockStatis(SReadH *pReadh, SDataStatis *pStatis, int numOfCols, SBlock *pBlock); static FORCE_INLINE int tsdbMakeRoom(void **ppBuf, size_t size) { void * pBuf = *ppBuf; diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit.c b/source/dnode/vnode/src/tsdb/tsdbCommit.c index f7e4d56fe2c22e77895b9b6971c8a937b6277c68..2e7116969e1e0f3d418b53b084b236469f94daad 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit.c @@ -50,8 +50,11 @@ typedef struct { #define TSDB_COMMIT_HEAD_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_HEAD) #define TSDB_COMMIT_DATA_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_DATA) #define TSDB_COMMIT_LAST_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_LAST) +#define TSDB_COMMIT_SMAD_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_SMAD) +#define TSDB_COMMIT_SMAL_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_SMAL) #define TSDB_COMMIT_BUF(ch) TSDB_READ_BUF(&((ch)->readh)) #define TSDB_COMMIT_COMP_BUF(ch) TSDB_READ_COMP_BUF(&((ch)->readh)) +#define TSDB_COMMIT_EXBUF(ch) TSDB_READ_EXBUF(&((ch)->readh)) #define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->config.maxRowsPerFileBlock) #define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch))) @@ -509,7 +512,7 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid // TSDB_FILE_HEAD SDFile *pWHeadf = TSDB_COMMIT_HEAD_FILE(pCommith); tsdbInitDFile(pRepo, pWHeadf, did, fid, FS_TXN_VERSION(REPO_FS(pRepo)), TSDB_FILE_HEAD); - if (tsdbCreateDFile(pRepo, pWHeadf, true) < 0) { + if (tsdbCreateDFile(pRepo, pWHeadf, true, TSDB_FILE_HEAD) < 0) { tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWHeadf), tstrerror(terrno)); @@ -560,7 +563,7 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid tsdbInitDFile(pRepo, pWLastf, did, fid, FS_TXN_VERSION(REPO_FS(pRepo)), TSDB_FILE_LAST); pCommith->isLFileSame = false; - if (tsdbCreateDFile(pRepo, pWLastf, true) < 0) { + if (tsdbCreateDFile(pRepo, pWLastf, true, TSDB_FILE_LAST) < 0) { tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWLastf), tstrerror(terrno)); @@ -572,6 +575,74 @@ static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid } } } + + // TSDB_FILE_SMAD + SDFile *pRSmadF = TSDB_READ_SMAD_FILE(&(pCommith->readh)); + SDFile *pWSmadF = TSDB_COMMIT_SMAD_FILE(pCommith); + + if (access(TSDB_FILE_FULL_NAME(pRSmadF), F_OK) != 0) { + tsdbDebug("vgId:%d create data file %s as not exist", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pRSmadF)); + tsdbInitDFile(pRepo, pWSmadF, did, fid, FS_TXN_VERSION(REPO_FS(pRepo)), TSDB_FILE_SMAD); + + if (tsdbCreateDFile(pRepo, pWSmadF, true, TSDB_FILE_SMAD) < 0) { + tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWSmadF), + tstrerror(terrno)); + + tsdbCloseDFileSet(pWSet); + (void)tsdbRemoveDFile(pWHeadf); + if (pCommith->isRFileSet) { + tsdbCloseAndUnsetFSet(&(pCommith->readh)); + return -1; + } + } + } else { + tsdbInitDFileEx(pWSmadF, pRSmadF); + if (tsdbOpenDFile(pWSmadF, O_RDWR) < 0) { + tsdbError("vgId:%d failed to open file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWSmadF), + tstrerror(terrno)); + + tsdbCloseDFileSet(pWSet); + tsdbRemoveDFile(pWHeadf); + if (pCommith->isRFileSet) { + tsdbCloseAndUnsetFSet(&(pCommith->readh)); + return -1; + } + } + } + + // TSDB_FILE_SMAL + SDFile *pRSmalF = TSDB_READ_SMAL_FILE(&(pCommith->readh)); + SDFile *pWSmalF = TSDB_COMMIT_SMAL_FILE(pCommith); + + if ((pCommith->isLFileSame) && access(TSDB_FILE_FULL_NAME(pRSmalF), F_OK) == 0) { + tsdbInitDFileEx(pWSmalF, pRSmalF); + if (tsdbOpenDFile(pWSmalF, O_RDWR) < 0) { + tsdbError("vgId:%d failed to open file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWSmalF), + tstrerror(terrno)); + + tsdbCloseDFileSet(pWSet); + tsdbRemoveDFile(pWHeadf); + if (pCommith->isRFileSet) { + tsdbCloseAndUnsetFSet(&(pCommith->readh)); + return -1; + } + } + } else { + tsdbDebug("vgId:%d create data file %s as not exist", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pRSmalF)); + tsdbInitDFile(pRepo, pWSmalF, did, fid, FS_TXN_VERSION(REPO_FS(pRepo)), TSDB_FILE_SMAL); + + if (tsdbCreateDFile(pRepo, pWSmalF, true, TSDB_FILE_SMAL) < 0) { + tsdbError("vgId:%d failed to create file %s to commit since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pWSmalF), + tstrerror(terrno)); + + tsdbCloseDFileSet(pWSet); + (void)tsdbRemoveDFile(pWHeadf); + if (pCommith->isRFileSet) { + tsdbCloseAndUnsetFSet(&(pCommith->readh)); + return -1; + } + } + } } return 0; @@ -1131,41 +1202,57 @@ static int tsdbComparKeyBlock(const void *arg1, const void *arg2) { } } -int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, - bool isSuper, void **ppBuf, void **ppCBuf) { - STsdbCfg *pCfg = REPO_CFG(pRepo); - SBlockData *pBlockData; - int64_t offset = 0; - int rowsToWrite = pDataCols->numOfRows; +int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDFile *pDFileAggr, SDataCols *pDataCols, + SBlock *pBlock, bool isLast, bool isSuper, void **ppBuf, void **ppCBuf, void **ppExBuf) { + STsdbCfg * pCfg = REPO_CFG(pRepo); + SBlockData * pBlockData = NULL; + SAggrBlkData *pAggrBlkData = NULL; + int64_t offset = 0, offsetAggr = 0; + int rowsToWrite = pDataCols->numOfRows; ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock); ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock); // Make buffer space - if (tsdbMakeRoom(ppBuf, TSDB_BLOCK_STATIS_SIZE(pDataCols->numOfCols)) < 0) { + if (tsdbMakeRoom(ppBuf, tsdbBlockStatisSize(pDataCols->numOfCols, SBlockVerLatest)) < 0) { return -1; } pBlockData = (SBlockData *)(*ppBuf); + if (tsdbMakeRoom(ppExBuf, tsdbBlockAggrSize(pDataCols->numOfCols, SBlockVerLatest)) < 0) { + return -1; + } + pAggrBlkData = (SAggrBlkData *)(*ppExBuf); + // Get # of cols not all NULL(not including key column) int nColsNotAllNull = 0; - for (int ncol = 1; ncol < pDataCols->numOfCols; ncol++) { // ncol from 1, we skip the timestamp column - SDataCol *pDataCol = pDataCols->cols + ncol; - SBlockCol *pBlockCol = pBlockData->cols + nColsNotAllNull; + for (int ncol = 1; ncol < pDataCols->numOfCols; ++ncol) { // ncol from 1, we skip the timestamp column + SDataCol * pDataCol = pDataCols->cols + ncol; + SBlockCol * pBlockCol = pBlockData->cols + nColsNotAllNull; + SAggrBlkCol *pAggrBlkCol = (SAggrBlkCol *)pAggrBlkData + nColsNotAllNull; if (isAllRowsNull(pDataCol)) { // all data to commit are NULL, just ignore it continue; } memset(pBlockCol, 0, sizeof(*pBlockCol)); + memset(pAggrBlkCol, 0, sizeof(*pAggrBlkCol)); pBlockCol->colId = pDataCol->colId; pBlockCol->type = pDataCol->type; + pAggrBlkCol->colId = pDataCol->colId; + if (tDataTypes[pDataCol->type].statisFunc) { +#if 0 (*tDataTypes[pDataCol->type].statisFunc)(pDataCol->pData, rowsToWrite, &(pBlockCol->min), &(pBlockCol->max), &(pBlockCol->sum), &(pBlockCol->minIndex), &(pBlockCol->maxIndex), &(pBlockCol->numOfNull)); - if (pBlockCol->numOfNull == 0) { +#endif + (*tDataTypes[pDataCol->type].statisFunc)(pDataCol->pData, rowsToWrite, &(pAggrBlkCol->min), &(pAggrBlkCol->max), + &(pAggrBlkCol->sum), &(pAggrBlkCol->minIndex), &(pAggrBlkCol->maxIndex), + &(pAggrBlkCol->numOfNull)); + + if (pAggrBlkCol->numOfNull == 0) { TD_SET_COL_ROWS_NORM(pBlockCol); } else { TD_SET_COL_ROWS_MISC(pBlockCol); @@ -1181,13 +1268,14 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols * // Compress the data if neccessary int tcol = 0; // counter of not all NULL and written columns uint32_t toffset = 0; - int32_t tsize = TSDB_BLOCK_STATIS_SIZE(nColsNotAllNull); + int32_t tsize = (int32_t)tsdbBlockStatisSize(nColsNotAllNull, SBlockVerLatest); int32_t lsize = tsize; + uint32_t tsizeAggr = (uint32_t)tsdbBlockAggrSize(nColsNotAllNull, SBlockVerLatest); int32_t keyLen = 0; int32_t nBitmaps = (int32_t)TD_BITMAP_BYTES(rowsToWrite); int32_t tBitmaps = 0; - for (int ncol = 0; ncol < pDataCols->numOfCols; ncol++) { + for (int ncol = 0; ncol < pDataCols->numOfCols; ++ncol) { // All not NULL columns finish if (ncol != 0 && tcol >= nColsNotAllNull) break; @@ -1248,7 +1336,7 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols * if (ncol != 0) { tsdbSetBlockColOffset(pBlockCol, toffset); pBlockCol->len = flen; - tcol++; + ++tcol; } else { keyLen = flen; } @@ -1269,6 +1357,18 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols * return -1; } + uint32_t aggrStatus = nColsNotAllNull > 0 ? 1 : 0; + if (aggrStatus > 0) { + + taosCalcChecksumAppend(0, (uint8_t *)pAggrBlkData, tsizeAggr); + tsdbUpdateDFileMagic(pDFileAggr, POINTER_SHIFT(pAggrBlkData, tsizeAggr - sizeof(TSCKSUM))); + + // Write the whole block to file + if (tsdbAppendDFile(pDFileAggr, (void *)pAggrBlkData, tsizeAggr, &offsetAggr) < tsizeAggr) { + return -1; + } + } + // Update pBlock membership vairables pBlock->last = isLast; pBlock->offset = offset; @@ -1280,6 +1380,9 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols * pBlock->numOfCols = nColsNotAllNull; pBlock->keyFirst = dataColsKeyFirst(pDataCols); pBlock->keyLast = dataColsKeyLast(pDataCols); + pBlock->aggrStat = aggrStatus; + pBlock->blkVer = SBlockVerLatest; + pBlock->aggrOffset = (uint64_t)offsetAggr; tsdbDebug("vgId:%d uid:%" PRId64 " a block of data is written to file %s, offset %" PRId64 " numOfRows %d len %d numOfCols %" PRId16 " keyFirst %" PRId64 " keyLast %" PRId64, @@ -1291,9 +1394,10 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols * static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast, bool isSuper) { - return tsdbWriteBlockImpl(TSDB_COMMIT_REPO(pCommith), TSDB_COMMIT_TABLE(pCommith), pDFile, pDataCols, pBlock, isLast, - isSuper, (void **)(&(TSDB_COMMIT_BUF(pCommith))), - (void **)(&(TSDB_COMMIT_COMP_BUF(pCommith)))); + return tsdbWriteBlockImpl(TSDB_COMMIT_REPO(pCommith), TSDB_COMMIT_TABLE(pCommith), pDFile, + isLast ? TSDB_COMMIT_SMAL_FILE(pCommith) : TSDB_COMMIT_SMAD_FILE(pCommith), pDataCols, + pBlock, isLast, isSuper, (void **)(&(TSDB_COMMIT_BUF(pCommith))), + (void **)(&(TSDB_COMMIT_COMP_BUF(pCommith))), (void **)(&(TSDB_COMMIT_EXBUF(pCommith)))); } static int tsdbWriteBlockInfo(SCommitH *pCommih) { diff --git a/source/dnode/vnode/src/tsdb/tsdbCompact.c b/source/dnode/vnode/src/tsdb/tsdbCompact.c index 80b59d8756b82901698491f549dca4c6fcda2fdd..e24d5974af5b5a9c11344fec48d053ff932e9717 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCompact.c +++ b/source/dnode/vnode/src/tsdb/tsdbCompact.c @@ -38,6 +38,8 @@ typedef struct { #define TSDB_COMPACT_HEAD_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_HEAD) #define TSDB_COMPACT_DATA_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_DATA) #define TSDB_COMPACT_LAST_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_LAST) +#define TSDB_COMPACT_SMAD_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_SMAD) +#define TSDB_COMPACT_SMAL_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_SMAL) #define TSDB_COMPACT_BUF(pComph) TSDB_READ_BUF(&((pComph)->readh)) #define TSDB_COMPACT_COMP_BUF(pComph) TSDB_READ_COMP_BUF(&((pComph)->readh)) diff --git a/source/dnode/vnode/src/tsdb/tsdbFS.c b/source/dnode/vnode/src/tsdb/tsdbFS.c index 24c765d3e5939c4dcb3fb9cb6244a25592b6f4bc..dcc9700d83144fc75683faaddeaf472be6918e10 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFS.c +++ b/source/dnode/vnode/src/tsdb/tsdbFS.c @@ -422,7 +422,7 @@ static int tsdbSaveFSStatus(STsdb *pRepo, SFSStatus *pStatus) { return -1; } - fsheader.version = TSDB_FS_VERSION; + fsheader.version = TSDB_LATEST_SFS_VER; if (taosArrayGetSize(pStatus->df) == 0) { fsheader.len = 0; } else { @@ -697,7 +697,7 @@ static int tsdbOpenFSFromCurrent(STsdb *pRepo) { ptr = tsdbDecodeFSHeader(ptr, &fsheader); ptr = tsdbDecodeFSMeta(ptr, &(pStatus->meta)); - if (fsheader.version != TSDB_FS_VERSION) { + if (fsheader.version != TSDB_LATEST_SFS_VER) { // TODO: handle file version change } diff --git a/source/dnode/vnode/src/tsdb/tsdbFile.c b/source/dnode/vnode/src/tsdb/tsdbFile.c index 5a00fa20a0d530189a41b048ad1a1b0e515248ef..4d70c429ffc86b9330671067f670a70d15242869 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFile.c +++ b/source/dnode/vnode/src/tsdb/tsdbFile.c @@ -19,8 +19,12 @@ static const char *TSDB_FNAME_SUFFIX[] = { "head", // TSDB_FILE_HEAD "data", // TSDB_FILE_DATA "last", // TSDB_FILE_LAST + "smad", // TSDB_FILE_SMAD + "smal", // TSDB_FILE_SMAL "", // TSDB_FILE_MAX "meta", // TSDB_FILE_META + "tsma", // TSDB_FILE_TSMA + "rsma", // TSDB_FILE_RSMA }; static void tsdbGetFilename(int vid, int fid, uint32_t ver, TSDB_FILE_T ftype, char *fname); @@ -304,6 +308,7 @@ void tsdbInitDFile(STsdb *pRepo, SDFile *pDFile, SDiskID did, int fid, uint32_t memset(&(pDFile->info), 0, sizeof(pDFile->info)); pDFile->info.magic = TSDB_FILE_INIT_MAGIC; + pDFile->info.fver = tsdbGetDFSVersion(ftype); tsdbGetFilename(pRepo->vgId, fid, ver, ftype, fname); tfsInitFile(pRepo->pTfs, &(pDFile->f), did, fname); @@ -341,7 +346,7 @@ static int tsdbEncodeSDFileEx(void **buf, SDFile *pDFile) { } static void *tsdbDecodeSDFileEx(void *buf, SDFile *pDFile) { - char *aname; + char *aname = NULL; buf = tsdbDecodeDFInfo(buf, &(pDFile->info)); buf = taosDecodeString(buf, &aname); @@ -352,7 +357,7 @@ static void *tsdbDecodeSDFileEx(void *buf, SDFile *pDFile) { return buf; } -int tsdbCreateDFile(STsdb *pRepo, SDFile *pDFile, bool updateHeader) { +int tsdbCreateDFile(STsdb *pRepo, SDFile *pDFile, bool updateHeader, TSDB_FILE_T fType) { ASSERT(pDFile->info.size == 0 && pDFile->info.magic == TSDB_FILE_INIT_MAGIC); pDFile->pFile = taosOpenFile(TSDB_FILE_FULL_NAME(pDFile), TD_FILE_CTEATE | TD_FILE_WRITE | TD_FILE_TRUNC); @@ -382,6 +387,7 @@ int tsdbCreateDFile(STsdb *pRepo, SDFile *pDFile, bool updateHeader) { } pDFile->info.size += TSDB_FILE_HEAD_SIZE; + pDFile->info.fver = tsdbGetDFSVersion(fType); if (tsdbUpdateDFileHeader(pDFile) < 0) { tsdbCloseDFile(pDFile); @@ -493,6 +499,7 @@ static int tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo) { int tlen = 0; tlen += taosEncodeFixedU32(buf, pInfo->magic); + tlen += taosEncodeFixedU32(buf, pInfo->fver); tlen += taosEncodeFixedU32(buf, pInfo->len); tlen += taosEncodeFixedU32(buf, pInfo->totalBlocks); tlen += taosEncodeFixedU32(buf, pInfo->totalSubBlocks); @@ -505,6 +512,7 @@ static int tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo) { static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo) { buf = taosDecodeFixedU32(buf, &(pInfo->magic)); + buf = taosDecodeFixedU32(buf, &(pInfo->fver)); buf = taosDecodeFixedU32(buf, &(pInfo->len)); buf = taosDecodeFixedU32(buf, &(pInfo->totalBlocks)); buf = taosDecodeFixedU32(buf, &(pInfo->totalSubBlocks)); @@ -562,8 +570,10 @@ static int tsdbRollBackDFile(SDFile *pDFile) { // ============== Operations on SDFileSet void tsdbInitDFileSet(STsdb *pRepo, SDFileSet *pSet, SDiskID did, int fid, uint32_t ver) { - pSet->fid = fid; - pSet->state = 0; + TSDB_FSET_FID(pSet) = fid; + TSDB_FSET_VER(pSet) = TSDB_LATEST_FSET_VER; + TSDB_FSET_STATE(pSet) = 0; + pSet->reserve = 0; for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { SDFile *pDFile = TSDB_DFILE_IN_SET(pSet, ftype); @@ -572,7 +582,7 @@ void tsdbInitDFileSet(STsdb *pRepo, SDFileSet *pSet, SDiskID did, int fid, uint3 } void tsdbInitDFileSetEx(SDFileSet *pSet, SDFileSet *pOSet) { - pSet->fid = pOSet->fid; + TSDB_FSET_FID(pSet) = TSDB_FSET_FID(pOSet); for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { tsdbInitDFileEx(TSDB_DFILE_IN_SET(pSet, ftype), TSDB_DFILE_IN_SET(pOSet, ftype)); } @@ -581,7 +591,10 @@ void tsdbInitDFileSetEx(SDFileSet *pSet, SDFileSet *pOSet) { int tsdbEncodeDFileSet(void **buf, SDFileSet *pSet) { int tlen = 0; - tlen += taosEncodeFixedI32(buf, pSet->fid); + tlen += taosEncodeFixedI32(buf, TSDB_FSET_FID(pSet)); + // state not included + tlen += taosEncodeFixedU8(buf, TSDB_FSET_VER(pSet)); + tlen += taosEncodeFixedU16(buf, pSet->reserve); for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { tlen += tsdbEncodeSDFile(buf, TSDB_DFILE_IN_SET(pSet, ftype)); } @@ -590,11 +603,11 @@ int tsdbEncodeDFileSet(void **buf, SDFileSet *pSet) { } void *tsdbDecodeDFileSet(STsdb *pRepo, void *buf, SDFileSet *pSet) { - int32_t fid; + buf = taosDecodeFixedI32(buf, &(TSDB_FSET_FID(pSet))); + TSDB_FSET_STATE(pSet) = 0; + buf = taosDecodeFixedU8(buf, &(TSDB_FSET_VER(pSet))); + buf = taosDecodeFixedU16(buf, &(pSet->reserve)); - buf = taosDecodeFixedI32(buf, &(fid)); - pSet->state = 0; - pSet->fid = fid; for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { buf = tsdbDecodeSDFile(pRepo, buf, TSDB_DFILE_IN_SET(pSet, ftype)); } @@ -604,7 +617,9 @@ void *tsdbDecodeDFileSet(STsdb *pRepo, void *buf, SDFileSet *pSet) { int tsdbEncodeDFileSetEx(void **buf, SDFileSet *pSet) { int tlen = 0; - tlen += taosEncodeFixedI32(buf, pSet->fid); + tlen += taosEncodeFixedI32(buf, TSDB_FSET_FID(pSet)); + tlen += taosEncodeFixedU8(buf, TSDB_FSET_VER(pSet)); + tlen += taosEncodeFixedU16(buf, pSet->reserve); for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { tlen += tsdbEncodeSDFileEx(buf, TSDB_DFILE_IN_SET(pSet, ftype)); } @@ -613,10 +628,10 @@ int tsdbEncodeDFileSetEx(void **buf, SDFileSet *pSet) { } void *tsdbDecodeDFileSetEx(void *buf, SDFileSet *pSet) { - int32_t fid; + buf = taosDecodeFixedI32(buf, &(TSDB_FSET_FID(pSet))); + buf = taosDecodeFixedU8(buf, &(TSDB_FSET_VER(pSet))); + buf = taosDecodeFixedU16(buf, &(pSet->reserve)); - buf = taosDecodeFixedI32(buf, &(fid)); - pSet->fid = fid; for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { buf = tsdbDecodeSDFileEx(buf, TSDB_DFILE_IN_SET(pSet, ftype)); } @@ -637,7 +652,7 @@ int tsdbApplyDFileSetChange(SDFileSet *from, SDFileSet *to) { int tsdbCreateDFileSet(STsdb *pRepo, SDFileSet *pSet, bool updateHeader) { for (TSDB_FILE_T ftype = 0; ftype < TSDB_FILE_MAX; ftype++) { - if (tsdbCreateDFile(pRepo, TSDB_DFILE_IN_SET(pSet, ftype), updateHeader) < 0) { + if (tsdbCreateDFile(pRepo, TSDB_DFILE_IN_SET(pSet, ftype), updateHeader, ftype) < 0) { tsdbCloseDFileSet(pSet); tsdbRemoveDFileSet(pSet); return -1; diff --git a/source/dnode/vnode/src/tsdb/tsdbMain.c b/source/dnode/vnode/src/tsdb/tsdbMain.c index 812ec67ec49dc4901a18fc39ad2b12ed9e8a1429..2d8c4701132a9c9818775654df8751b5b4a2ec75 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMain.c +++ b/source/dnode/vnode/src/tsdb/tsdbMain.c @@ -821,9 +821,10 @@ static int tsdbRestoreLastColumns(STsdbRepo *pRepo, STable *pTable, SReadH* pRea // file block with sub-blocks has no statistics data if (pBlock->numOfSubBlocks <= 1) { - tsdbLoadBlockStatis(pReadh, pBlock); - tsdbGetBlockStatis(pReadh, pBlockStatis, (int)numColumns); - loadStatisData = true; + if (tsdbLoadBlockStatis(pReadh, pBlock) == TSDB_STATIS_OK) { + tsdbGetBlockStatis(pReadh, pBlockStatis, (int)numColumns, pBlock); + loadStatisData = true; + } } for (int16_t i = 0; i < numColumns && numColumns > pTable->restoreColumnNum; ++i) { diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index c1cf776cb542110f6089ab9e684d2e2756a8040c..4bd0ee959e0db8e9b84e7e02566e497e15dcb066 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -3276,8 +3276,12 @@ int32_t tsdbRetrieveDataBlockStatisInfo(tsdbReaderT* pTsdbReadHandle, SDataStati } int64_t stime = taosGetTimestampUs(); - if (tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock) < 0) { + int statisStatus = tsdbLoadBlockStatis(&pHandle->rhelper, pBlockInfo->compBlock); + if (statisStatus < TSDB_STATIS_OK) { return terrno; + } else if (statisStatus > TSDB_STATIS_OK) { + *pBlockStatis = NULL; + return TSDB_CODE_SUCCESS; } int16_t* colIds = pHandle->defaultLoadColumn->pData; @@ -3288,7 +3292,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(tsdbReaderT* pTsdbReadHandle, SDataStati pHandle->statis[i].colId = colIds[i]; } - tsdbGetBlockStatis(&pHandle->rhelper, pHandle->statis, (int)numOfCols); + tsdbGetBlockStatis(&pHandle->rhelper, pHandle->statis, (int)numOfCols, pBlockInfo->compBlock); // always load the first primary timestamp column data SDataStatis* pPrimaryColStatis = &pHandle->statis[0]; diff --git a/source/dnode/vnode/src/tsdb/tsdbReadImpl.c b/source/dnode/vnode/src/tsdb/tsdbReadImpl.c index 7e8e7866d71addb8a125998bf3fa54963b2466cb..f6827eaae187dfb3da31110c81dcf38c24a67702 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReadImpl.c +++ b/source/dnode/vnode/src/tsdb/tsdbReadImpl.c @@ -19,6 +19,7 @@ static void tsdbResetReadTable(SReadH *pReadh); static void tsdbResetReadFile(SReadH *pReadh); +static int tsdbLoadBlockOffset(SReadH *pReadh, SBlock *pBlock); static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDataCols); static int tsdbCheckAndDecodeColumnData(SDataCol *pDataCol, void *content, int32_t len, int8_t comp, int numOfRows, int numOfBitmaps, int lenOfBitmaps, int maxPoints, char *buffer, @@ -63,10 +64,12 @@ int tsdbInitReadH(SReadH *pReadh, STsdb *pRepo) { void tsdbDestroyReadH(SReadH *pReadh) { if (pReadh == NULL) return; + pReadh->pExBuf = taosTZfree(pReadh->pExBuf); pReadh->pCBuf = taosTZfree(pReadh->pCBuf); pReadh->pBuf = taosTZfree(pReadh->pBuf); pReadh->pDCols[0] = tdFreeDataCols(pReadh->pDCols[0]); pReadh->pDCols[1] = tdFreeDataCols(pReadh->pDCols[1]); + pReadh->pAggrBlkData = taosTZfree(pReadh->pAggrBlkData); pReadh->pBlkData = taosTZfree(pReadh->pBlkData); pReadh->pBlkInfo = taosTZfree(pReadh->pBlkInfo); pReadh->cidx = 0; @@ -305,15 +308,58 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo, int tsdbLoadBlockStatis(SReadH *pReadh, SBlock *pBlock) { ASSERT(pBlock->numOfSubBlocks <= 1); - SDFile *pDFile = (pBlock->last) ? TSDB_READ_LAST_FILE(pReadh) : TSDB_READ_DATA_FILE(pReadh); + if (!pBlock->aggrStat) { + return TSDB_STATIS_NONE; + } + + SDFile *pDFileAggr = pBlock->last ? TSDB_READ_SMAL_FILE(pReadh) : TSDB_READ_SMAD_FILE(pReadh); + if (tsdbSeekDFile(pDFileAggr, pBlock->aggrOffset, SEEK_SET) < 0) { + tsdbError("vgId:%d failed to load block aggr part while seek file %s to offset %" PRIu64 " since %s", + TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFileAggr), (uint64_t)pBlock->aggrOffset, + tstrerror(terrno)); + return -1; + } + + size_t sizeAggr = tsdbBlockAggrSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer); + if (tsdbMakeRoom((void **)(&(pReadh->pAggrBlkData)), sizeAggr) < 0) return -1; + + int64_t nreadAggr = tsdbReadDFile(pDFileAggr, (void *)(pReadh->pAggrBlkData), sizeAggr); + if (nreadAggr < 0) { + tsdbError("vgId:%d failed to load block aggr part while read file %s since %s, offset:%" PRIu64 " len :%" PRIzu, + TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFileAggr), tstrerror(terrno), + (uint64_t)pBlock->aggrOffset, sizeAggr); + return -1; + } + + if (nreadAggr < sizeAggr) { + terrno = TSDB_CODE_TDB_FILE_CORRUPTED; + tsdbError("vgId:%d block aggr part in file %s is corrupted, offset:%" PRIu64 " expected bytes:%" PRIzu + " read bytes: %" PRId64, + TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFileAggr), (uint64_t)pBlock->aggrOffset, sizeAggr, + nreadAggr); + return -1; + } + + if (!taosCheckChecksumWhole((uint8_t *)(pReadh->pAggrBlkData), (uint32_t)sizeAggr)) { + terrno = TSDB_CODE_TDB_FILE_CORRUPTED; + tsdbError("vgId:%d block aggr part in file %s is corrupted since wrong checksum, offset:%" PRIu64 " len :%" PRIzu, + TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFileAggr), (uint64_t)pBlock->aggrOffset, sizeAggr); + return -1; + } + return 0; +} + +static int tsdbLoadBlockOffset(SReadH *pReadh, SBlock *pBlock) { + ASSERT(pBlock->numOfSubBlocks <= 1); + SDFile *pDFile = (pBlock->last) ? TSDB_READ_LAST_FILE(pReadh) : TSDB_READ_DATA_FILE(pReadh); if (tsdbSeekDFile(pDFile, pBlock->offset, SEEK_SET) < 0) { tsdbError("vgId:%d failed to load block statis part while seek file %s to offset %" PRId64 " since %s", TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFile), (int64_t)pBlock->offset, tstrerror(terrno)); return -1; } - size_t size = TSDB_BLOCK_STATIS_SIZE(pBlock->numOfCols); + size_t size = tsdbBlockStatisSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer); if (tsdbMakeRoom((void **)(&(pReadh->pBlkData)), size) < 0) return -1; int64_t nread = tsdbReadDFile(pDFile, (void *)(pReadh->pBlkData), size); @@ -337,7 +383,6 @@ int tsdbLoadBlockStatis(SReadH *pReadh, SBlock *pBlock) { TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFile), (int64_t)pBlock->offset, size); return -1; } - return 0; } @@ -375,13 +420,14 @@ void *tsdbDecodeSBlockIdx(void *buf, SBlockIdx *pIdx) { return buf; } -void tsdbGetBlockStatis(SReadH *pReadh, SDataStatis *pStatis, int numOfCols) { +void tsdbGetBlockStatis(SReadH *pReadh, SDataStatis *pStatis, int numOfCols, SBlock *pBlock) { +#ifdef TD_REFACTOR_3 SBlockData *pBlockData = pReadh->pBlkData; for (int i = 0, j = 0; i < numOfCols;) { if (j >= pBlockData->numOfCols) { pStatis[i].numOfNull = -1; - i++; + ++i; continue; } @@ -392,15 +438,45 @@ void tsdbGetBlockStatis(SReadH *pReadh, SDataStatis *pStatis, int numOfCols) { pStatis[i].maxIndex = pBlockData->cols[j].maxIndex; pStatis[i].minIndex = pBlockData->cols[j].minIndex; pStatis[i].numOfNull = pBlockData->cols[j].numOfNull; - i++; - j++; + ++i; + ++j; } else if (pStatis[i].colId < pBlockData->cols[j].colId) { pStatis[i].numOfNull = -1; - i++; + ++i; } else { - j++; + ++j; } } +#else + if (pBlock->aggrStat) { + SAggrBlkData *pAggrBlkData = pReadh->pAggrBlkData; + + for (int i = 0, j = 0; i < numOfCols;) { + if (j >= pBlock->numOfCols) { + pStatis[i].numOfNull = -1; + ++i; + continue; + } + SAggrBlkCol *pAggrBlkCol = ((SAggrBlkCol *)(pAggrBlkData)) + j; + if (pStatis[i].colId == pAggrBlkCol->colId) { + pStatis[i].sum = pAggrBlkCol->sum; + pStatis[i].max = pAggrBlkCol->max; + pStatis[i].min = pAggrBlkCol->min; + pStatis[i].maxIndex = pAggrBlkCol->maxIndex; + pStatis[i].minIndex = pAggrBlkCol->minIndex; + pStatis[i].numOfNull = pAggrBlkCol->numOfNull; + ++i; + ++j; + } else if (pStatis[i].colId < pAggrBlkCol->colId) { + pStatis[i].numOfNull = -1; + ++i; + } else { + ++j; + } + } + } + +#endif } static void tsdbResetReadTable(SReadH *pReadh) { @@ -449,7 +525,7 @@ static int tsdbLoadBlockDataImpl(SReadH *pReadh, SBlock *pBlock, SDataCols *pDat return -1; } - int32_t tsize = TSDB_BLOCK_STATIS_SIZE(pBlock->numOfCols); + int32_t tsize = (int32_t)tsdbBlockStatisSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer); if (!taosCheckChecksumWhole((uint8_t *)TSDB_READ_BUF(pReadh), tsize)) { terrno = TSDB_CODE_TDB_FILE_CORRUPTED; tsdbError("vgId:%d block statis part in file %s is corrupted since wrong checksum, offset:%" PRId64 " len :%d", @@ -592,7 +668,7 @@ static int tsdbLoadBlockDataColsImpl(SReadH *pReadh, SBlock *pBlock, SDataCols * tdResetDataCols(pDataCols); // If only load timestamp column, no need to load SBlockData part - if (numOfColIds > 1 && tsdbLoadBlockStatis(pReadh, pBlock) < 0) return -1; + if (numOfColIds > 1 && tsdbLoadBlockOffset(pReadh, pBlock) < 0) return -1; pDataCols->numOfRows = pBlock->numOfRows; @@ -686,7 +762,8 @@ static int tsdbLoadColData(SReadH *pReadh, SDFile *pDFile, SBlock *pBlock, SBloc if (tsdbMakeRoom((void **)(&TSDB_READ_BUF(pReadh)), pBlockCol->len) < 0) return -1; if (tsdbMakeRoom((void **)(&TSDB_READ_COMP_BUF(pReadh)), tsize) < 0) return -1; - int64_t offset = pBlock->offset + TSDB_BLOCK_STATIS_SIZE(pBlock->numOfCols) + tsdbGetBlockColOffset(pBlockCol); + int64_t offset = pBlock->offset + tsdbBlockStatisSize(pBlock->numOfCols, (uint32_t)pBlock->blkVer) + + tsdbGetBlockColOffset(pBlockCol); if (tsdbSeekDFile(pDFile, offset, SEEK_SET) < 0) { tsdbError("vgId:%d failed to load block column data while seek file %s to offset %" PRId64 " since %s", TSDB_READ_REPO_ID(pReadh), TSDB_FILE_FULL_NAME(pDFile), offset, tstrerror(terrno)); diff --git a/source/dnode/vnode/src/vnd/vnodeMain.c b/source/dnode/vnode/src/vnd/vnodeMain.c index c748907d6c41a02ecbd2be3f70f04ab2ea9b2738..ba346064ae6216b92b62435a3ba1ec995d2cec52 100644 --- a/source/dnode/vnode/src/vnd/vnodeMain.c +++ b/source/dnode/vnode/src/vnd/vnodeMain.c @@ -30,6 +30,9 @@ SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg) { cfg.pDnode = pVnodeCfg->pDnode; cfg.pTfs = pVnodeCfg->pTfs; cfg.dbId = pVnodeCfg->dbId; + cfg.hashBegin = pVnodeCfg->hashBegin; + cfg.hashEnd = pVnodeCfg->hashEnd; + cfg.hashMethod = pVnodeCfg->hashMethod; } // Validate options diff --git a/source/libs/CMakeLists.txt b/source/libs/CMakeLists.txt index e07e46948f4b66930ccfa3abb7d31066f12cad72..78625d1eedfc3575bac15bbd50970f443803a320 100644 --- a/source/libs/CMakeLists.txt +++ b/source/libs/CMakeLists.txt @@ -14,5 +14,6 @@ add_subdirectory(function) add_subdirectory(qcom) add_subdirectory(qworker) add_subdirectory(tfs) +add_subdirectory(monitor) add_subdirectory(nodes) add_subdirectory(scalar) diff --git a/source/libs/cache/CMakeLists.txt b/source/libs/cache/CMakeLists.txt index 5ba59ef160706b16d28e3ad17b1ccc429b806095..c99b5602ad707695839cf8de24569445b937e65d 100644 --- a/source/libs/cache/CMakeLists.txt +++ b/source/libs/cache/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src CACHE_SRC) -add_library(cache ${CACHE_SRC}) +add_library(cache STATIC ${CACHE_SRC}) target_include_directories( cache PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/cache" diff --git a/source/libs/catalog/CMakeLists.txt b/source/libs/catalog/CMakeLists.txt index bb9ed686a77501b5513127f84a2be65b830d5e64..09cd252a895ca3b5b82870c8be6cdfb2e77b79f5 100644 --- a/source/libs/catalog/CMakeLists.txt +++ b/source/libs/catalog/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src CATALOG_SRC) -add_library(catalog ${CATALOG_SRC}) +add_library(catalog STATIC ${CATALOG_SRC}) target_include_directories( catalog PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/catalog" diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index e71f559ad960466264702e67b6c384d01e5f1113..c4f1a117fe58e146efcc393287700db8c9d131e4 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -60,6 +60,7 @@ typedef struct SCtgDebug { bool lockDebug; bool cacheDebug; bool apiDebug; + bool metaDebug; uint32_t showCachePeriodSec; } SCtgDebug; @@ -119,6 +120,10 @@ typedef struct SCatalogStat { SCtgCacheStat cache; } SCatalogStat; +typedef struct SCtgUpdateMsgHeader { + SCatalog* pCtg; +} SCtgUpdateMsgHeader; + typedef struct SCtgUpdateVgMsg { SCatalog* pCtg; char dbFName[TSDB_DB_FNAME_LEN]; @@ -145,6 +150,14 @@ typedef struct SCtgRemoveStbMsg { uint64_t suid; } SCtgRemoveStbMsg; +typedef struct SCtgRemoveTblMsg { + SCatalog* pCtg; + char dbFName[TSDB_DB_FNAME_LEN]; + char tbName[TSDB_TABLE_NAME_LEN]; + uint64_t dbId; +} SCtgRemoveTblMsg; + + typedef struct SCtgMetaAction { int32_t act; void *data; @@ -189,19 +202,21 @@ typedef struct SCtgAction { #define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE) #define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE) -#define CTG_FLAG_STB 0x1 -#define CTG_FLAG_NOT_STB 0x2 -#define CTG_FLAG_UNKNOWN_STB 0x4 -#define CTG_FLAG_INF_DB 0x8 - -#define CTG_IS_STB(_flag) ((_flag) & CTG_FLAG_STB) -#define CTG_IS_NOT_STB(_flag) ((_flag) & CTG_FLAG_NOT_STB) -#define CTG_IS_UNKNOWN_STB(_flag) ((_flag) & CTG_FLAG_UNKNOWN_STB) -#define CTG_IS_INF_DB(_flag) ((_flag) & CTG_FLAG_INF_DB) -#define CTG_SET_INF_DB(_flag) ((_flag) |= CTG_FLAG_INF_DB) -#define CTG_SET_STB(_flag, tbType) do { (_flag) |= ((tbType) == TSDB_SUPER_TABLE) ? CTG_FLAG_STB : ((tbType) > TSDB_SUPER_TABLE ? CTG_FLAG_NOT_STB : CTG_FLAG_UNKNOWN_STB); } while (0) -#define CTG_GEN_STB_FLAG(_isStb) ((_isStb) == 1) ? CTG_FLAG_STB : ((_isStb) == 0 ? CTG_FLAG_NOT_STB : CTG_FLAG_UNKNOWN_STB) -#define CTG_TBTYPE_MATCH(_flag, tbType) (CTG_IS_UNKNOWN_STB(_flag) || (CTG_IS_STB(_flag) && (tbType) == TSDB_SUPER_TABLE) || (CTG_IS_NOT_STB(_flag) && (tbType) != TSDB_SUPER_TABLE)) +#define CTG_FLAG_STB 0x1 +#define CTG_FLAG_NOT_STB 0x2 +#define CTG_FLAG_UNKNOWN_STB 0x4 +#define CTG_FLAG_INF_DB 0x8 +#define CTG_FLAG_FORCE_UPDATE 0x10 + +#define CTG_FLAG_IS_STB(_flag) ((_flag) & CTG_FLAG_STB) +#define CTG_FLAG_IS_NOT_STB(_flag) ((_flag) & CTG_FLAG_NOT_STB) +#define CTG_FLAG_IS_UNKNOWN_STB(_flag) ((_flag) & CTG_FLAG_UNKNOWN_STB) +#define CTG_FLAG_IS_INF_DB(_flag) ((_flag) & CTG_FLAG_INF_DB) +#define CTG_FLAG_IS_FORCE_UPDATE(_flag) ((_flag) & CTG_FLAG_FORCE_UPDATE) +#define CTG_FLAG_SET_INF_DB(_flag) ((_flag) |= CTG_FLAG_INF_DB) +#define CTG_FLAG_SET_STB(_flag, tbType) do { (_flag) |= ((tbType) == TSDB_SUPER_TABLE) ? CTG_FLAG_STB : ((tbType) > TSDB_SUPER_TABLE ? CTG_FLAG_NOT_STB : CTG_FLAG_UNKNOWN_STB); } while (0) +#define CTG_FLAG_MAKE_STB(_isStb) (((_isStb) == 1) ? CTG_FLAG_STB : ((_isStb) == 0 ? CTG_FLAG_NOT_STB : CTG_FLAG_UNKNOWN_STB)) +#define CTG_FLAG_MATCH_STB(_flag, tbType) (CTG_FLAG_IS_UNKNOWN_STB(_flag) || (CTG_FLAG_IS_STB(_flag) && (tbType) == TSDB_SUPER_TABLE) || (CTG_FLAG_IS_NOT_STB(_flag) && (tbType) != TSDB_SUPER_TABLE)) #define CTG_IS_INF_DBNAME(_dbname) ((*(_dbname) == 'i') && (0 == strcmp(_dbname, TSDB_INFORMATION_SCHEMA_DB))) diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index f0ea51c2f9e28b6a9999d1d8d75bbe8821f5483e..5779906761bbfef3c72b13d646b3bf7de0448c23 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -72,6 +72,12 @@ int32_t ctgDbgEnableDebug(char *option) { return TSDB_CODE_SUCCESS; } + if (0 == strcasecmp(option, "meta")) { + gCTGDebug.metaDebug = true; + qDebug("api debug enabled"); + return TSDB_CODE_SUCCESS; + } + qError("invalid debug option:%s", option); return TSDB_CODE_CTG_INTERNAL_ERROR; @@ -148,9 +154,30 @@ int32_t ctgDbgGetClusterCacheNum(SCatalog* pCtg, int32_t type) { return num; } +void ctgDbgShowTableMeta(SCatalog* pCtg, const char *tbName, STableMeta* p) { + if (!gCTGDebug.metaDebug) { + return; + } + + STableComInfo *c = &p->tableInfo; + + if (TSDB_CHILD_TABLE == p->tableType) { + ctgDebug("table [%s] meta: type:%d, vgId:%d, uid:%" PRIx64 ",suid:%" PRIx64, tbName, p->tableType, p->vgId, p->uid, p->suid); + return; + } else { + ctgDebug("table [%s] meta: type:%d, vgId:%d, uid:%" PRIx64 ",suid:%" PRIx64 ",sv:%d, tv:%d, tagNum:%d, precision:%d, colNum:%d, rowSize:%d", + tbName, p->tableType, p->vgId, p->uid, p->suid, p->sversion, p->tversion, c->numOfTags, c->precision, c->numOfColumns, c->rowSize); + } + + int32_t colNum = c->numOfColumns + c->numOfTags; + for (int32_t i = 0; i < colNum; ++i) { + SSchema *s = &p->schema[i]; + ctgDebug("[%d] name:%s, type:%d, colId:%d, bytes:%d", i, s->name, s->type, s->colId, s->bytes); + } +} -void ctgDbgShowDBCache(SHashObj *dbHash) { - if (NULL == dbHash) { +void ctgDbgShowDBCache(SCatalog* pCtg, SHashObj *dbHash) { + if (NULL == dbHash || !gCTGDebug.cacheDebug) { return; } @@ -164,31 +191,24 @@ void ctgDbgShowDBCache(SHashObj *dbHash) { dbCache = (SCtgDBCache *)pIter; taosHashGetKey(dbCache, (void **)&dbFName, &len); - - CTG_CACHE_DEBUG("** %dth db [%.*s][%"PRIx64"] **", i, (int32_t)len, dbFName, dbCache->dbId); - CTG_CACHE_DEBUG("deleted: %d", dbCache->deleted); + int32_t metaNum = dbCache->tbCache.metaCache ? taosHashGetSize(dbCache->tbCache.metaCache) : 0; + int32_t stbNum = dbCache->tbCache.stbCache ? taosHashGetSize(dbCache->tbCache.stbCache) : 0; + int32_t vgVersion = CTG_DEFAULT_INVALID_VERSION; + int32_t hashMethod = -1; + int32_t vgNum = 0; + if (dbCache->vgInfo) { - CTG_CACHE_DEBUG("vgVersion: %d", dbCache->vgInfo->vgVersion); - CTG_CACHE_DEBUG("hashMethod: %d", dbCache->vgInfo->hashMethod); + vgVersion = dbCache->vgInfo->vgVersion; + hashMethod = dbCache->vgInfo->hashMethod; if (dbCache->vgInfo->vgHash) { - CTG_CACHE_DEBUG("vgNum: %d", taosHashGetSize(dbCache->vgInfo->vgHash)); - //TODO - } else { - CTG_CACHE_DEBUG("vgHash: %p", dbCache->vgInfo->vgHash); + vgNum = taosHashGetSize(dbCache->vgInfo->vgHash); } - } else { - CTG_CACHE_DEBUG("vgInfo: %p", dbCache->vgInfo); - } - - if (dbCache->tbCache.metaCache) { - CTG_CACHE_DEBUG("metaNum: %d", taosHashGetSize(dbCache->tbCache.metaCache)); - } - - if (dbCache->tbCache.stbCache) { - CTG_CACHE_DEBUG("stbNum: %d", taosHashGetSize(dbCache->tbCache.stbCache)); - } + } + ctgDebug("[%d] db [%.*s][%"PRIx64"] %s: metaNum:%d, stbNum:%d, vgVersion:%d, hashMethod:%d, vgNum:%d", + i, (int32_t)len, dbFName, dbCache->dbId, dbCache->deleted?"deleted":"", metaNum, stbNum, vgVersion, hashMethod, vgNum); + pIter = taosHashIterate(dbHash, pIter); } } @@ -197,15 +217,15 @@ void ctgDbgShowDBCache(SHashObj *dbHash) { void ctgDbgShowClusterCache(SCatalog* pCtg) { - if (NULL == pCtg) { + if (!gCTGDebug.cacheDebug || NULL == pCtg) { return; } - CTG_CACHE_DEBUG("## cluster %"PRIx64" %p cache Info ##", pCtg->clusterId, pCtg); - CTG_CACHE_DEBUG("db:%d meta:%d stb:%d dbRent:%d stbRent:%d", ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_DB_NUM), ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM), + ctgDebug("## cluster %"PRIx64" %p cache Info ##", pCtg->clusterId, pCtg); + ctgDebug("db:%d meta:%d stb:%d dbRent:%d stbRent:%d", ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_DB_NUM), ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM), ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_STB_NUM), ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_DB_RENT_NUM), ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_STB_RENT_NUM)); - ctgDbgShowDBCache(pCtg->dbCache); + ctgDbgShowDBCache(pCtg, pCtg->dbCache); } @@ -292,6 +312,66 @@ _return: } +int32_t ctgPushRmStbMsgInQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *stbName, uint64_t suid) { + int32_t code = 0; + SCtgMetaAction action= {.act = CTG_ACT_REMOVE_STB}; + SCtgRemoveStbMsg *msg = malloc(sizeof(SCtgRemoveStbMsg)); + if (NULL == msg) { + ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveStbMsg)); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + msg->pCtg = pCtg; + strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName)); + strncpy(msg->stbName, stbName, sizeof(msg->stbName)); + msg->dbId = dbId; + msg->suid = suid; + + action.data = msg; + + CTG_ERR_JRET(ctgPushAction(&action)); + + ctgDebug("action [%s] added into queue", gCtgAction[action.act].name); + + return TSDB_CODE_SUCCESS; + +_return: + + tfree(action.data); + CTG_RET(code); +} + + + +int32_t ctgPushRmTblMsgInQueue(SCatalog* pCtg, const char *dbFName, int64_t dbId, const char *tbName) { + int32_t code = 0; + SCtgMetaAction action= {.act = CTG_ACT_REMOVE_TBL}; + SCtgRemoveTblMsg *msg = malloc(sizeof(SCtgRemoveTblMsg)); + if (NULL == msg) { + ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveTblMsg)); + CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); + } + + msg->pCtg = pCtg; + strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName)); + strncpy(msg->tbName, tbName, sizeof(msg->tbName)); + msg->dbId = dbId; + + action.data = msg; + + CTG_ERR_JRET(ctgPushAction(&action)); + + ctgDebug("action [%s] added into queue", gCtgAction[action.act].name); + + return TSDB_CODE_SUCCESS; + +_return: + + tfree(action.data); + CTG_RET(code); +} + + void ctgFreeTableMetaCache(SCtgTbMetaCache *cache) { CTG_LOCK(CTG_WRITE, &cache->stbLock); if (cache->stbCache) { @@ -554,7 +634,7 @@ int32_t ctgIsTableMetaExistInCache(SCatalog* pCtg, char *dbFName, char* tbName, } -int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STableMeta** pTableMeta, int32_t *exist, int32_t flag) { +int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STableMeta** pTableMeta, int32_t *exist, int32_t flag, uint64_t *dbId) { if (NULL == pCtg->dbCache) { *exist = 0; ctgWarn("empty tbmeta cache, tbName:%s", pTableName->tname); @@ -562,7 +642,7 @@ int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STable } char dbFName[TSDB_DB_FNAME_LEN] = {0}; - if (CTG_IS_INF_DB(flag)) { + if (CTG_FLAG_IS_INF_DB(flag)) { strcpy(dbFName, pTableName->dbname); } else { tNameGetFullDbName(pTableName, dbFName); @@ -590,6 +670,9 @@ int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STable } *exist = 1; + if (dbId) { + *dbId = dbCache->dbId; + } tbMeta = *pTableMeta; @@ -646,7 +729,7 @@ int32_t ctgGetTableTypeFromCache(SCatalog* pCtg, const SName* pTableName, int32_ } char dbFName[TSDB_DB_FNAME_LEN] = {0}; - if (CTG_IS_INF_DB(flag)) { + if (CTG_FLAG_IS_INF_DB(flag)) { strcpy(dbFName, pTableName->dbname); } else { tNameGetFullDbName(pTableName, dbFName); @@ -1304,18 +1387,21 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui STableMeta *orig = taosHashGet(tbCache->metaCache, tbName, strlen(tbName)); if (orig) { origType = orig->tableType; - origSuid = orig->suid; - if (origType == TSDB_SUPER_TABLE && ((!isStb) || origSuid != meta->suid)) { - CTG_LOCK(CTG_WRITE, &tbCache->stbLock); - if (taosHashRemove(tbCache->stbCache, &orig->suid, sizeof(orig->suid))) { - ctgError("stb not exist in stbCache, dbFName:%s, stb:%s, suid:%"PRIx64, dbFName, tbName, orig->suid); + if (origType == TSDB_SUPER_TABLE) { + if ((!isStb) || orig->suid != meta->suid) { + CTG_LOCK(CTG_WRITE, &tbCache->stbLock); + if (taosHashRemove(tbCache->stbCache, &orig->suid, sizeof(orig->suid))) { + ctgError("stb not exist in stbCache, dbFName:%s, stb:%s, suid:%"PRIx64, dbFName, tbName, orig->suid); + } + CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock); + + ctgDebug("stb removed from stbCache, dbFName:%s, stb:%s, suid:%"PRIx64, dbFName, tbName, orig->suid); + + ctgMetaRentRemove(&pCtg->stbRent, orig->suid, ctgStbVersionCompare); } - CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock); - ctgDebug("stb removed from stbCache, dbFName:%s, stb:%s, suid:%"PRIx64, dbFName, tbName, orig->suid); - - ctgMetaRentRemove(&pCtg->stbRent, orig->suid, ctgStbVersionCompare); + origSuid = orig->suid; } } @@ -1334,13 +1420,14 @@ int32_t ctgUpdateTblMeta(SCatalog *pCtg, SCtgDBCache *dbCache, char *dbFName, ui } ctgDebug("tbmeta updated to cache, dbFName:%s, tbName:%s, tbType:%d", dbFName, tbName, meta->tableType); + ctgDbgShowTableMeta(pCtg, tbName, meta); if (!isStb) { CTG_UNLOCK(CTG_READ, &tbCache->metaLock); return TSDB_CODE_SUCCESS; } - if (isStb && origSuid == meta->suid) { + if (origType == TSDB_SUPER_TABLE && origSuid == meta->suid) { CTG_UNLOCK(CTG_WRITE, &tbCache->stbLock); CTG_UNLOCK(CTG_READ, &tbCache->metaLock); return TSDB_CODE_SUCCESS; @@ -1506,7 +1593,7 @@ int32_t ctgRefreshTblMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, SVgroupInfo vgroupInfo = {0}; int32_t code = 0; - if (!CTG_IS_INF_DB(flag)) { + if (!CTG_FLAG_IS_INF_DB(flag)) { CTG_ERR_RET(catalogGetTableHashVgroup(pCtg, pTrans, pMgmtEps, pTableName, &vgroupInfo)); } @@ -1518,11 +1605,11 @@ int32_t ctgRefreshTblMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, CTG_ERR_RET(TSDB_CODE_CTG_MEM_ERROR); } - if (CTG_IS_INF_DB(flag)) { + if (CTG_FLAG_IS_INF_DB(flag)) { ctgDebug("will refresh tbmeta, supposed in information_schema, tbName:%s", tNameGetTableName(pTableName)); CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCtg, pTrans, pMgmtEps, (char *)pTableName->dbname, (char *)pTableName->tname, output)); - } else if (CTG_IS_STB(flag)) { + } else if (CTG_FLAG_IS_STB(flag)) { ctgDebug("will refresh tbmeta, supposed to be stb, tbName:%s", tNameGetTableName(pTableName)); // if get from mnode failed, will not try vnode @@ -1538,14 +1625,17 @@ int32_t ctgRefreshTblMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, CTG_ERR_JRET(ctgGetTableMetaFromVnode(pCtg, pTrans, pMgmtEps, pTableName, &vgroupInfo, output)); if (CTG_IS_META_TABLE(output->metaType) && TSDB_SUPER_TABLE == output->tbMeta->tableType) { - ctgDebug("will continue to refresh tbmeta since got stb, tbName:%s, metaType:%d", tNameGetTableName(pTableName), output->metaType); + ctgDebug("will continue to refresh tbmeta since got stb, tbName:%s", tNameGetTableName(pTableName)); tfree(output->tbMeta); CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCtg, pTrans, pMgmtEps, output->dbFName, output->tbName, output)); } else if (CTG_IS_META_BOTH(output->metaType)) { int32_t exist = 0; - CTG_ERR_JRET(ctgIsTableMetaExistInCache(pCtg, output->dbFName, output->tbName, &exist)); + if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) { + CTG_ERR_JRET(ctgIsTableMetaExistInCache(pCtg, output->dbFName, output->tbName, &exist)); + } + if (0 == exist) { CTG_ERR_JRET(ctgGetTableMetaFromMnodeImpl(pCtg, pTrans, pMgmtEps, output->dbFName, output->tbName, &moutput)); @@ -1606,35 +1696,40 @@ _return: CTG_RET(code); } -int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, bool forceUpdate, STableMeta** pTableMeta, int32_t flag) { +int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta, int32_t flag) { if (NULL == pCtg || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == pTableMeta) { CTG_ERR_RET(TSDB_CODE_CTG_INVALID_INPUT); } int32_t exist = 0; int32_t code = 0; + uint64_t dbId = 0; + uint64_t suid = 0; + STableMetaOutput *output = NULL; if (CTG_IS_INF_DBNAME(pTableName->dbname)) { - CTG_SET_INF_DB(flag); + CTG_FLAG_SET_INF_DB(flag); } - if ((!forceUpdate) || (CTG_IS_INF_DB(flag))) { - CTG_ERR_RET(ctgGetTableMetaFromCache(pCtg, pTableName, pTableMeta, &exist, flag)); + CTG_ERR_RET(ctgGetTableMetaFromCache(pCtg, pTableName, pTableMeta, &exist, flag, &dbId)); - if (exist && CTG_TBTYPE_MATCH(flag, (*pTableMeta)->tableType)) { - return TSDB_CODE_SUCCESS; + int32_t tbType = 0; + + if (exist) { + if (CTG_FLAG_MATCH_STB(flag, (*pTableMeta)->tableType) && ((!CTG_FLAG_IS_FORCE_UPDATE(flag)) || (CTG_FLAG_IS_INF_DB(flag)))) { + goto _return; } - tfree(*pTableMeta); - } else if (CTG_IS_UNKNOWN_STB(flag)) { - int32_t tbType = 0; - - CTG_ERR_RET(ctgGetTableTypeFromCache(pCtg, pTableName, &tbType, flag)); + tbType = (*pTableMeta)->tableType; + suid = (*pTableMeta)->suid; - CTG_SET_STB(flag, tbType); + tfree(*pTableMeta); + } + + if (CTG_FLAG_IS_UNKNOWN_STB(flag)) { + CTG_FLAG_SET_STB(flag, tbType); } - STableMetaOutput *output = NULL; while (true) { CTG_ERR_JRET(ctgRefreshTblMeta(pCtg, pRpc, pMgmtEps, pTableName, flag, &output)); @@ -1662,7 +1757,7 @@ int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, cons SName stbName = *pTableName; strcpy(stbName.tname, output->tbName); - CTG_ERR_JRET(ctgGetTableMetaFromCache(pCtg, &stbName, pTableMeta, &exist, flag)); + CTG_ERR_JRET(ctgGetTableMetaFromCache(pCtg, &stbName, pTableMeta, &exist, flag, NULL)); if (0 == exist) { ctgDebug("stb no longer exist, dbFName:%s, tbName:%s", output->dbFName, pTableName->tname); continue; @@ -1675,10 +1770,26 @@ int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, cons _return: + if (CTG_TABLE_NOT_EXIST(code) && exist) { + char dbFName[TSDB_DB_FNAME_LEN] = {0}; + if (CTG_FLAG_IS_INF_DB(flag)) { + strcpy(dbFName, pTableName->dbname); + } else { + tNameGetFullDbName(pTableName, dbFName); + } + + if (TSDB_SUPER_TABLE == tbType) { + ctgPushRmStbMsgInQueue(pCtg, dbFName, dbId, pTableName->tname, suid); + } else { + ctgPushRmTblMsgInQueue(pCtg, dbFName, dbId, pTableName->tname); + } + } + tfree(output); if (*pTableMeta) { ctgDebug("tbmeta returned, tbName:%s, tbType:%d", pTableName->tname, (*pTableMeta)->tableType); + ctgDbgShowTableMeta(pCtg, pTableName->tname, *pTableMeta); } CTG_RET(code); @@ -1694,7 +1805,7 @@ int32_t ctgActUpdateVg(SCtgMetaAction *action) { _return: - tfree(msg->dbInfo); + ctgFreeVgInfo(msg->dbInfo); tfree(msg); CTG_RET(code); @@ -1780,7 +1891,6 @@ _return: int32_t ctgActRemoveStb(SCtgMetaAction *action) { int32_t code = 0; SCtgRemoveStbMsg *msg = action->data; - bool removed = false; SCatalog* pCtg = msg->pCtg; SCtgDBCache *dbCache = NULL; @@ -1826,7 +1936,36 @@ _return: } int32_t ctgActRemoveTbl(SCtgMetaAction *action) { + int32_t code = 0; + SCtgRemoveTblMsg *msg = action->data; + SCatalog* pCtg = msg->pCtg; + + SCtgDBCache *dbCache = NULL; + ctgGetDBCache(pCtg, msg->dbFName, &dbCache); + if (NULL == dbCache) { + return TSDB_CODE_SUCCESS; + } + + if (dbCache->dbId != msg->dbId) { + ctgDebug("dbId already modified, dbFName:%s, current:%"PRIx64", dbId:%"PRIx64", tbName:%s", msg->dbFName, dbCache->dbId, msg->dbId, msg->tbName); + return TSDB_CODE_SUCCESS; + } + + CTG_LOCK(CTG_READ, &dbCache->tbCache.metaLock); + if (taosHashRemove(dbCache->tbCache.metaCache, msg->tbName, strlen(msg->tbName))) { + CTG_UNLOCK(CTG_READ, &dbCache->tbCache.metaLock); + ctgError("stb not exist in cache, dbFName:%s, tbName:%s", msg->dbFName, msg->tbName); + CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + CTG_UNLOCK(CTG_READ, &dbCache->tbCache.metaLock); + + ctgInfo("table removed from cache, dbFName:%s, tbName:%s", msg->dbFName, msg->tbName); + +_return: + tfree(msg); + + CTG_RET(code); } @@ -1846,12 +1985,15 @@ void* ctgUpdateThreadFunc(void* param) { SCtgMetaAction *action = NULL; ctgPopAction(&action); + SCatalog *pCtg = ((SCtgUpdateMsgHeader *)action->data)->pCtg; - qDebug("process %s action", gCtgAction[action->act].name); + ctgDebug("process [%s] action", gCtgAction[action->act].name); (*gCtgAction[action->act].func)(action); CTG_STAT_ADD(gCtgMgmt.stat.runtime.qDoneNum); + + ctgDbgShowClusterCache(pCtg); } CTG_UNLOCK(CTG_READ, &gCtgMgmt.lock); @@ -2121,22 +2263,20 @@ int32_t catalogUpdateDBVgInfo(SCatalog* pCtg, const char* dbFName, uint64_t dbId strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName)); msg->dbId = dbId; msg->dbInfo = dbInfo; - dbInfo = NULL; action.data = msg; CTG_ERR_JRET(ctgPushAction(&action)); + dbInfo = NULL; + ctgDebug("action [%s] added into queue", gCtgAction[action.act].name); CTG_API_LEAVE(code); _return: - if (dbInfo) { - taosHashCleanup(dbInfo->vgHash); - tfree(dbInfo); - } + ctgFreeVgInfo(dbInfo); tfree(msg); @@ -2179,31 +2319,12 @@ int32_t catalogRemoveStbMeta(SCatalog* pCtg, const char* dbFName, uint64_t dbId, CTG_API_LEAVE(TSDB_CODE_SUCCESS); } - SCtgMetaAction action= {.act = CTG_ACT_REMOVE_STB}; - SCtgRemoveStbMsg *msg = malloc(sizeof(SCtgRemoveStbMsg)); - if (NULL == msg) { - ctgError("malloc %d failed", (int32_t)sizeof(SCtgRemoveStbMsg)); - CTG_API_LEAVE(TSDB_CODE_CTG_MEM_ERROR); - } - - msg->pCtg = pCtg; - strncpy(msg->dbFName, dbFName, sizeof(msg->dbFName)); - strncpy(msg->stbName, stbName, sizeof(msg->stbName)); - msg->dbId = dbId; - msg->suid = suid; - - action.data = msg; - - CTG_ERR_JRET(ctgPushAction(&action)); - - ctgDebug("action [%s] added into queue", gCtgAction[action.act].name); + CTG_ERR_JRET(ctgPushRmStbMsgInQueue(pCtg, dbFName, dbId, stbName, suid)); CTG_API_LEAVE(TSDB_CODE_SUCCESS); _return: - tfree(action.data); - CTG_API_LEAVE(code); } @@ -2211,13 +2332,13 @@ _return: int32_t catalogGetTableMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta) { CTG_API_ENTER(); - CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, false, pTableMeta, CTG_FLAG_UNKNOWN_STB)); + CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, pTableMeta, CTG_FLAG_UNKNOWN_STB)); } int32_t catalogGetSTableMeta(SCatalog* pCtg, void * pTrans, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta) { CTG_API_ENTER(); - CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, false, pTableMeta, CTG_FLAG_STB)); + CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, pTableMeta, CTG_FLAG_STB)); } int32_t catalogUpdateSTableMeta(SCatalog* pCtg, STableMetaRsp *rspMsg) { @@ -2279,13 +2400,13 @@ int32_t catalogRefreshTableMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgm CTG_API_LEAVE(TSDB_CODE_CTG_INVALID_INPUT); } - CTG_API_LEAVE(ctgRefreshTblMeta(pCtg, pTrans, pMgmtEps, pTableName, CTG_GEN_STB_FLAG(isSTable), NULL)); + CTG_API_LEAVE(ctgRefreshTblMeta(pCtg, pTrans, pMgmtEps, pTableName, CTG_FLAG_FORCE_UPDATE | CTG_FLAG_MAKE_STB(isSTable), NULL)); } int32_t catalogRefreshGetTableMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, const SName* pTableName, STableMeta** pTableMeta, int32_t isSTable) { CTG_API_ENTER(); - CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, true, pTableMeta, CTG_GEN_STB_FLAG(isSTable))); + CTG_API_LEAVE(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, pTableName, pTableMeta, CTG_FLAG_FORCE_UPDATE | CTG_FLAG_MAKE_STB(isSTable))); } int32_t catalogGetTableDistVgInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const SName* pTableName, SArray** pVgList) { @@ -2309,7 +2430,7 @@ int32_t catalogGetTableDistVgInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgm *pVgList = NULL; - CTG_ERR_JRET(ctgGetTableMeta(pCtg, pRpc, pMgmtEps, pTableName, false, &tbMeta, CTG_FLAG_UNKNOWN_STB)); + CTG_ERR_JRET(ctgGetTableMeta(pCtg, pRpc, pMgmtEps, pTableName, &tbMeta, CTG_FLAG_UNKNOWN_STB)); char db[TSDB_DB_FNAME_LEN] = {0}; tNameGetFullDbName(pTableName, db); @@ -2441,7 +2562,7 @@ int32_t catalogGetAllMeta(SCatalog* pCtg, void *pTrans, const SEpSet* pMgmtEps, SName *name = taosArrayGet(pReq->pTableName, i); STableMeta *pTableMeta = NULL; - CTG_ERR_JRET(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, name, false, &pTableMeta, CTG_FLAG_UNKNOWN_STB)); + CTG_ERR_JRET(ctgGetTableMeta(pCtg, pTrans, pMgmtEps, name, &pTableMeta, CTG_FLAG_UNKNOWN_STB)); if (NULL == taosArrayPush(pRsp->pTableMeta, &pTableMeta)) { ctgError("taosArrayPush failed, idx:%d", i); diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp index b7432429f4cf59b24a06b366b5db01f29211f78d..b417a645be2423a241af39667c302e8985159229 100644 --- a/source/libs/catalog/test/catalogTests.cpp +++ b/source/libs/catalog/test/catalogTests.cpp @@ -38,7 +38,7 @@ namespace { extern "C" int32_t ctgGetTableMetaFromCache(struct SCatalog *pCatalog, const SName *pTableName, STableMeta **pTableMeta, - int32_t *exist, int32_t flag); + int32_t *exist, int32_t flag, uint64_t *dbId); extern "C" int32_t ctgDbgGetClusterCacheNum(struct SCatalog* pCatalog, int32_t type); extern "C" int32_t ctgActUpdateTbl(SCtgMetaAction *action); extern "C" int32_t ctgDbgEnableDebug(char *option); @@ -57,12 +57,14 @@ enum { CTGT_RSP_CTBMETA, CTGT_RSP_STBMETA, CTGT_RSP_MSTBMETA, + CTGT_RSP_TBMETA_NOT_EXIST, }; bool ctgTestStop = false; bool ctgTestEnableSleep = false; +bool ctgTestEnableLog = true; bool ctgTestDeadLoop = false; -int32_t ctgTestPrintNum = 200000; +int32_t ctgTestPrintNum = 10000; int32_t ctgTestMTRunSec = 5; int32_t ctgTestCurrentVgVersion = 0; @@ -74,14 +76,18 @@ int32_t ctgTestSVersion = 1; int32_t ctgTestTVersion = 1; int32_t ctgTestSuid = 2; uint64_t ctgTestDbId = 33; +uint64_t ctgTestNormalTblUid = 1; uint64_t ctgTestClusterId = 0x1; char *ctgTestDbname = "1.db1"; char *ctgTestTablename = "table1"; char *ctgTestCTablename = "ctable1"; char *ctgTestSTablename = "stable1"; +char *ctgTestCurrentCTableName = NULL; +char *ctgTestCurrentTableName = NULL; +char *ctgTestCurrentSTableName = NULL; -int32_t ctgTestRspFunc[10] = {0}; +int32_t ctgTestRspFunc[100] = {0}; int32_t ctgTestRspIdx = 0; void sendCreateDbMsg(void *shandle, SEpSet *pEpSet) { @@ -123,6 +129,10 @@ void sendCreateDbMsg(void *shandle, SEpSet *pEpSet) { } void ctgTestInitLogFile() { + if (!ctgTestEnableLog) { + return; + } + const char *defaultLogFileNamePrefix = "taoslog"; const int32_t maxLogFileNum = 10; @@ -131,6 +141,8 @@ void ctgTestInitLogFile() { strcpy(tsLogDir, "/var/log/taos"); ctgDbgEnableDebug("api"); + ctgDbgEnableDebug("meta"); + ctgDbgEnableDebug("cache"); if (taosInitLog(defaultLogFileNamePrefix, maxLogFileNum) < 0) { printf("failed to open log file in directory:%s\n", tsLogDir); @@ -321,7 +333,7 @@ void ctgTestRspTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg * metaRsp.sversion = ctgTestSVersion; metaRsp.tversion = ctgTestTVersion; metaRsp.suid = 0; - metaRsp.tuid = 0x0000000000000001; + metaRsp.tuid = ctgTestNormalTblUid++; metaRsp.vgId = 8; metaRsp.pSchemas = (SSchema *)malloc((metaRsp.numOfTags + metaRsp.numOfColumns) * sizeof(SSchema)); @@ -349,10 +361,15 @@ void ctgTestRspTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg * tFreeSTableMetaRsp(&metaRsp); } +void ctgTestRspTableMetaNotExist(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { + pRsp->code = CTG_ERR_CODE_TABLE_NOT_EXIST; +} + + void ctgTestRspCTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { STableMetaRsp metaRsp = {0}; strcpy(metaRsp.dbFName, ctgTestDbname); - strcpy(metaRsp.tbName, ctgTestCTablename); + strcpy(metaRsp.tbName, ctgTestCurrentCTableName ? ctgTestCurrentCTableName : ctgTestCTablename); strcpy(metaRsp.stbName, ctgTestSTablename); metaRsp.numOfTags = ctgTestTagNum; metaRsp.numOfColumns = ctgTestColNum; @@ -399,7 +416,7 @@ void ctgTestRspCTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg void ctgTestRspSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp) { STableMetaRsp metaRsp = {0}; strcpy(metaRsp.dbFName, ctgTestDbname); - strcpy(metaRsp.tbName, ctgTestSTablename); + strcpy(metaRsp.tbName, ctgTestCurrentSTableName ? ctgTestCurrentSTableName : ctgTestSTablename); strcpy(metaRsp.stbName, ctgTestSTablename); metaRsp.numOfTags = ctgTestTagNum; metaRsp.numOfColumns = ctgTestColNum; @@ -409,7 +426,7 @@ void ctgTestRspSTableMeta(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg metaRsp.sversion = ctgTestSVersion; metaRsp.tversion = ctgTestTVersion; metaRsp.suid = ctgTestSuid; - metaRsp.tuid = ctgTestSuid; + metaRsp.tuid = ctgTestSuid++; metaRsp.vgId = 0; metaRsp.pSchemas = (SSchema *)malloc((metaRsp.numOfTags + metaRsp.numOfColumns) * sizeof(SSchema)); @@ -511,6 +528,9 @@ void ctgTestRspByIdx(void *shandle, SEpSet *pEpSet, SRpcMsg *pMsg, SRpcMsg *pRsp case CTGT_RSP_MSTBMETA: ctgTestRspMultiSTableMeta(shandle, pEpSet, pMsg, pRsp); break; + case CTGT_RSP_TBMETA_NOT_EXIST: + ctgTestRspTableMetaNotExist(shandle, pEpSet, pMsg, pRsp); + break; default: break; } @@ -773,7 +793,7 @@ void *ctgTestGetCtableMetaThread(void *param) { strcpy(cn.tname, ctgTestCTablename); while (!ctgTestStop) { - code = ctgGetTableMetaFromCache(pCtg, &cn, &tbMeta, &exist, 0); + code = ctgGetTableMetaFromCache(pCtg, &cn, &tbMeta, &exist, 0, NULL); if (code || 0 == exist) { assert(0); } @@ -828,7 +848,7 @@ void *ctgTestSetCtableMetaThread(void *param) { return NULL; } -#if 0 +#if 1 TEST(tableMeta, normalTable) { @@ -860,7 +880,7 @@ TEST(tableMeta, normalTable) { ASSERT_EQ(vgInfo.epset.numOfEps, 3); while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_DB_NUM)) { - usleep(10000); + usleep(50000); } ctgTestSetRspTableMeta(); @@ -870,6 +890,7 @@ TEST(tableMeta, normalTable) { ASSERT_EQ(code, 0); ASSERT_EQ(tableMeta->vgId, 8); ASSERT_EQ(tableMeta->tableType, TSDB_NORMAL_TABLE); + ASSERT_EQ(tableMeta->uid, ctgTestNormalTblUid - 1); ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); @@ -880,7 +901,7 @@ TEST(tableMeta, normalTable) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (0 == n) { - usleep(10000); + usleep(50000); } else { break; } @@ -975,7 +996,7 @@ TEST(tableMeta, childTableCase) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (0 == n) { - usleep(10000); + usleep(50000); } else { break; } @@ -994,7 +1015,7 @@ TEST(tableMeta, childTableCase) { ASSERT_EQ(tableMeta->tableInfo.precision, 1); ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); - tableMeta = NULL; + tfree(tableMeta); strcpy(n.tname, ctgTestSTablename); code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); @@ -1074,8 +1095,8 @@ TEST(tableMeta, superTableCase) { ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); - ASSERT_EQ(tableMeta->uid, ctgTestSuid); - ASSERT_EQ(tableMeta->suid, ctgTestSuid); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); ASSERT_EQ(tableMeta->tableInfo.precision, 1); @@ -1084,7 +1105,7 @@ TEST(tableMeta, superTableCase) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (0 == n) { - usleep(10000); + usleep(50000); } else { break; } @@ -1111,7 +1132,7 @@ TEST(tableMeta, superTableCase) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (2 != n) { - usleep(10000); + usleep(50000); } else { break; } @@ -1199,8 +1220,8 @@ TEST(tableMeta, rmStbMeta) { ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); - ASSERT_EQ(tableMeta->uid, ctgTestSuid); - ASSERT_EQ(tableMeta->suid, ctgTestSuid); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); ASSERT_EQ(tableMeta->tableInfo.precision, 1); @@ -1209,21 +1230,21 @@ TEST(tableMeta, rmStbMeta) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (0 == n) { - usleep(10000); + usleep(50000); } else { break; } } - code = catalogRemoveStbMeta(pCtg, "1.db1", ctgTestDbId, ctgTestSTablename, ctgTestSuid); + code = catalogRemoveStbMeta(pCtg, "1.db1", ctgTestDbId, ctgTestSTablename, ctgTestSuid - 1); ASSERT_EQ(code, 0); while (true) { int32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); int32_t m = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_STB_RENT_NUM); if (n || m) { - usleep(10000); + usleep(50000); } else { break; } @@ -1269,8 +1290,8 @@ TEST(tableMeta, updateStbMeta) { ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); - ASSERT_EQ(tableMeta->uid, ctgTestSuid); - ASSERT_EQ(tableMeta->suid, ctgTestSuid); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); ASSERT_EQ(tableMeta->tableInfo.precision, 1); @@ -1279,7 +1300,7 @@ TEST(tableMeta, updateStbMeta) { while (true) { uint32_t n = ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM); if (0 == n) { - usleep(10000); + usleep(50000); } else { break; } @@ -1299,7 +1320,7 @@ TEST(tableMeta, updateStbMeta) { uint64_t n = 0; ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); if (n != 3) { - usleep(10000); + usleep(50000); } else { break; } @@ -1330,6 +1351,499 @@ TEST(tableMeta, updateStbMeta) { memset(&gCtgMgmt.stat, 0, sizeof(gCtgMgmt.stat)); } +TEST(refreshGetMeta, normal2normal) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_TBMETA; + ctgTestRspFunc[2] = CTGT_RSP_TBMETA; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 8); + ASSERT_EQ(tableMeta->tableType, TSDB_NORMAL_TABLE); + ASSERT_EQ(tableMeta->uid, ctgTestNormalTblUid - 1); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, 0); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 8); + ASSERT_EQ(tableMeta->tableType, TSDB_NORMAL_TABLE); + ASSERT_EQ(tableMeta->uid, ctgTestNormalTblUid - 1); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, 0); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); +} + +TEST(refreshGetMeta, normal2notexist) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_TBMETA; + ctgTestRspFunc[2] = CTGT_RSP_TBMETA_NOT_EXIST; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 8); + ASSERT_EQ(tableMeta->tableType, TSDB_NORMAL_TABLE); + ASSERT_EQ(tableMeta->uid, ctgTestNormalTblUid - 1); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, 0); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, CTG_ERR_CODE_TABLE_NOT_EXIST); + ASSERT_TRUE(tableMeta == NULL); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); +} + + +TEST(refreshGetMeta, normal2child) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_TBMETA; + ctgTestRspFunc[2] = CTGT_RSP_CTBMETA; + ctgTestRspFunc[3] = CTGT_RSP_STBMETA; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + ctgTestCurrentCTableName = ctgTestTablename; + ctgTestCurrentSTableName = ctgTestSTablename; + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 8); + ASSERT_EQ(tableMeta->tableType, TSDB_NORMAL_TABLE); + ASSERT_EQ(tableMeta->uid, ctgTestNormalTblUid - 1); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, 0); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 9); + ASSERT_EQ(tableMeta->tableType, TSDB_CHILD_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); + ctgTestCurrentCTableName = NULL; + ctgTestCurrentSTableName = NULL; +} + +TEST(refreshGetMeta, stable2child) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_STBMETA; + ctgTestRspFunc[2] = CTGT_RSP_STBMETA; + ctgTestRspFunc[3] = CTGT_RSP_CTBMETA; + ctgTestRspFunc[4] = CTGT_RSP_STBMETA; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + ctgTestCurrentSTableName = ctgTestTablename; + ctgTestCurrentCTableName = ctgTestTablename; + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 0); + ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + ctgTestCurrentSTableName = ctgTestSTablename; + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 9); + ASSERT_EQ(tableMeta->tableType, TSDB_CHILD_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); + ctgTestCurrentCTableName = NULL; + ctgTestCurrentSTableName = NULL; +} + +TEST(refreshGetMeta, stable2stable) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_STBMETA; + ctgTestRspFunc[2] = CTGT_RSP_STBMETA; + ctgTestRspFunc[3] = CTGT_RSP_STBMETA; + ctgTestRspFunc[4] = CTGT_RSP_STBMETA; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + ctgTestCurrentSTableName = ctgTestTablename; + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 0); + ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 0); + ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); + ctgTestCurrentCTableName = NULL; + ctgTestCurrentSTableName = NULL; +} + + +TEST(refreshGetMeta, child2stable) { + struct SCatalog *pCtg = NULL; + void *mockPointer = (void *)0x1; + SVgroupInfo vgInfo = {0}; + SArray *vgList = NULL; + + ctgTestInitLogFile(); + + memset(ctgTestRspFunc, 0, sizeof(ctgTestRspFunc)); + ctgTestRspIdx = 0; + ctgTestRspFunc[0] = CTGT_RSP_VGINFO; + ctgTestRspFunc[1] = CTGT_RSP_CTBMETA; + ctgTestRspFunc[2] = CTGT_RSP_STBMETA; + ctgTestRspFunc[3] = CTGT_RSP_STBMETA; + ctgTestRspFunc[4] = CTGT_RSP_STBMETA; + + ctgTestSetRspByIdx(); + + initQueryModuleMsgHandle(); + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + // sendCreateDbMsg(pConn->pTransporter, &pConn->pAppInfo->mgmtEp.epSet); + + code = catalogGetHandle(ctgTestClusterId, &pCtg); + ASSERT_EQ(code, 0); + + SName n = {.type = TSDB_TABLE_NAME_T, .acctId = 1}; + strcpy(n.dbname, "db1"); + strcpy(n.tname, ctgTestTablename); + ctgTestCurrentCTableName = ctgTestTablename; + ctgTestCurrentSTableName = ctgTestSTablename; + + code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); + ASSERT_EQ(code, 0); + ASSERT_EQ(vgInfo.vgId, 8); + ASSERT_EQ(vgInfo.epset.numOfEps, 3); + + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); + } + + STableMeta *tableMeta = NULL; + code = catalogGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 9); + ASSERT_EQ(tableMeta->tableType, TSDB_CHILD_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + while (2 != ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM)) { + usleep(50000); + } + + ctgTestCurrentSTableName = ctgTestTablename; + code = catalogRefreshGetTableMeta(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &tableMeta, 0); + ASSERT_EQ(code, 0); + ASSERT_EQ(tableMeta->vgId, 0); + ASSERT_EQ(tableMeta->tableType, TSDB_SUPER_TABLE); + ASSERT_EQ(tableMeta->sversion, ctgTestSVersion); + ASSERT_EQ(tableMeta->tversion, ctgTestTVersion); + ASSERT_EQ(tableMeta->uid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->suid, ctgTestSuid - 1); + ASSERT_EQ(tableMeta->tableInfo.numOfColumns, ctgTestColNum); + ASSERT_EQ(tableMeta->tableInfo.numOfTags, ctgTestTagNum); + ASSERT_EQ(tableMeta->tableInfo.precision, 1); + ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); + tfree(tableMeta); + + catalogDestroy(); + memset(&gCtgMgmt, 0, sizeof(gCtgMgmt)); + ctgTestCurrentCTableName = NULL; + ctgTestCurrentSTableName = NULL; +} + + TEST(tableDistVgroup, normalTable) { struct SCatalog *pCtg = NULL; void *mockPointer = (void *)0x1; @@ -1499,11 +2013,15 @@ TEST(dbVgroup, getSetDbVgroupCase) { ASSERT_EQ(code, 0); ASSERT_EQ(taosArrayGetSize((const SArray *)vgList), ctgTestVgNum); - while (0 == ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_DB_RENT_NUM)) { - usleep(10000); + while (true) { + uint64_t n = 0; + ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); + if (n > 0) { + break; + } + usleep(50000); } - code = catalogGetTableHashVgroup(pCtg, mockPointer, (const SEpSet *)mockPointer, &n, &vgInfo); ASSERT_EQ(code, 0); ASSERT_EQ(vgInfo.vgId, 8); @@ -1525,7 +2043,7 @@ TEST(dbVgroup, getSetDbVgroupCase) { uint64_t n = 0; ctgDbgGetStatNum("runtime.qDoneNum", (void *)&n); if (n != 3) { - usleep(10000); + usleep(50000); } else { break; } @@ -1749,7 +2267,7 @@ TEST(rentTest, allRent) { ASSERT_EQ(tableMeta->tableInfo.rowSize, 12); while (ctgDbgGetClusterCacheNum(pCtg, CTG_DBG_META_NUM) < i) { - usleep(10000); + usleep(50000); } code = catalogGetExpiredDBs(pCtg, &dbs, &num); diff --git a/source/libs/function/CMakeLists.txt b/source/libs/function/CMakeLists.txt index 9f700dbb3ccb3ab1c475789ab53b10fb0fa6bc4c..a10a542b6b2e094166202c6cb299801576d15234 100644 --- a/source/libs/function/CMakeLists.txt +++ b/source/libs/function/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src FUNCTION_SRC) -add_library(function ${FUNCTION_SRC}) +add_library(function STATIC ${FUNCTION_SRC}) target_include_directories( function PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/function" diff --git a/source/libs/index/CMakeLists.txt b/source/libs/index/CMakeLists.txt index 50e76abd3f4dc7c0d255baf08fce3d2a34a95606..047fc555a0c9f6b4549b2a0009b919a738fbf443 100644 --- a/source/libs/index/CMakeLists.txt +++ b/source/libs/index/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src INDEX_SRC) -add_library(index ${INDEX_SRC}) +add_library(index STATIC ${INDEX_SRC}) target_include_directories( index PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/index" diff --git a/source/libs/monitor/CMakeLists.txt b/source/libs/monitor/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..309d63691c28365e6cc9a551414a90987f50d015 --- /dev/null +++ b/source/libs/monitor/CMakeLists.txt @@ -0,0 +1,13 @@ +aux_source_directory(src MONITOR_SRC) +add_library(monitor STATIC ${MONITOR_SRC}) +target_include_directories( + monitor + PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/monitor" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) + +target_link_libraries(monitor os util common) + +if(${BUILD_TEST}) + add_subdirectory(test) +endif(${BUILD_TEST}) \ No newline at end of file diff --git a/source/libs/monitor/inc/monInt.h b/source/libs/monitor/inc/monInt.h new file mode 100644 index 0000000000000000000000000000000000000000..61f9980e4e3133469869e1fb7f649b2aa33ec1cc --- /dev/null +++ b/source/libs/monitor/inc/monInt.h @@ -0,0 +1,42 @@ +/* + * 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_MONITOR_INT_H_ +#define _TD_MONITOR_INT_H_ + +#include "monitor.h" + +#include "tarray.h" +#include "tlockfree.h" +#include "tjson.h" + +typedef struct { + SRWLatch lock; + SArray *logs; // array of SMonLogItem + int32_t maxLogs; + const char *server; + uint16_t port; +} SMonitor; + +typedef struct SMonInfo { + SArray *logs; // array of SMonLogItem + SJson *pJson; +} SMonInfo; + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_MONITOR_INT_H_*/ diff --git a/source/libs/monitor/src/monitor.c b/source/libs/monitor/src/monitor.c new file mode 100644 index 0000000000000000000000000000000000000000..811ee40dc8a00c330444fdb11af04a6b39266a68 --- /dev/null +++ b/source/libs/monitor/src/monitor.c @@ -0,0 +1,117 @@ +/* + * 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 "monInt.h" +#include "taoserror.h" +#include "thttp.h" +#include "tlog.h" +#include "ttime.h" + +static SMonitor tsMonitor = {0}; + +int32_t monInit(const SMonCfg *pCfg) { + tsMonitor.logs = taosArrayInit(16, sizeof(SMonInfo)); + if (tsMonitor.logs == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + tsMonitor.maxLogs = pCfg->maxLogs; + tsMonitor.server = pCfg->server; + tsMonitor.port = pCfg->port; + taosInitRWLatch(&tsMonitor.lock); + return 0; +} + +void monCleanup() { + taosArrayDestroy(tsMonitor.logs); + tsMonitor.logs = NULL; +} + +void monAddLogItem(SMonLogItem *pItem) { + taosWLockLatch(&tsMonitor.lock); + int32_t size = taosArrayGetSize(tsMonitor.logs); + if (size > tsMonitor.maxLogs) { + uInfo("too many logs for monitor"); + } else { + taosArrayPush(tsMonitor.logs, pItem); + } + taosWUnLockLatch(&tsMonitor.lock); +} + +SMonInfo *monCreateMonitorInfo() { + SMonInfo *pMonitor = calloc(1, sizeof(SMonInfo)); + if (pMonitor == NULL) return NULL; + + taosWLockLatch(&tsMonitor.lock); + pMonitor->logs = taosArrayDup(tsMonitor.logs); + taosArrayClear(tsMonitor.logs); + taosWUnLockLatch(&tsMonitor.lock); + + pMonitor->pJson = tjsonCreateObject(); + if (pMonitor->pJson == NULL || pMonitor->logs == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + monCleanupMonitorInfo(pMonitor); + return NULL; + } + + return pMonitor; +} + +void monCleanupMonitorInfo(SMonInfo *pMonitor) { + taosArrayDestroy(pMonitor->logs); + tjsonDelete(pMonitor->pJson); + free(pMonitor); +} + +void monSendReport(SMonInfo *pMonitor) { + char *pCont = tjsonToString(pMonitor->pJson); + if (pCont != NULL) { + taosSendHttpReport(tsMonitor.server, tsMonitor.port, pCont, strlen(pCont)); + free(pCont); + } +} + +void monSetBasicInfo(SMonInfo *pMonitor, SMonBasicInfo *pInfo) { + SJson *pJson = pMonitor->pJson; + tjsonAddDoubleToObject(pJson, "dnode_id", pInfo->dnode_id); + tjsonAddStringToObject(pJson, "dnode_ep", pInfo->dnode_ep); + + int64_t ms = taosGetTimestampMs(); + char buf[40] = {0}; + taosFormatUtcTime(buf, sizeof(buf), ms, TSDB_TIME_PRECISION_MILLI); + tjsonAddStringToObject(pJson, "ts", buf); +} + +void monSetClusterInfo(SMonInfo *pMonitor, SMonClusterInfo *pInfo) { + +} + +void monSetVgroupInfo(SMonInfo *pMonitor, SMonVgroupInfo *pInfo) { + +} + +void monSetGrantInfo(SMonInfo *pMonitor, SMonGrantInfo *pInfo) { + +} + +void monSetDnodeInfo(SMonInfo *pMonitor, SMonDnodeInfo *pInfo) { + +} + +void monSetDiskInfo(SMonInfo *pMonitor, SMonDiskInfo *pInfo) { + +} diff --git a/source/libs/monitor/test/CMakeLists.txt b/source/libs/monitor/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e3ab7e73373deaa163c8f07facf2e7f8f3b616b4 --- /dev/null +++ b/source/libs/monitor/test/CMakeLists.txt @@ -0,0 +1,14 @@ +enable_testing() + +aux_source_directory(. MONITOR_TEST_SRC) +add_executable(monitor_test ${MONITOR_TEST_SRC}) +target_link_libraries( + monitor_test + PUBLIC monitor + PUBLIC gtest_main +) + +add_test( + NAME monitor_test + COMMAND monitor_test +) diff --git a/source/libs/monitor/test/monTest.cpp b/source/libs/monitor/test/monTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1805d0c9cddaf80fda75fb02d3951de94183413 --- /dev/null +++ b/source/libs/monitor/test/monTest.cpp @@ -0,0 +1,33 @@ +/** + * @file monTest.cpp + * @author slguan (slguan@taosdata.com) + * @brief monitor module tests + * @version 1.0 + * @date 2022-03-05 + * + * @copyright Copyright (c) 2022 + * + */ + +#include +#include "os.h" + +#include "monitor.h" + +class MonitorTest : public ::testing::Test { + protected: + static void SetUpTestSuite() { root = "/tmp/monTest"; } + static void TearDownTestSuite() {} + + public: + void SetUp() override {} + void TearDown() override {} + + static const char *root; +}; + +const char *MonitorTest::root; + +TEST_F(MonitorTest, 01_Open_Close) { + +} diff --git a/source/libs/parser/CMakeLists.txt b/source/libs/parser/CMakeLists.txt index 417c56aba1402e273e3375c19db1acd91d7d6b7c..5d028686575b950732ba14e50f3ff25f1b233952 100644 --- a/source/libs/parser/CMakeLists.txt +++ b/source/libs/parser/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src PARSER_SRC) -add_library(parser ${PARSER_SRC}) +add_library(parser STATIC ${PARSER_SRC}) target_include_directories( parser PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/parser" diff --git a/source/libs/planner/CMakeLists.txt b/source/libs/planner/CMakeLists.txt index 14b4488e6a84e70129ff4bf3ba0826dee930f576..db5d31f22b9b20449cf3d4c729e89265e1eba906 100644 --- a/source/libs/planner/CMakeLists.txt +++ b/source/libs/planner/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src PLANNER_SRC) -add_library(planner ${PLANNER_SRC}) +add_library(planner STATIC ${PLANNER_SRC}) target_include_directories( planner PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/planner" diff --git a/source/libs/qcom/CMakeLists.txt b/source/libs/qcom/CMakeLists.txt index c63e54fb9b014d0e166187605b06cf4715b4015a..a9bf0f5594cb0bc36c2eee84c4fb373507b4118e 100644 --- a/source/libs/qcom/CMakeLists.txt +++ b/source/libs/qcom/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src QUERY_SRC) -add_library(qcom ${QUERY_SRC}) +add_library(qcom STATIC ${QUERY_SRC}) target_include_directories( qcom PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/qcom" diff --git a/source/libs/scheduler/CMakeLists.txt b/source/libs/scheduler/CMakeLists.txt index 1b4aee3ccf5f3a4ccea614fc98390fca4ec74df8..862ae7ccae82f40812145b8f0261d23f09b19402 100644 --- a/source/libs/scheduler/CMakeLists.txt +++ b/source/libs/scheduler/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src SCHEDULER_SRC) -add_library(scheduler ${SCHEDULER_SRC}) +add_library(scheduler STATIC ${SCHEDULER_SRC}) target_include_directories( scheduler diff --git a/source/libs/scheduler/inc/schedulerInt.h b/source/libs/scheduler/inc/schedulerInt.h index 42270cd6453a0e51d1f2a29d045b23898ab6ffe7..50c274ad483cfe80be135628d389985622ee3d4d 100644 --- a/source/libs/scheduler/inc/schedulerInt.h +++ b/source/libs/scheduler/inc/schedulerInt.h @@ -36,6 +36,11 @@ enum { SCH_WRITE, }; +typedef struct SSchTrans { + void *transInst; + void *transHandle; +} SSchTrans; + typedef struct SSchApiStat { } SSchApiStat; @@ -59,12 +64,13 @@ typedef struct SSchedulerMgmt { uint64_t taskId; // sequential taksId uint64_t sId; // schedulerId SSchedulerCfg cfg; - SHashObj *jobs; // key: queryId, value: SQueryJob* + int32_t jobRef; SSchedulerStat stat; } SSchedulerMgmt; typedef struct SSchCallbackParam { uint64_t queryId; + int64_t refId; uint64_t taskId; } SSchCallbackParam; @@ -75,7 +81,8 @@ typedef struct SSchLevel { int32_t taskFailed; int32_t taskSucceed; int32_t taskNum; - SArray *subTasks; // Element is SQueryTask + int32_t taskLaunchIdx; // launch startup index + SArray *subTasks; // Element is SQueryTask } SSchLevel; typedef struct SSchTask { @@ -105,6 +112,7 @@ typedef struct SSchJobAttr { } SSchJobAttr; typedef struct SSchJob { + int64_t refId; uint64_t queryId; SSchJobAttr attr; int32_t levelNum; @@ -119,7 +127,6 @@ typedef struct SSchJob { SHashObj *succTasks; // succeed tasks, key:taskid, value:SQueryTask* SHashObj *failTasks; // failed tasks, key:taskid, value:SQueryTask* - int32_t ref; int8_t status; SQueryNodeAddr resNode; tsem_t rspSem; @@ -168,6 +175,8 @@ typedef struct SSchJob { static int32_t schLaunchTask(SSchJob *job, SSchTask *task); static int32_t schBuildAndSendMsg(SSchJob *job, SSchTask *task, SQueryNodeAddr *addr, int32_t msgType); +SSchJob *schAcquireJob(int64_t refId); +int32_t schReleaseJob(int64_t refId); #ifdef __cplusplus } diff --git a/source/libs/scheduler/src/scheduler.c b/source/libs/scheduler/src/scheduler.c index f14b95873ac8b1d4929aa993c8b1e39ba8345f65..f1ed0cef7d3bdc93e1e1a7cd96fec47936f6e235 100644 --- a/source/libs/scheduler/src/scheduler.c +++ b/source/libs/scheduler/src/scheduler.c @@ -17,12 +17,17 @@ #include "tmsg.h" #include "query.h" #include "catalog.h" +#include "tref.h" -typedef struct SSchTrans { - void *transInst; - void *transHandle; -}SSchTrans; -static SSchedulerMgmt schMgmt = {0}; +SSchedulerMgmt schMgmt = {0}; + +FORCE_INLINE SSchJob *schAcquireJob(int64_t refId) { + return (SSchJob *)taosAcquireRef(schMgmt.jobRef, refId); +} + +FORCE_INLINE int32_t schReleaseJob(int64_t refId) { + return taosReleaseRef(schMgmt.jobRef, refId); +} uint64_t schGenTaskId(void) { return atomic_add_fetch_64(&schMgmt.taskId, 1); @@ -886,7 +891,7 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch } case TDMT_VND_DROP_TASK_RSP: { // SHOULD NEVER REACH HERE - SCH_TASK_ELOG("invalid status to handle drop task rsp, ref:%d", atomic_load_32(&pJob->ref)); + SCH_TASK_ELOG("invalid status to handle drop task rsp, refId:%" PRIx64, pJob->refId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); break; } @@ -908,28 +913,23 @@ _return: int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, int32_t rspCode) { int32_t code = 0; SSchCallbackParam *pParam = (SSchCallbackParam *)param; - SSchJob *pJob = NULL; SSchTask *pTask = NULL; - SSchJob **job = taosHashGet(schMgmt.jobs, &pParam->queryId, sizeof(pParam->queryId)); - if (NULL == job || NULL == (*job)) { - qError("QID:%"PRIx64" taosHashGet queryId not exist, may be dropped", pParam->queryId); + SSchJob *pJob = taosAcquireRef(schMgmt.jobRef, pParam->refId); + if (NULL == pJob) { + qError("QID:0x%" PRIx64 ",TID:0x%" PRIx64 "taosAcquireRef job failed, may be dropped, refId:%" PRIx64, pParam->queryId, pParam->taskId, pParam->refId); SCH_ERR_JRET(TSDB_CODE_QRY_JOB_FREED); } - pJob = *job; - - atomic_add_fetch_32(&pJob->ref, 1); - int32_t s = taosHashGetSize(pJob->execTasks); if (s <= 0) { - qError("QID:%"PRIx64",TID:%"PRId64" no task in execTask list", pParam->queryId, pParam->taskId); + SCH_JOB_ELOG("empty execTask list, refId:%" PRIx64 ", taskId:%" PRIx64, pParam->refId, pParam->taskId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); } SSchTask **task = taosHashGet(pJob->execTasks, &pParam->taskId, sizeof(pParam->taskId)); if (NULL == task || NULL == (*task)) { - qError("QID:%"PRIx64",TID:%"PRId64" taosHashGet taskId not exist", pParam->queryId, pParam->taskId); + SCH_JOB_ELOG("task not found in execTask list, refId:%" PRIx64 ", taskId:%" PRIx64, pParam->refId, pParam->taskId); SCH_ERR_JRET(TSDB_CODE_SCH_INTERNAL_ERROR); } @@ -942,7 +942,7 @@ int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, in _return: if (pJob) { - atomic_sub_fetch_32(&pJob->ref, 1); + taosReleaseRef(schMgmt.jobRef, pParam->refId); } tfree(param); @@ -1003,28 +1003,29 @@ int32_t schGetCallbackFp(int32_t msgType, __async_send_cb_fn_t *fp) { } -int32_t schAsyncSendMsg(void *transport, SEpSet* epSet, uint64_t qId, uint64_t tId, int32_t msgType, void *msg, uint32_t msgSize) { +int32_t schAsyncSendMsg(SSchJob *pJob, SSchTask *pTask, void *transport, SEpSet* epSet, int32_t msgType, void *msg, uint32_t msgSize) { int32_t code = 0; SSchTrans *trans = (SSchTrans *)transport; SMsgSendInfo* pMsgSendInfo = calloc(1, sizeof(SMsgSendInfo)); if (NULL == pMsgSendInfo) { - qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", qId, tId, (int32_t)sizeof(SMsgSendInfo)); + SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SMsgSendInfo)); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } SSchCallbackParam *param = calloc(1, sizeof(SSchCallbackParam)); if (NULL == param) { - qError("QID:%"PRIx64 ",TID:%"PRIx64 " calloc %d failed", qId, tId, (int32_t)sizeof(SSchCallbackParam)); + SCH_TASK_ELOG("calloc %d failed", (int32_t)sizeof(SSchCallbackParam)); SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); } __async_send_cb_fn_t fp = NULL; SCH_ERR_JRET(schGetCallbackFp(msgType, &fp)); - param->queryId = qId; - param->taskId = tId; + param->queryId = pJob->queryId; + param->refId = pJob->refId; + param->taskId = pTask->taskId; pMsgSendInfo->param = param; @@ -1040,7 +1041,7 @@ int32_t schAsyncSendMsg(void *transport, SEpSet* epSet, uint64_t qId, uint64_t t SCH_ERR_JRET(code); } - qDebug("QID:0x%"PRIx64 ",TID:0x%"PRIx64 " req msg sent, type:%d, %s", qId, tId, msgType, TMSG_INFO(msgType)); + SCH_TASK_DLOG("req msg sent, refId:%" PRIx64 ", type:%d, %s", pJob->refId, msgType, TMSG_INFO(msgType)); return TSDB_CODE_SUCCESS; _return: @@ -1160,7 +1161,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, atomic_store_32(&pTask->lastMsgType, msgType); SSchTrans trans = {.transInst = pJob->transport, .transHandle = pTask->handle}; - SCH_ERR_JRET(schAsyncSendMsg(&trans, &epSet, pJob->queryId, pTask->taskId, msgType, msg, msgSize)); + SCH_ERR_JRET(schAsyncSendMsg(pJob, pTask, &trans, &epSet, msgType, msg, msgSize)); if (isCandidateAddr) { SCH_ERR_RET(schRecordTaskExecNode(pJob, pTask, addr)); @@ -1283,7 +1284,60 @@ void schDropJobAllTasks(SSchJob *pJob) { schDropTaskInHashList(pJob, pJob->failTasks); } -static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryDag* pDag, struct SSchJob** job, const char* sql, bool syncSchedule) { + +int32_t schCancelJob(SSchJob *pJob) { + //TODO + + //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST + +} + +void schFreeJobImpl(void *job) { + if (NULL == job) { + return; + } + + SSchJob *pJob = job; + uint64_t queryId = pJob->queryId; + int64_t refId = pJob->refId; + + if (pJob->status == JOB_TASK_STATUS_EXECUTING) { + schCancelJob(pJob); + } + + schDropJobAllTasks(pJob); + + pJob->subPlans = NULL; // it is a reference to pDag->pSubplans + + int32_t numOfLevels = taosArrayGetSize(pJob->levels); + for(int32_t i = 0; i < numOfLevels; ++i) { + SSchLevel *pLevel = taosArrayGet(pJob->levels, i); + + int32_t numOfTasks = taosArrayGetSize(pLevel->subTasks); + for(int32_t j = 0; j < numOfTasks; ++j) { + SSchTask* pTask = taosArrayGet(pLevel->subTasks, j); + schFreeTask(pTask); + } + + taosArrayDestroy(pLevel->subTasks); + } + + taosHashCleanup(pJob->execTasks); + taosHashCleanup(pJob->failTasks); + taosHashCleanup(pJob->succTasks); + + taosArrayDestroy(pJob->levels); + taosArrayDestroy(pJob->nodeList); + + tfree(pJob->res); + + tfree(pJob); + + qDebug("QID:0x%"PRIx64" job freed, refId:%" PRIx64 ", pointer:%p", queryId, refId, pJob); +} + + +static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryDag* pDag, int64_t *job, const char* sql, bool syncSchedule) { qDebug("QID:0x%"PRIx64" job started", pDag->queryId); if (pNodeList == NULL || (pNodeList && taosArrayGetSize(pNodeList) <= 0)) { @@ -1327,21 +1381,20 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryDag* pDa tsem_init(&pJob->rspSem, 0, 0); - code = taosHashPut(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId), &pJob, POINTER_BYTES); - if (0 != code) { - if (HASH_NODE_EXIST(code)) { - SCH_JOB_ELOG("job already exist, isQueryJob:%d", pJob->attr.queryJob); - SCH_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT); - } else { - SCH_JOB_ELOG("taosHashPut job failed, errno:%d", errno); - SCH_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } + pJob->refId = taosAddRef(schMgmt.jobRef, pJob); + if (pJob->refId < 0) { + SCH_JOB_ELOG("taosHashPut job failed, error:%s", tstrerror(terrno)); + SCH_ERR_JRET(terrno); } + SCH_JOB_DLOG("job refId:%" PRIx64, pJob->refId); + pJob->status = JOB_TASK_STATUS_NOT_START; SCH_ERR_JRET(schLaunchJob(pJob)); - *(SSchJob **)job = pJob; + taosAcquireRef(schMgmt.jobRef, pJob->refId); + + *job = pJob->refId; if (syncSchedule) { SCH_JOB_DLOG("will wait for rsp now, job status:%d", SCH_GET_JOB_STATUS(pJob)); @@ -1349,25 +1402,20 @@ static int32_t schExecJobImpl(void *transport, SArray *pNodeList, SQueryDag* pDa } SCH_JOB_DLOG("job exec done, job status:%d", SCH_GET_JOB_STATUS(pJob)); + + taosReleaseRef(schMgmt.jobRef, pJob->refId); + return TSDB_CODE_SUCCESS; _return: - *(SSchJob **)job = NULL; - schedulerFreeJob(pJob); + schFreeJobImpl(pJob); SCH_RET(code); } -int32_t schCancelJob(SSchJob *pJob) { - //TODO - - //TODO MOVE ALL TASKS FROM EXEC LIST TO FAIL LIST - -} - int32_t schedulerInit(SSchedulerCfg *cfg) { - if (schMgmt.jobs) { + if (schMgmt.jobRef) { qError("scheduler already initialized"); return TSDB_CODE_QRY_INVALID_INPUT; } @@ -1381,9 +1429,9 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { } else { schMgmt.cfg.maxJobNum = SCHEDULE_DEFAULT_JOB_NUMBER; } - - schMgmt.jobs = taosHashInit(schMgmt.cfg.maxJobNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - if (NULL == schMgmt.jobs) { + + schMgmt.jobRef = taosOpenRef(schMgmt.cfg.maxJobNum, schFreeJobImpl); + if (schMgmt.jobRef < 0) { qError("init schduler jobs failed, num:%u", schMgmt.cfg.maxJobNum); SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } @@ -1398,24 +1446,28 @@ int32_t schedulerInit(SSchedulerCfg *cfg) { return TSDB_CODE_SUCCESS; } -int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, struct SSchJob** pJob, const char* sql, SQueryResult *pRes) { +int32_t schedulerExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, int64_t *pJob, const char* sql, SQueryResult *pRes) { if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob || NULL == pRes) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SCH_ERR_RET(schExecJobImpl(transport, nodeList, pDag, pJob, sql, true)); - pRes->code = atomic_load_32(&(*pJob)->errCode); - pRes->numOfRows = (*pJob)->resNumOfRows; + + SSchJob *job = taosAcquireRef(schMgmt.jobRef, *pJob); + pRes->code = atomic_load_32(&job->errCode); + pRes->numOfRows = job->resNumOfRows; + taosReleaseRef(schMgmt.jobRef, *pJob); return TSDB_CODE_SUCCESS; } -int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, struct SSchJob** pJob) { +int32_t schedulerAsyncExecJob(void *transport, SArray *pNodeList, SQueryDag* pDag, const char* sql, int64_t *pJob) { if (NULL == transport || NULL == pDag || NULL == pDag->pSubplans || NULL == pJob) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } SCH_ERR_RET(schExecJobImpl(transport, pNodeList, pDag, pJob, sql, false)); + return TSDB_CODE_SUCCESS; } @@ -1541,28 +1593,35 @@ _return: } -int32_t schedulerFetchRows(SSchJob *pJob, void** pData) { - if (NULL == pJob || NULL == pData) { +int32_t schedulerFetchRows(int64_t job, void** pData) { + if (NULL == pData) { SCH_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } int32_t code = 0; - atomic_add_fetch_32(&pJob->ref, 1); + SSchJob *pJob = taosAcquireRef(schMgmt.jobRef, job); + if (NULL == pJob) { + qError("acquire job from jobRef list failed, may be dropped, refId:%" PRIx64, job); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } int8_t status = SCH_GET_JOB_STATUS(pJob); if (status == JOB_TASK_STATUS_DROPPING) { SCH_JOB_ELOG("job is dropping, status:%d", status); - SCH_ERR_JRET(TSDB_CODE_SCH_STATUS_ERROR); + taosReleaseRef(schMgmt.jobRef, job); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); } if (!SCH_JOB_NEED_FETCH(&pJob->attr)) { SCH_JOB_ELOG("no need to fetch data, status:%d", SCH_GET_JOB_STATUS(pJob)); - SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + taosReleaseRef(schMgmt.jobRef, job); + SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } if (atomic_val_compare_exchange_8(&pJob->userFetch, 0, 1) != 0) { SCH_JOB_ELOG("prior fetching not finished, userFetch:%d", atomic_load_8(&pJob->userFetch)); - SCH_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + taosReleaseRef(schMgmt.jobRef, job); + SCH_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } if (JOB_TASK_STATUS_FAILED == status || JOB_TASK_STATUS_DROPPING == status) { @@ -1588,7 +1647,6 @@ int32_t schedulerFetchRows(SSchJob *pJob, void** pData) { SCH_ERR_JRET(schCheckAndUpdateJobStatus(pJob, JOB_TASK_STATUS_SUCCEED)); } -_return: while (true) { *pData = atomic_load_ptr(&pJob->res); @@ -1609,96 +1667,47 @@ _return: SCH_JOB_DLOG("empty res and set query complete, code:%x", code); } - atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0); - SCH_JOB_DLOG("fetch done, totalRows:%d, code:%s", pJob->resNumOfRows, tstrerror(code)); - atomic_sub_fetch_32(&pJob->ref, 1); + +_return: + + atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0); + + taosReleaseRef(schMgmt.jobRef, job); SCH_RET(code); } -int32_t scheduleCancelJob(void *job) { - SSchJob *pJob = (SSchJob *)job; - - atomic_add_fetch_32(&pJob->ref, 1); +int32_t scheduleCancelJob(int64_t job) { + SSchJob *pJob = taosAcquireRef(schMgmt.jobRef, job); + if (NULL == pJob) { + qError("acquire job from jobRef list failed, may be dropped, refId:%" PRIx64, job); + SCH_ERR_RET(TSDB_CODE_SCH_STATUS_ERROR); + } int32_t code = schCancelJob(pJob); - atomic_sub_fetch_32(&pJob->ref, 1); + taosReleaseRef(schMgmt.jobRef, job); SCH_RET(code); } -void schedulerFreeJob(void *job) { - if (NULL == job) { +void schedulerFreeJob(int64_t job) { + SSchJob *pJob = taosAcquireRef(schMgmt.jobRef, job); + if (NULL == pJob) { + qError("acquire job from jobRef list failed, may be dropped, refId:%" PRIx64, job); return; } - SSchJob *pJob = job; - uint64_t queryId = pJob->queryId; - bool setJobFree = false; - - if (SCH_GET_JOB_STATUS(pJob) > 0) { - if (0 != taosHashRemove(schMgmt.jobs, &pJob->queryId, sizeof(pJob->queryId))) { - SCH_JOB_ELOG("taosHashRemove job from list failed, may already freed, pJob:%p", pJob); - return; - } - - SCH_JOB_DLOG("job removed from list, no further ref, ref:%d", atomic_load_32(&pJob->ref)); - - while (true) { - int32_t ref = atomic_load_32(&pJob->ref); - if (0 == ref) { - break; - } else if (ref > 0) { - if (1 == ref && atomic_load_8(&pJob->userFetch) > 0 && !setJobFree) { - schProcessOnJobDropped(pJob, TSDB_CODE_QRY_JOB_FREED); - setJobFree = true; - } - - usleep(1); - } else { - SCH_JOB_ELOG("invalid job ref number, ref:%d", ref); - break; - } - } - - SCH_JOB_DLOG("job no ref now, status:%d", SCH_GET_JOB_STATUS(pJob)); - - if (pJob->status == JOB_TASK_STATUS_EXECUTING) { - schCancelJob(pJob); - } - - schDropJobAllTasks(pJob); + if (atomic_load_8(&pJob->userFetch) > 0) { + schProcessOnJobDropped(pJob, TSDB_CODE_QRY_JOB_FREED); } - pJob->subPlans = NULL; // it is a reference to pDag->pSubplans - - int32_t numOfLevels = taosArrayGetSize(pJob->levels); - for(int32_t i = 0; i < numOfLevels; ++i) { - SSchLevel *pLevel = taosArrayGet(pJob->levels, i); - - int32_t numOfTasks = taosArrayGetSize(pLevel->subTasks); - for(int32_t j = 0; j < numOfTasks; ++j) { - SSchTask* pTask = taosArrayGet(pLevel->subTasks, j); - schFreeTask(pTask); - } + SCH_JOB_DLOG("start to remove job from jobRef list, refId:%" PRIx64, job); - taosArrayDestroy(pLevel->subTasks); + if (taosRemoveRef(schMgmt.jobRef, job)) { + SCH_JOB_ELOG("remove job from job list failed, refId:%" PRIx64, job); } - - taosHashCleanup(pJob->execTasks); - taosHashCleanup(pJob->failTasks); - taosHashCleanup(pJob->succTasks); - - taosArrayDestroy(pJob->levels); - taosArrayDestroy(pJob->nodeList); - - tfree(pJob->res); - - tfree(pJob); - - qDebug("QID:0x%"PRIx64" job freed", queryId); } void schedulerFreeTaskList(SArray *taskList) { @@ -1716,9 +1725,17 @@ void schedulerFreeTaskList(SArray *taskList) { } void schedulerDestroy(void) { - if (schMgmt.jobs) { - taosHashCleanup(schMgmt.jobs); //TODO - schMgmt.jobs = NULL; + if (schMgmt.jobRef) { + SSchJob *pJob = taosIterateRef(schMgmt.jobRef, 0); + + while (pJob) { + taosRemoveRef(schMgmt.jobRef, pJob->refId); + + pJob = taosIterateRef(schMgmt.jobRef, pJob->refId); + } + + taosCloseRef(schMgmt.jobRef); + schMgmt.jobRef = 0; } } diff --git a/source/libs/scheduler/test/schedulerTests.cpp b/source/libs/scheduler/test/schedulerTests.cpp index 89d365a7e7fe2410a5cfa8e3e7168b28f096540d..11ed3335e68c1f7d48aec528b1dd36bb8c0086f1 100644 --- a/source/libs/scheduler/test/schedulerTests.cpp +++ b/source/libs/scheduler/test/schedulerTests.cpp @@ -38,15 +38,15 @@ #include "schedulerInt.h" #include "stub.h" #include "addr_any.h" - +#include "tref.h" namespace { extern "C" int32_t schHandleResponseMsg(SSchJob *job, SSchTask *task, int32_t msgType, char *msg, int32_t msgSize, int32_t rspCode); extern "C" int32_t schHandleCallback(void* param, const SDataBuf* pMsg, int32_t msgType, int32_t rspCode); -struct SSchJob *pInsertJob = NULL; -struct SSchJob *pQueryJob = NULL; +int64_t insertJobRefId = 0; +int64_t queryJobRefId = 0; uint64_t schtMergeTemplateId = 0x4; uint64_t schtFetchTaskId = 0; @@ -65,6 +65,7 @@ void schtInitLogFile() { tsAsyncLog = 0; qDebugFlag = 159; + strcpy(tsLogDir, "/var/log/taos"); if (taosInitLog(defaultLogFileNamePrefix, maxLogFileNum) < 0) { printf("failed to open log file in directory:%s\n", tsLogDir); @@ -255,34 +256,40 @@ void schtSetAsyncSendMsgToServer() { void *schtSendRsp(void *param) { - SSchJob *job = NULL; + SSchJob *pJob = NULL; + int64_t job = 0; int32_t code = 0; while (true) { - job = *(SSchJob **)param; + job = *(int64_t *)param; if (job) { break; } usleep(1000); } + + pJob = schAcquireJob(job); - void *pIter = taosHashIterate(job->execTasks, NULL); + void *pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; SSubmitRsp rsp = {0}; rsp.affectedRows = 10; - schHandleResponseMsg(job, task, TDMT_VND_SUBMIT_RSP, (char *)&rsp, sizeof(rsp), 0); + schHandleResponseMsg(pJob, task, TDMT_VND_SUBMIT_RSP, (char *)&rsp, sizeof(rsp), 0); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } + schReleaseJob(job); + return NULL; } void *schtCreateFetchRspThread(void *param) { - struct SSchJob* job = (struct SSchJob*)param; + int64_t job = *(int64_t *)param; + SSchJob* pJob = schAcquireJob(job); sleep(1); @@ -291,8 +298,10 @@ void *schtCreateFetchRspThread(void *param) { rsp->completed = 1; rsp->numOfRows = 10; - code = schHandleResponseMsg(job, job->fetchTask, TDMT_VND_FETCH_RSP, (char *)rsp, sizeof(*rsp), 0); - + code = schHandleResponseMsg(pJob, pJob->fetchTask, TDMT_VND_FETCH_RSP, (char *)rsp, sizeof(*rsp), 0); + + schReleaseJob(job); + assert(code == 0); } @@ -329,9 +338,9 @@ void *schtFetchRspThread(void *aa) { void schtFreeQueryJob(int32_t freeThread) { static uint32_t freeNum = 0; - SSchJob *job = atomic_load_ptr(&pQueryJob); + int64_t job = queryJobRefId; - if (job && atomic_val_compare_exchange_ptr(&pQueryJob, job, NULL)) { + if (job && atomic_val_compare_exchange_64(&queryJobRefId, job, 0)) { schedulerFreeJob(job); if (freeThread) { if (++freeNum % schtTestPrintNum == 0) { @@ -360,7 +369,7 @@ void* schtRunJobThread(void *aa) { schtSetExecNode(); schtSetAsyncSendMsgToServer(); - SSchJob *job = NULL; + SSchJob *pJob = NULL; SSchCallbackParam *param = NULL; SHashObj *execTasks = NULL; SDataBuf dataBuf = {0}; @@ -376,24 +385,29 @@ void* schtRunJobThread(void *aa) { qnodeAddr.port = 6031; taosArrayPush(qnodeList, &qnodeAddr); - code = schedulerAsyncExecJob(mockPointer, qnodeList, &dag, "select * from tb", &job); + code = schedulerAsyncExecJob(mockPointer, qnodeList, &dag, "select * from tb", &queryJobRefId); assert(code == 0); + pJob = schAcquireJob(queryJobRefId); + if (NULL == pJob) { + taosArrayDestroy(qnodeList); + schtFreeQueryDag(&dag); + continue; + } + execTasks = taosHashInit(5, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), false, HASH_ENTRY_LOCK); - void *pIter = taosHashIterate(job->execTasks, NULL); + void *pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; schtFetchTaskId = task->taskId - 1; taosHashPut(execTasks, &task->taskId, sizeof(task->taskId), task, sizeof(*task)); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } param = (SSchCallbackParam *)calloc(1, sizeof(*param)); - param->queryId = schtQueryId; - - pQueryJob = job; - + param->refId = queryJobRefId; + param->queryId = pJob->queryId; pIter = taosHashIterate(execTasks, NULL); while (pIter) { @@ -412,8 +426,9 @@ void* schtRunJobThread(void *aa) { param = (SSchCallbackParam *)calloc(1, sizeof(*param)); - param->queryId = schtQueryId; - + param->refId = queryJobRefId; + param->queryId = pJob->queryId; + pIter = taosHashIterate(execTasks, NULL); while (pIter) { SSchTask *task = (SSchTask *)pIter; @@ -431,7 +446,8 @@ void* schtRunJobThread(void *aa) { param = (SSchCallbackParam *)calloc(1, sizeof(*param)); - param->queryId = schtQueryId; + param->refId = queryJobRefId; + param->queryId = pJob->queryId; pIter = taosHashIterate(execTasks, NULL); while (pIter) { @@ -450,7 +466,8 @@ void* schtRunJobThread(void *aa) { param = (SSchCallbackParam *)calloc(1, sizeof(*param)); - param->queryId = schtQueryId; + param->refId = queryJobRefId; + param->queryId = pJob->queryId; pIter = taosHashIterate(execTasks, NULL); while (pIter) { @@ -470,7 +487,7 @@ void* schtRunJobThread(void *aa) { atomic_store_32(&schtStartFetch, 1); void *data = NULL; - code = schedulerFetchRows(pQueryJob, &data); + code = schedulerFetchRows(queryJobRefId, &data); assert(code == 0 || code); if (0 == code) { @@ -480,12 +497,13 @@ void* schtRunJobThread(void *aa) { } data = NULL; - code = schedulerFetchRows(pQueryJob, &data); + code = schedulerFetchRows(queryJobRefId, &data); assert(code == 0 || code); schtFreeQueryJob(0); taosHashCleanup(execTasks); + taosArrayDestroy(qnodeList); schtFreeQueryDag(&dag); @@ -516,7 +534,7 @@ TEST(queryTest, normalCase) { char *dbname = "1.db1"; char *tablename = "table1"; SVgroupInfo vgInfo = {0}; - SSchJob *pJob = NULL; + int64_t job = 0; SQueryDag dag = {0}; schtInitLogFile(); @@ -537,59 +555,61 @@ TEST(queryTest, normalCase) { schtSetExecNode(); schtSetAsyncSendMsgToServer(); - code = schedulerAsyncExecJob(mockPointer, qnodeList, &dag, "select * from tb", &pJob); + code = schedulerAsyncExecJob(mockPointer, qnodeList, &dag, "select * from tb", &job); ASSERT_EQ(code, 0); - SSchJob *job = (SSchJob *)pJob; - void *pIter = taosHashIterate(job->execTasks, NULL); + + SSchJob *pJob = schAcquireJob(job); + + void *pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; SQueryTableRsp rsp = {0}; - code = schHandleResponseMsg(job, task, TDMT_VND_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(pJob, task, TDMT_VND_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } - pIter = taosHashIterate(job->execTasks, NULL); + pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; SResReadyRsp rsp = {0}; - code = schHandleResponseMsg(job, task, TDMT_VND_RES_READY_RSP, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(pJob, task, TDMT_VND_RES_READY_RSP, (char *)&rsp, sizeof(rsp), 0); printf("code:%d", code); ASSERT_EQ(code, 0); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } - pIter = taosHashIterate(job->execTasks, NULL); + pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; SQueryTableRsp rsp = {0}; - code = schHandleResponseMsg(job, task, TDMT_VND_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(pJob, task, TDMT_VND_QUERY_RSP, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } - pIter = taosHashIterate(job->execTasks, NULL); + pIter = taosHashIterate(pJob->execTasks, NULL); while (pIter) { SSchTask *task = *(SSchTask **)pIter; SResReadyRsp rsp = {0}; - code = schHandleResponseMsg(job, task, TDMT_VND_RES_READY_RSP, (char *)&rsp, sizeof(rsp), 0); + code = schHandleResponseMsg(pJob, task, TDMT_VND_RES_READY_RSP, (char *)&rsp, sizeof(rsp), 0); ASSERT_EQ(code, 0); - pIter = taosHashIterate(job->execTasks, pIter); + pIter = taosHashIterate(pJob->execTasks, pIter); } pthread_attr_t thattr; pthread_attr_init(&thattr); pthread_t thread1; - pthread_create(&(thread1), &thattr, schtCreateFetchRspThread, job); + pthread_create(&(thread1), &thattr, schtCreateFetchRspThread, &job); void *data = NULL; code = schedulerFetchRows(job, &data); @@ -603,9 +623,11 @@ TEST(queryTest, normalCase) { data = NULL; code = schedulerFetchRows(job, &data); ASSERT_EQ(code, 0); - ASSERT_TRUE(data); + ASSERT_TRUE(data == NULL); + + schReleaseJob(job); - schedulerFreeJob(pJob); + schedulerFreeJob(job); schtFreeQueryDag(&dag); @@ -644,14 +666,14 @@ TEST(insertTest, normalCase) { pthread_attr_init(&thattr); pthread_t thread1; - pthread_create(&(thread1), &thattr, schtSendRsp, &pInsertJob); + pthread_create(&(thread1), &thattr, schtSendRsp, &insertJobRefId); SQueryResult res = {0}; - code = schedulerExecJob(mockPointer, qnodeList, &dag, &pInsertJob, "insert into tb values(now,1)", &res); + code = schedulerExecJob(mockPointer, qnodeList, &dag, &insertJobRefId, "insert into tb values(now,1)", &res); ASSERT_EQ(code, 0); ASSERT_EQ(res.numOfRows, 20); - schedulerFreeJob(pInsertJob); + schedulerFreeJob(insertJobRefId); schedulerDestroy(); } @@ -684,4 +706,4 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -#pragma GCC diagnostic pop \ No newline at end of file +#pragma GCC diagnostic pop diff --git a/source/libs/sync/CMakeLists.txt b/source/libs/sync/CMakeLists.txt index cb38d7e3637a4cf11dff6ddc5d3e91354ad81587..cb196acc02e49c7e3aa85a1d522515d69ebf33ef 100644 --- a/source/libs/sync/CMakeLists.txt +++ b/source/libs/sync/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src SYNC_SRC) -add_library(sync ${SYNC_SRC}) +add_library(sync STATIC ${SYNC_SRC}) target_link_libraries( sync diff --git a/source/libs/transport/CMakeLists.txt b/source/libs/transport/CMakeLists.txt index a2e82201bfe416b731b3a1109c37687899c93cae..465646ac9539591b92103ed22dbc3ef1efa4049a 100644 --- a/source/libs/transport/CMakeLists.txt +++ b/source/libs/transport/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src TRANSPORT_SRC) -add_library(transport ${TRANSPORT_SRC}) +add_library(transport STATIC ${TRANSPORT_SRC}) target_include_directories( transport PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/transport" diff --git a/source/libs/wal/CMakeLists.txt b/source/libs/wal/CMakeLists.txt index bcf759e04f584648052cd45259e57a2aa74235c9..4cf7cff8186bf3625ad932223d14f5e36f97bed8 100644 --- a/source/libs/wal/CMakeLists.txt +++ b/source/libs/wal/CMakeLists.txt @@ -1,5 +1,5 @@ aux_source_directory(src WAL_SRC) -add_library(wal ${WAL_SRC}) +add_library(wal STATIC ${WAL_SRC}) target_include_directories( wal PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/wal" diff --git a/source/os/CMakeLists.txt b/source/os/CMakeLists.txt index 0eda9d637df074d3a4ad9a522ce8ce9d63bc8a94..c3bf94e88850b74121d3cfa1c4fde2ba13046efa 100644 --- a/source/os/CMakeLists.txt +++ b/source/os/CMakeLists.txt @@ -1,14 +1,10 @@ aux_source_directory(src OS_SRC) -add_library(os ${OS_SRC}) +add_library(os STATIC ${OS_SRC}) target_include_directories( os PUBLIC "${CMAKE_SOURCE_DIR}/include/os" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include" ) target_link_libraries( - os - PUBLIC pthread - PUBLIC dl - PUBLIC rt - PUBLIC m + os pthread dl rt m ) \ No newline at end of file diff --git a/source/os/src/osSysinfo.c b/source/os/src/osSysinfo.c index 163fad803fc11487101c3d106fe69343b4154c47..3e761c6d9164719963d01b138dea749e0b7d9ace 100644 --- a/source/os/src/osSysinfo.c +++ b/source/os/src/osSysinfo.c @@ -167,11 +167,9 @@ void taosGetSystemInfo() { tsTotalMemoryMB = taosGetTotalMemory(); float tmp1, tmp2; - // taosGetDisk(); taosGetBandSpeed(&tmp1); taosGetCpuUsage(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2); - } void taosKillSystem() { @@ -712,7 +710,6 @@ void taosGetSystemInfo() { float tmp1, tmp2; taosGetSysMemory(&tmp1); taosGetProcMemory(&tmp2); - // taosGetDisk(); taosGetBandSpeed(&tmp1); taosGetCpuUsage(&tmp1, &tmp2); taosGetProcIO(&tmp1, &tmp2); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index c8cafb93dde0b08edc329ebba1394bb047c3518b..176290ba38db5043ed4c4cfb07acdef0181a171e 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -345,6 +345,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO, "Invalid information t TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_AVAIL_DISK, "No available disk") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_MESSED_MSG, "TSDB messed message") TAOS_DEFINE_ERROR(TSDB_CODE_TDB_IVLD_TAG_VAL, "TSDB invalid tag value") +TAOS_DEFINE_ERROR(TSDB_CODE_TDB_NO_CACHE_LAST_ROW, "TSDB no cache last row data") // query TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_QHANDLE, "Invalid handle") diff --git a/source/util/src/thttp.c b/source/util/src/thttp.c index 14c39d3f03f6a59e921de174abe4425bec6f7441..adf29b1aa96e91e51e3e4515d684ffbf76d4c273 100644 --- a/source/util/src/thttp.c +++ b/source/util/src/thttp.c @@ -32,7 +32,7 @@ int32_t taosSendHttpReport(const char* server, uint16_t port, const char* pCont, fd = taosOpenTcpClientSocket(ip, port, 0); if (fd < 0) { terrno = TAOS_SYSTEM_ERROR(errno); - uError("failed to create http socket since %s", terrstr()); + uError("failed to create http socket to %s:%u since %s", server, port, terrstr()); goto SEND_OVER; } @@ -46,24 +46,24 @@ int32_t taosSendHttpReport(const char* server, uint16_t port, const char* pCont, if (taosWriteSocket(fd, (void*)header, headLen) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); - uError("failed to send http header since %s", terrstr()); + uError("failed to send http header to %s:%u since %s", server, port, terrstr()); goto SEND_OVER; } if (taosWriteSocket(fd, (void*)pCont, contLen) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); - uError("failed to send http content since %s", terrstr()); + uError("failed to send http content to %s:%u since %s", server, port, terrstr()); goto SEND_OVER; } // read something to avoid nginx error 499 if (taosReadSocket(fd, header, 10) < 0) { terrno = TAOS_SYSTEM_ERROR(errno); - uError("failed to receive response since %s", terrstr()); + uError("failed to receive response from %s:%u since %s", server, port, terrstr()); goto SEND_OVER; } - uInfo("send http to %s:%d, len:%d content: %s", server, port, contLen, pCont); + uInfo("send http to %s:%u, len:%d content: %s", server, port, contLen, pCont); code = 0; SEND_OVER: diff --git a/source/util/src/tjson.c b/source/util/src/tjson.c index 2c117771b12b5236c5599600a20c1eca3004a2c5..27848c4e2389cc0ff39ce3d248a2ab5cd06af159 100644 --- a/source/util/src/tjson.c +++ b/source/util/src/tjson.c @@ -26,7 +26,11 @@ SJson* tjsonCreateObject() { return pJson; } -void tjsonDelete(SJson* pJson) { cJSON_Delete((cJSON*)pJson); } +void tjsonDelete(SJson* pJson) { + if (pJson != NULL) { + cJSON_Delete((cJSON*)pJson); + } +} int32_t tjsonAddIntegerToObject(SJson* pJson, const char* pName, const uint64_t number) { char tmp[40] = {0};