From 8c6f452f09d3bc9fe66915d7415bfac553628c52 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Fri, 27 Oct 2023 15:51:52 +0800 Subject: [PATCH 01/43] tsdb/write: make last tier writable to mem --- source/dnode/vnode/src/tsdb/tsdbWrite.c | 6 +++--- source/dnode/vnode/src/vnd/vnodeSvr.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbWrite.c b/source/dnode/vnode/src/tsdb/tsdbWrite.c index 5949b103d5..1e6526da48 100644 --- a/source/dnode/vnode/src/tsdb/tsdbWrite.c +++ b/source/dnode/vnode/src/tsdb/tsdbWrite.c @@ -80,8 +80,8 @@ int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq2 *pMsg) { TSKEY minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep2; TSKEY maxKey = tsMaxKeyByPrecision[pCfg->precision]; int32_t size = taosArrayGetSize(pMsg->aSubmitTbData); - int32_t nlevel = tfsGetLevel(pTsdb->pVnode->pTfs); - + /* + int32_t nlevel = tfsGetLevel(pTsdb->pVnode->pTfs); if (nlevel > 1 && tsS3Enabled) { if (nlevel == 3) { minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep1; @@ -89,7 +89,7 @@ int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq2 *pMsg) { minKey = now - tsTickPerMin[pCfg->precision] * pCfg->keep0; } } - + */ for (int32_t i = 0; i < size; ++i) { SSubmitTbData *pData = TARRAY_GET_ELEM(pMsg->aSubmitTbData, i); if (pData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index c46ea15111..ed3b9460a6 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -13,13 +13,13 @@ * along with this program. If not, see . */ +#include "audit.h" #include "tencode.h" #include "tmsg.h" #include "vnd.h" #include "vndCos.h" #include "vnode.h" #include "vnodeInt.h" -#include "audit.h" static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); static int32_t vnodeProcessAlterStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); @@ -177,7 +177,7 @@ static int32_t vnodePreProcessDropTtlMsg(SVnode *pVnode, SRpcMsg *pMsg) { ttlReq.pTbUids = tbUids; } - { // prepare new content + { // prepare new content int32_t reqLenNew = tSerializeSVDropTtlTableReq(NULL, 0, &ttlReq); int32_t contLenNew = reqLenNew + sizeof(SMsgHead); @@ -262,8 +262,9 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int now *= 1000000; } - int32_t nlevel = tfsGetLevel(pVnode->pTfs); int32_t keep = pVnode->config.tsdbCfg.keep2; + /* + int32_t nlevel = tfsGetLevel(pVnode->pTfs); if (nlevel > 1 && tsS3Enabled) { if (nlevel == 3) { keep = pVnode->config.tsdbCfg.keep1; @@ -271,7 +272,7 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int keep = pVnode->config.tsdbCfg.keep0; } } - + */ TSKEY minKey = now - tsTickPerMin[pVnode->config.tsdbCfg.precision] * keep; TSKEY maxKey = tsMaxKeyByPrecision[pVnode->config.tsdbCfg.precision]; if (submitTbData.flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { @@ -584,7 +585,7 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t ver, SRpcMsg } } break; case TDMT_VND_STREAM_TASK_RESET: { - if (pVnode->restored/* && vnodeIsLeader(pVnode)*/) { + if (pVnode->restored /* && vnodeIsLeader(pVnode)*/) { tqProcessTaskResetReq(pVnode->pTq, pMsg); } } break; @@ -947,7 +948,7 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, taosArrayPush(rsp.pArray, &cRsp); - if(tsEnableAuditCreateTable){ + if (tsEnableAuditCreateTable) { int64_t clusterId = pVnode->config.syncCfg.nodeInfo[0].clusterId; SName name = {0}; @@ -1460,7 +1461,6 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, in int32_t nRow = TARRAY_SIZE(pSubmitTbData->aRowP); SRow **aRow = (SRow **)TARRAY_DATA(pSubmitTbData->aRowP); for (int32_t iRow = 0; iRow < nRow; ++iRow) { - if (aRow[iRow]->ts < minKey || aRow[iRow]->ts > maxKey || (iRow > 0 && aRow[iRow]->ts <= aRow[iRow - 1]->ts)) { code = TSDB_CODE_INVALID_MSG; vError("vgId:%d %s failed since %s, version:%" PRId64, TD_VID(pVnode), __func__, tstrerror(code), ver); @@ -1569,7 +1569,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, in if (terrno != TSDB_CODE_TDB_TABLE_ALREADY_EXIST) { code = terrno; vError("vgId:%d failed to create table:%s, code:%s", TD_VID(pVnode), pSubmitTbData->pCreateTbReq->name, - tstrerror(terrno)); + tstrerror(terrno)); goto _exit; } terrno = 0; From 4fede02da4b285940ddd8578f1ed485edf632458 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Mon, 30 Oct 2023 10:06:42 +0800 Subject: [PATCH 02/43] tsdb/retention: remove s3 evict cache hook --- source/dnode/vnode/src/tsdb/tsdbRetention.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index f2665dcf26..8fb7648c99 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -342,6 +342,7 @@ static int32_t tsdbDoRetention2(void *arg) { code = tsdbMigrateDataFileS3(rtner, fobj, &did); TSDB_CHECK_CODE(code, lino, _exit); } else { + /* if (tsS3Enabled) { int64_t fsize = 0; if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) { @@ -352,7 +353,7 @@ static int32_t tsdbDoRetention2(void *arg) { } s3EvictCache(fobj->fname, fsize * 2); } - + */ code = tsdbDoMigrateFileObj(rtner, fobj, &did); TSDB_CHECK_CODE(code, lino, _exit); } From 84d2f9c379b5299b874ec969759619bda512f273 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Mon, 30 Oct 2023 14:58:22 +0800 Subject: [PATCH 03/43] tsdb/upload: delay data file uploading --- source/common/src/tglobal.c | 25 ++++++++-- source/dnode/vnode/src/inc/vndCos.h | 1 + source/dnode/vnode/src/tsdb/tsdbCommit2.c | 38 ++++++++++++-- .../dnode/vnode/src/tsdb/tsdbReaderWriter.c | 2 + source/dnode/vnode/src/tsdb/tsdbRetention.c | 49 ++++++++++++------- 5 files changed, 87 insertions(+), 28 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 0a155f4ea1..a170e5436e 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -120,7 +120,7 @@ char tsSmlTsDefaultName[TSDB_COL_NAME_LEN] = "_ts"; char tsSmlTagName[TSDB_COL_NAME_LEN] = "_tag_null"; char tsSmlChildTableName[TSDB_TABLE_NAME_LEN] = ""; // user defined child table name can be specified in tag value. char tsSmlAutoChildTableNameDelimiter[TSDB_TABLE_NAME_LEN] = ""; - // If set to empty system will generate table name using MD5 hash. +// If set to empty system will generate table name using MD5 hash. // true means that the name and order of cols in each line are the same(only for influx protocol) // bool tsSmlDataFormat = false; // int32_t tsSmlBatchSize = 10000; @@ -273,6 +273,7 @@ char tsS3Hostname[TSDB_FQDN_LEN] = ""; int32_t tsS3BlockSize = 4096; // number of tsdb pages int32_t tsS3BlockCacheSize = 16; // number of blocks +int32_t tsS3UploadDelaySec = 60 * 60; int32_t tsCheckpointInterval = 300; @@ -453,7 +454,8 @@ static int32_t taosAddClientCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "queryUseNodeAllocator", tsQueryUseNodeAllocator, CFG_SCOPE_CLIENT) != 0) return -1; if (cfgAddBool(pCfg, "keepColumnName", tsKeepColumnName, CFG_SCOPE_CLIENT) != 0) return -1; if (cfgAddString(pCfg, "smlChildTableName", tsSmlChildTableName, CFG_SCOPE_CLIENT) != 0) return -1; - if (cfgAddString(pCfg, "smlAutoChildTableNameDelimiter", tsSmlAutoChildTableNameDelimiter, CFG_SCOPE_CLIENT) != 0) return -1; + if (cfgAddString(pCfg, "smlAutoChildTableNameDelimiter", tsSmlAutoChildTableNameDelimiter, CFG_SCOPE_CLIENT) != 0) + return -1; if (cfgAddString(pCfg, "smlTagName", tsSmlTagName, CFG_SCOPE_CLIENT) != 0) return -1; if (cfgAddString(pCfg, "smlTsDefaultName", tsSmlTsDefaultName, CFG_SCOPE_CLIENT) != 0) return -1; if (cfgAddBool(pCfg, "smlDot2Underline", tsSmlDot2Underline, CFG_SCOPE_CLIENT) != 0) return -1; @@ -665,7 +667,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddBool(pCfg, "disableStream", tsDisableStream, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt64(pCfg, "streamBufferSize", tsStreamBufferSize, 0, INT64_MAX, CFG_SCOPE_SERVER) != 0) return -1; - if (cfgAddInt64(pCfg, "checkpointInterval", tsStreamCheckpointTickInterval, 60, 1200, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt64(pCfg, "checkpointInterval", tsStreamCheckpointTickInterval, 60, 1200, CFG_SCOPE_SERVER) != 0) + return -1; if (cfgAddInt32(pCfg, "cacheLazyLoadThreshold", tsCacheLazyLoadThreshold, 0, 100000, CFG_SCOPE_SERVER) != 0) return -1; @@ -688,6 +691,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, 2048, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 10, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER) != 0) + return -1; // min free disk space used to check if the disk is full [50MB, 1GB] if (cfgAddInt64(pCfg, "minDiskFreeSize", tsMinDiskFreeSize, TFS_MIN_DISK_FREE_SIZE, 1024 * 1024 * 1024, @@ -946,7 +951,8 @@ static int32_t taosSetClientCfg(SConfig *pCfg) { return -1; } - tstrncpy(tsSmlAutoChildTableNameDelimiter, cfgGetItem(pCfg, "smlAutoChildTableNameDelimiter")->str, TSDB_TABLE_NAME_LEN); + tstrncpy(tsSmlAutoChildTableNameDelimiter, cfgGetItem(pCfg, "smlAutoChildTableNameDelimiter")->str, + TSDB_TABLE_NAME_LEN); tstrncpy(tsSmlChildTableName, cfgGetItem(pCfg, "smlChildTableName")->str, TSDB_TABLE_NAME_LEN); tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagName")->str, TSDB_COL_NAME_LEN); tstrncpy(tsSmlTsDefaultName, cfgGetItem(pCfg, "smlTsDefaultName")->str, TSDB_COL_NAME_LEN); @@ -1116,6 +1122,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsS3BlockSize = cfgGetItem(pCfg, "s3BlockSize")->i32; tsS3BlockCacheSize = cfgGetItem(pCfg, "s3BlockCacheSize")->i32; + tsS3UploadDelaySec = cfgGetItem(pCfg, "s3UploadDelaySec")->i32; GRANT_CFG_GET; return 0; @@ -1413,7 +1420,8 @@ int32_t taosApplyLocalCfg(SConfig *pCfg, char *name) { } else if (strcasecmp("smlChildTableName", name) == 0) { tstrncpy(tsSmlChildTableName, cfgGetItem(pCfg, "smlChildTableName")->str, TSDB_TABLE_NAME_LEN); } else if (strcasecmp("smlAutoChildTableNameDelimiter", name) == 0) { - tstrncpy(tsSmlAutoChildTableNameDelimiter, cfgGetItem(pCfg, "smlAutoChildTableNameDelimiter")->str, TSDB_TABLE_NAME_LEN); + tstrncpy(tsSmlAutoChildTableNameDelimiter, cfgGetItem(pCfg, "smlAutoChildTableNameDelimiter")->str, + TSDB_TABLE_NAME_LEN); } else if (strcasecmp("smlTagName", name) == 0) { tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagName")->str, TSDB_COL_NAME_LEN); // } else if (strcasecmp("smlDataFormat", name) == 0) { @@ -1708,6 +1716,13 @@ void taosCfgDynamicOptions(const char *option, const char *value) { return; } + if (strcasecmp(option, "s3UploadDelaySec") == 0) { + int32_t newS3UploadDelaysec = atoi(value); + uInfo("s3UploadDelaySec set from %d to %d", tsS3UploadDelaySec, newS3UploadDelaysec); + tsS3UploadDelaySec = newS3UploadDelaysec; + return; + } + if (strcasecmp(option, "ttlPushInterval") == 0) { int32_t newTtlPushInterval = atoi(value); uInfo("ttlPushInterval set from %d to %d", tsTtlPushIntervalSec, newTtlPushInterval); diff --git a/source/dnode/vnode/src/inc/vndCos.h b/source/dnode/vnode/src/inc/vndCos.h index bb4d284f0e..6612b5c653 100644 --- a/source/dnode/vnode/src/inc/vndCos.h +++ b/source/dnode/vnode/src/inc/vndCos.h @@ -27,6 +27,7 @@ extern "C" { extern int8_t tsS3Enabled; extern int32_t tsS3BlockSize; extern int32_t tsS3BlockCacheSize; +extern int32_t tsS3UploadDelaySec; int32_t s3Init(); void s3CleanUp(); diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c index 6dc492f420..c77c444125 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c @@ -46,6 +46,7 @@ typedef struct { STFileSet *fset; TABLEID tbid[1]; bool hasTSData; + bool skipTsRow; } ctx[1]; // reader @@ -127,18 +128,18 @@ static int32_t tsdbCommitTSData(SCommitter2 *committer) { continue; } } - + /* extern int8_t tsS3Enabled; int32_t nlevel = tfsGetLevel(committer->tsdb->pVnode->pTfs); - bool skipRow = false; + committer->ctx->skipTsRow = false; if (tsS3Enabled && nlevel > 1 && committer->ctx->did.level == nlevel - 1) { - skipRow = true; + committer->ctx->skipTsRow = true; } - + */ int64_t ts = TSDBROW_TS(&row->row); - if (skipRow && ts <= committer->ctx->maxKey) { + if (committer->ctx->skipTsRow && ts <= committer->ctx->maxKey) { ts = committer->ctx->maxKey + 1; } @@ -397,6 +398,33 @@ static int32_t tsdbCommitFileSetBegin(SCommitter2 *committer) { // reset nextKey committer->ctx->nextKey = TSKEY_MAX; + committer->ctx->skipTsRow = false; + + extern int8_t tsS3Enabled; + extern int32_t tsS3UploadDelaySec; + long s3Size(const char *object_name); + int32_t nlevel = tfsGetLevel(committer->tsdb->pVnode->pTfs); + committer->ctx->skipTsRow = false; + if (tsS3Enabled && nlevel > 1 /* && committer->ctx->did.level == nlevel - 1*/) { + STFileObj *fobj = committer->ctx->fset->farr[TSDB_FTYPE_DATA]; + if (committer->ctx->fset && fobj) { + // if exists on s3 or local mtime < committer->ctx->now - tsS3UploadDelay + const char *object_name = taosDirEntryBaseName((char *)fobj->fname); + + if (taosCheckExistFile(fobj->fname)) { + int32_t mtime = 0; + taosStatFile(fobj->fname, NULL, &mtime, NULL); + if (mtime < committer->ctx->now - tsS3UploadDelaySec) { + committer->ctx->skipTsRow = true; + } + } else if (s3Size(object_name) > 0) { + committer->ctx->skipTsRow = true; + } + } + + // new fset can be written with ts data + } + _exit: if (code) { TSDB_ERROR_LOG(TD_VID(tsdb->pVnode), lino, code); diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c index f3bcfef703..6904249adb 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c +++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c @@ -131,6 +131,7 @@ static int32_t tsdbWriteFilePage(STsdbFD *pFD) { } if (pFD->s3File) { + tsdbWarn("%s file:%d", __func__, pFD->path); return code; } if (pFD->pgno > 0) { @@ -286,6 +287,7 @@ int32_t tsdbFsyncFile(STsdbFD *pFD) { int32_t code = 0; if (pFD->s3File) { + tsdbWarn("%s file:%d", __func__, pFD->path); return code; } code = tsdbWriteFilePage(pFD); diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 8fb7648c99..4a5c8300cd 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -304,7 +304,8 @@ static int32_t tsdbDoRetention2(void *arg) { if (fobj == NULL) continue; int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); - if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && fobj->f->did.level == nlevel - 1) { + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && fobj->f->did.level == nlevel - 1 && + !taosCheckExistFile(fobj->fname)) { code = tsdbRemoveFileObjectS3(rtner, fobj); TSDB_CHECK_CODE(code, lino, _exit); } else { @@ -335,28 +336,40 @@ static int32_t tsdbDoRetention2(void *arg) { for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX && (fobj = rtner->ctx->fset->farr[ftype], 1); ++ftype) { if (fobj == NULL) continue; - if (fobj->f->did.level == did.level) continue; - int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); - if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1) { - code = tsdbMigrateDataFileS3(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); - } else { - /* - if (tsS3Enabled) { - int64_t fsize = 0; - if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) { - code = TAOS_SYSTEM_ERROR(terrno); - tsdbError("vgId:%d %s failed since file:%s stat failed, reason:%s", TD_VID(rtner->tsdb->pVnode), __func__, - fobj->fname, tstrerror(code)); + + if (fobj->f->did.level == did.level) { + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1 && + taosCheckExistFile(fobj->fname)) { + int32_t mtime = 0; + taosStatFile(fobj->fname, NULL, &mtime, NULL); + if (mtime < rtner->now - tsS3UploadDelaySec) { + code = tsdbMigrateDataFileS3(rtner, fobj, &did); TSDB_CHECK_CODE(code, lino, _exit); } - s3EvictCache(fobj->fname, fsize * 2); } - */ - code = tsdbDoMigrateFileObj(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); + + continue; } + /* + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1) { + code = tsdbMigrateDataFileS3(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + + if (tsS3Enabled) { + int64_t fsize = 0; + if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) { + code = TAOS_SYSTEM_ERROR(terrno); + tsdbError("vgId:%d %s failed since file:%s stat failed, reason:%s", TD_VID(rtner->tsdb->pVnode), + __func__, fobj->fname, tstrerror(code)); TSDB_CHECK_CODE(code, lino, _exit); + } + s3EvictCache(fobj->fname, fsize * 2); + } + */ + code = tsdbDoMigrateFileObj(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + //} } // stt From 800cbfbb056a763ed6ffac35d0a1d98cab6bbf32 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Mon, 30 Oct 2023 17:36:49 +0800 Subject: [PATCH 04/43] tsdb/file: new s3flag in mem --- source/dnode/mnode/impl/src/mndDnode.c | 34 ++++++++++++++++++++- source/dnode/vnode/src/tsdb/tsdbCommit2.c | 5 ++- source/dnode/vnode/src/tsdb/tsdbFile2.c | 1 + source/dnode/vnode/src/tsdb/tsdbFile2.h | 1 + source/dnode/vnode/src/tsdb/tsdbRetention.c | 2 ++ 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index b53dee7bff..50e5ec46b8 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -720,7 +720,7 @@ static int32_t mndProcessNotifyReq(SRpcMsg *pReq) { mndReleaseVgroup(pMnode, pVgroup); } } - mndUpdClusterInfo(pReq); + mndUpdClusterInfo(pReq); _OVER: tFreeSNotifyReq(¬ifyReq); return code; @@ -1235,6 +1235,38 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { strcpy(dcfgReq.config, "monitor"); snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); + } else if (strncasecmp(cfgReq.config, "s3blockcachesize", 16) == 0) { + int32_t optLen = strlen("s3blockcachesize"); + int32_t flag = -1; + int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); + if (code < 0) return code; + + if (flag < 4 || flag > 1024 * 1024) { + mError("dnode:%d, failed to config s3BlockCacheSize since value:%d. Valid range: [4, 1024 * 1024]", + cfgReq.dnodeId, flag); + terrno = TSDB_CODE_INVALID_CFG; + tFreeSMCfgDnodeReq(&cfgReq); + return -1; + } + + strcpy(dcfgReq.config, "s3blockcachesize"); + snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); + } else if (strncasecmp(cfgReq.config, "s3uploaddelaysec", 16) == 0) { + int32_t optLen = strlen("s3uploaddelaysec"); + int32_t flag = -1; + int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); + if (code < 0) return code; + + if (flag < 600 || flag > 60 * 60 * 24 * 30) { + mError("dnode:%d, failed to config s3UploadDelaySec since value:%d. Valid range: [600, 60 * 60 * 24 * 30]", + cfgReq.dnodeId, flag); + terrno = TSDB_CODE_INVALID_CFG; + tFreeSMCfgDnodeReq(&cfgReq); + return -1; + } + + strcpy(dcfgReq.config, "s3uploaddelaysec"); + snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); } else if (strncasecmp(cfgReq.config, "ttlpushinterval", 14) == 0) { int32_t optLen = strlen("ttlpushinterval"); int32_t flag = -1; diff --git a/source/dnode/vnode/src/tsdb/tsdbCommit2.c b/source/dnode/vnode/src/tsdb/tsdbCommit2.c index c77c444125..5357c52723 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCommit2.c +++ b/source/dnode/vnode/src/tsdb/tsdbCommit2.c @@ -405,9 +405,9 @@ static int32_t tsdbCommitFileSetBegin(SCommitter2 *committer) { long s3Size(const char *object_name); int32_t nlevel = tfsGetLevel(committer->tsdb->pVnode->pTfs); committer->ctx->skipTsRow = false; - if (tsS3Enabled && nlevel > 1 /* && committer->ctx->did.level == nlevel - 1*/) { + if (tsS3Enabled && nlevel > 1 && committer->ctx->fset) { STFileObj *fobj = committer->ctx->fset->farr[TSDB_FTYPE_DATA]; - if (committer->ctx->fset && fobj) { + if (fobj && fobj->f->did.level == nlevel - 1) { // if exists on s3 or local mtime < committer->ctx->now - tsS3UploadDelay const char *object_name = taosDirEntryBaseName((char *)fobj->fname); @@ -421,7 +421,6 @@ static int32_t tsdbCommitFileSetBegin(SCommitter2 *committer) { committer->ctx->skipTsRow = true; } } - // new fset can be written with ts data } diff --git a/source/dnode/vnode/src/tsdb/tsdbFile2.c b/source/dnode/vnode/src/tsdb/tsdbFile2.c index 963c5bad34..9edb03d35b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFile2.c +++ b/source/dnode/vnode/src/tsdb/tsdbFile2.c @@ -303,6 +303,7 @@ bool tsdbIsSameTFile(const STFile *f1, const STFile *f2) { if (f1->did.id != f2->did.id) return false; if (f1->fid != f2->fid) return false; if (f1->cid != f2->cid) return false; + if (f1->s3flag != f2->s3flag) return false; return true; } diff --git a/source/dnode/vnode/src/tsdb/tsdbFile2.h b/source/dnode/vnode/src/tsdb/tsdbFile2.h index 33d8ac5478..9da198c1f0 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFile2.h +++ b/source/dnode/vnode/src/tsdb/tsdbFile2.h @@ -58,6 +58,7 @@ int32_t tsdbTFileObjCmpr(const STFileObj **fobj1, const STFileObj **fobj2); struct STFile { tsdb_ftype_t type; SDiskID did; // disk id + int32_t s3flag; int32_t fid; // file id int64_t cid; // commit id int64_t size; diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 4a5c8300cd..cfeca531fc 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -211,6 +211,8 @@ static int32_t tsdbMigrateDataFileS3(SRTNer *rtner, const STFileObj *fobj, const }, }; + op.nf.s3flag = true; + code = TARRAY2_APPEND(rtner->fopArr, op); TSDB_CHECK_CODE(code, lino, _exit); From 867ce92dcc9f0c8e58591183a0672c442e3ec9ff Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Mon, 30 Oct 2023 19:28:18 +0800 Subject: [PATCH 05/43] tsdb/file-rw: fix log msg --- source/dnode/vnode/src/tsdb/tsdbReaderWriter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c index 6904249adb..65f0f1b94d 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c +++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c @@ -131,7 +131,7 @@ static int32_t tsdbWriteFilePage(STsdbFD *pFD) { } if (pFD->s3File) { - tsdbWarn("%s file:%d", __func__, pFD->path); + tsdbWarn("%s file: %s", __func__, pFD->path); return code; } if (pFD->pgno > 0) { @@ -287,7 +287,7 @@ int32_t tsdbFsyncFile(STsdbFD *pFD) { int32_t code = 0; if (pFD->s3File) { - tsdbWarn("%s file:%d", __func__, pFD->path); + tsdbWarn("%s file: %s", __func__, pFD->path); return code; } code = tsdbWriteFilePage(pFD); From a61502411df454c474ff2f70aadb4d311fc970bc Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 1 Nov 2023 10:49:05 +0800 Subject: [PATCH 06/43] tsdb/pg-cache: new page cache for tsdb s3 read file page --- source/dnode/vnode/src/inc/tsdb.h | 16 ++- source/dnode/vnode/src/tsdb/tsdbCache.c | 79 +++++++++++- .../dnode/vnode/src/tsdb/tsdbReaderWriter.c | 117 +++++++++++++++++- 3 files changed, 200 insertions(+), 12 deletions(-) diff --git a/source/dnode/vnode/src/inc/tsdb.h b/source/dnode/vnode/src/inc/tsdb.h index 79112babc3..857aef78dc 100644 --- a/source/dnode/vnode/src/inc/tsdb.h +++ b/source/dnode/vnode/src/inc/tsdb.h @@ -382,6 +382,8 @@ struct STsdb { TdThreadMutex biMutex; SLRUCache *bCache; TdThreadMutex bMutex; + SLRUCache *pgCache; + TdThreadMutex pgMutex; struct STFileSystem *pFS; // new SRocksCache rCache; }; @@ -677,9 +679,9 @@ typedef struct STSnapRange STSnapRange; typedef TARRAY2(STSnapRange *) TSnapRangeArray; // disjoint snap ranges // util -int32_t tSerializeSnapRangeArray(void *buf, int32_t bufLen, TSnapRangeArray *pSnapR); -int32_t tDeserializeSnapRangeArray(void *buf, int32_t bufLen, TSnapRangeArray *pSnapR); -void tsdbSnapRangeArrayDestroy(TSnapRangeArray **ppSnap); +int32_t tSerializeSnapRangeArray(void *buf, int32_t bufLen, TSnapRangeArray *pSnapR); +int32_t tDeserializeSnapRangeArray(void *buf, int32_t bufLen, TSnapRangeArray *pSnapR); +void tsdbSnapRangeArrayDestroy(TSnapRangeArray **ppSnap); SHashObj *tsdbGetSnapRangeHash(TSnapRangeArray *pRanges); // snap partition list @@ -873,8 +875,8 @@ int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf); void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter); bool tMergeTreeNext(SMergeTree *pMTree); -void tMergeTreePinSttBlock(SMergeTree* pMTree); -void tMergeTreeUnpinSttBlock(SMergeTree* pMTree); +void tMergeTreePinSttBlock(SMergeTree *pMTree); +void tMergeTreeUnpinSttBlock(SMergeTree *pMTree); bool tMergeTreeIgnoreEarlierTs(SMergeTree *pMTree); void tMergeTreeClose(SMergeTree *pMTree); @@ -909,7 +911,9 @@ int32_t tsdbCacheGetBlockIdx(SLRUCache *pCache, SDataFReader *pFileReader, LRUHa int32_t tsdbBICacheRelease(SLRUCache *pCache, LRUHandle *h); int32_t tsdbCacheGetBlockS3(SLRUCache *pCache, STsdbFD *pFD, LRUHandle **handle); -int32_t tsdbBCacheRelease(SLRUCache *pCache, LRUHandle *h); +int32_t tsdbCacheGetPageS3(SLRUCache *pCache, STsdbFD *pFD, int64_t pgno, LRUHandle **handle); +int32_t tsdbCacheSetPageS3(SLRUCache *pCache, STsdbFD *pFD, int64_t pgno, uint8_t *pPage); +int32_t tsdbCacheRelease(SLRUCache *pCache, LRUHandle *h); int32_t tsdbCacheDeleteLastrow(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey); int32_t tsdbCacheDeleteLast(SLRUCache *pCache, tb_uid_t uid, TSKEY eKey); diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index ca3fb7027f..7cea469c34 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -87,6 +87,41 @@ static void tsdbCloseBCache(STsdb *pTsdb) { } } +static int32_t tsdbOpenPgCache(STsdb *pTsdb) { + int32_t code = 0; + // SLRUCache *pCache = taosLRUCacheInit(10 * 1024 * 1024, 0, .5); + int32_t szPage = pTsdb->pVnode->config.tsdbPageSize; + + SLRUCache *pCache = taosLRUCacheInit((int64_t)tsS3BlockCacheSize * szPage, 0, .5); + if (pCache == NULL) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + + taosLRUCacheSetStrictCapacity(pCache, false); + + taosThreadMutexInit(&pTsdb->pgMutex, NULL); + +_err: + pTsdb->pgCache = pCache; + return code; +} + +static void tsdbClosePgCache(STsdb *pTsdb) { + SLRUCache *pCache = pTsdb->pgCache; + if (pCache) { + int32_t elems = taosLRUCacheGetElems(pCache); + tsdbTrace("vgId:%d, elems: %d", TD_VID(pTsdb->pVnode), elems); + taosLRUCacheEraseUnrefEntries(pCache); + elems = taosLRUCacheGetElems(pCache); + tsdbTrace("vgId:%d, elems: %d", TD_VID(pTsdb->pVnode), elems); + + taosLRUCacheCleanup(pCache); + + taosThreadMutexDestroy(&pTsdb->bMutex); + } +} + #define ROCKS_KEY_LEN (sizeof(tb_uid_t) + sizeof(int16_t) + sizeof(int8_t)) typedef struct { @@ -1191,6 +1226,12 @@ int32_t tsdbOpenCache(STsdb *pTsdb) { goto _err; } + code = tsdbOpenPgCache(pTsdb); + if (code != TSDB_CODE_SUCCESS) { + code = TSDB_CODE_OUT_OF_MEMORY; + goto _err; + } + code = tsdbOpenRocksCache(pTsdb); if (code != TSDB_CODE_SUCCESS) { code = TSDB_CODE_OUT_OF_MEMORY; @@ -1221,6 +1262,7 @@ void tsdbCloseCache(STsdb *pTsdb) { tsdbCloseBICache(pTsdb); tsdbCloseBCache(pTsdb); + tsdbClosePgCache(pTsdb); tsdbCloseRocksCache(pTsdb); } @@ -3057,7 +3099,6 @@ static int32_t tsdbCacheLoadBlockS3(STsdbFD *pFD, uint8_t **ppBlock) { } */ int64_t block_offset = (pFD->blkno - 1) * tsS3BlockSize * pFD->szPage; - // int64_t size = 4096; code = s3GetObjectBlock(pFD->objName, block_offset, tsS3BlockSize * pFD->szPage, ppBlock); if (code != TSDB_CODE_SUCCESS) { // taosMemoryFree(pBlock); @@ -3123,10 +3164,42 @@ int32_t tsdbCacheGetBlockS3(SLRUCache *pCache, STsdbFD *pFD, LRUHandle **handle) return code; } -int32_t tsdbBCacheRelease(SLRUCache *pCache, LRUHandle *h) { +int32_t tsdbCacheGetPageS3(SLRUCache *pCache, STsdbFD *pFD, int64_t pgno, LRUHandle **handle) { int32_t code = 0; + char key[128] = {0}; + int keyLen = 0; - taosLRUCacheRelease(pCache, h, false); + getBCacheKey(pFD->fid, pFD->cid, pFD->blkno, key, &keyLen); + *handle = taosLRUCacheLookup(pCache, key, keyLen); + + return code; +} + +int32_t tsdbCacheSetPageS3(SLRUCache *pCache, STsdbFD *pFD, int64_t pgno, uint8_t *pPage) { + int32_t code = 0; + char key[128] = {0}; + int keyLen = 0; + LRUHandle *handle = NULL; + + getBCacheKey(pFD->fid, pFD->cid, pgno, key, &keyLen); + taosThreadMutexLock(&pFD->pTsdb->pgMutex); + handle = taosLRUCacheLookup(pFD->pTsdb->pgCache, key, keyLen); + if (!handle) { + size_t charge = pFD->szPage; + _taos_lru_deleter_t deleter = deleteBCache; + uint8_t *pPg = taosMemoryMalloc(charge); + memcpy(pPg, pPage, charge); + + LRUStatus status = + taosLRUCacheInsert(pCache, key, keyLen, pPg, charge, deleter, &handle, TAOS_LRU_PRIORITY_LOW, NULL); + if (status != TAOS_LRU_STATUS_OK) { + // ignore cache updating if not ok + // code = TSDB_CODE_OUT_OF_MEMORY; + } + } + taosThreadMutexUnlock(&pFD->pTsdb->pgMutex); + + tsdbCacheRelease(pFD->pTsdb->pgCache, handle); return code; } diff --git a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c index 65f0f1b94d..def9a73d10 100644 --- a/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c +++ b/source/dnode/vnode/src/tsdb/tsdbReaderWriter.c @@ -178,7 +178,7 @@ static int32_t tsdbReadFilePage(STsdbFD *pFD, int64_t pgno) { pFD->blkno = (pgno + tsS3BlockSize - 1) / tsS3BlockSize; code = tsdbCacheGetBlockS3(pFD->pTsdb->bCache, pFD, &handle); if (code != TSDB_CODE_SUCCESS || handle == NULL) { - tsdbBCacheRelease(pFD->pTsdb->bCache, handle); + tsdbCacheRelease(pFD->pTsdb->bCache, handle); if (code == TSDB_CODE_SUCCESS && !handle) { code = TSDB_CODE_OUT_OF_MEMORY; } @@ -190,7 +190,7 @@ static int32_t tsdbReadFilePage(STsdbFD *pFD, int64_t pgno) { int64_t blk_offset = (pFD->blkno - 1) * tsS3BlockSize * pFD->szPage; memcpy(pFD->pBuf, pBlock + (offset - blk_offset), pFD->szPage); - tsdbBCacheRelease(pFD->pTsdb->bCache, handle); + tsdbCacheRelease(pFD->pTsdb->bCache, handle); } else { // seek int64_t n = taosLSeekFile(pFD->pFD, offset, SEEK_SET); @@ -254,7 +254,7 @@ _exit: return code; } -int32_t tsdbReadFile(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size) { +static int32_t tsdbReadFileImp(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size) { int32_t code = 0; int64_t n = 0; int64_t fOffset = LOGIC_TO_FILE_OFFSET(offset, pFD->szPage); @@ -283,6 +283,117 @@ _exit: return code; } +static int32_t tsdbReadFileS3(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size) { + int32_t code = 0; + int64_t n = 0; + int32_t szPgCont = PAGE_CONTENT_SIZE(pFD->szPage); + int64_t fOffset = LOGIC_TO_FILE_OFFSET(offset, pFD->szPage); + int64_t pgno = OFFSET_PGNO(fOffset, pFD->szPage); + int64_t bOffset = fOffset % pFD->szPage; + + ASSERT(bOffset < szPgCont); + + // 1, find pgnoStart & pgnoEnd to fetch from s3, if all pgs are local, no need to fetch + // 2, fetch pgnoStart ~ pgnoEnd from s3 + // 3, store pgs to pcache & last pg to pFD->pBuf + // 4, deliver pgs to [pBuf, pBuf + size) + + while (n < size) { + if (pFD->pgno != pgno) { + LRUHandle *handle = NULL; + code = tsdbCacheGetPageS3(pFD->pTsdb->pgCache, pFD, pgno, &handle); + if (code != TSDB_CODE_SUCCESS) { + if (handle) { + tsdbCacheRelease(pFD->pTsdb->pgCache, handle); + } + goto _exit; + } + + if (!handle) { + break; + } + + uint8_t *pPage = (uint8_t *)taosLRUCacheValue(pFD->pTsdb->pgCache, handle); + memcpy(pFD->pBuf, pPage, pFD->szPage); + tsdbCacheRelease(pFD->pTsdb->pgCache, handle); + + // check + if (pgno > 1 && !taosCheckChecksumWhole(pFD->pBuf, pFD->szPage)) { + code = TSDB_CODE_FILE_CORRUPTED; + goto _exit; + } + + pFD->pgno = pgno; + } + + int64_t nRead = TMIN(szPgCont - bOffset, size - n); + memcpy(pBuf + n, pFD->pBuf + bOffset, nRead); + + n += nRead; + pgno++; + bOffset = 0; + } + + if (n < size) { + // 2, retrieve pgs from s3 + uint8_t *pBlock = NULL; + int64_t retrieve_offset = PAGE_OFFSET(pgno, pFD->szPage); + int64_t pgnoEnd = pgno - 1 + (size - n + szPgCont - 1) / szPgCont; + int64_t retrieve_size = (pgnoEnd - pgno + 1) * pFD->szPage; + code = s3GetObjectBlock(pFD->objName, retrieve_offset, retrieve_size, &pBlock); + if (code != TSDB_CODE_SUCCESS) { + goto _exit; + } + + // 3, Store Pages in Cache + int nPage = pgnoEnd - pgno + 1; + for (int i = 0; i < nPage; ++i) { + tsdbCacheSetPageS3(pFD->pTsdb->pgCache, pFD, pgno, pBlock + i * pFD->szPage); + + memcpy(pFD->pBuf, pBlock + i * pFD->szPage, pFD->szPage); + + // check + if (pgno > 1 && !taosCheckChecksumWhole(pFD->pBuf, pFD->szPage)) { + code = TSDB_CODE_FILE_CORRUPTED; + goto _exit; + } + + pFD->pgno = pgno; + + int64_t nRead = TMIN(szPgCont - bOffset, size - n); + memcpy(pBuf + n, pFD->pBuf + bOffset, nRead); + + n += nRead; + pgno++; + bOffset = 0; + } + + taosMemoryFree(pBlock); + } + +_exit: + return code; +} + +int32_t tsdbReadFile(STsdbFD *pFD, int64_t offset, uint8_t *pBuf, int64_t size) { + int32_t code = 0; + if (!pFD->pFD) { + code = tsdbOpenFileImpl(pFD); + if (code) { + goto _exit; + } + } + + if (pFD->s3File && tsS3BlockSize < 0) { + return tsdbReadFileS3(pFD, offset, pBuf, size); + } else { + return tsdbReadFileImp(pFD, offset, pBuf, size); + } + +_exit: + return code; +} + int32_t tsdbFsyncFile(STsdbFD *pFD) { int32_t code = 0; From 221afff9eefdbde51126cc080375b356c092145c Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 1 Nov 2023 11:00:47 +0800 Subject: [PATCH 07/43] vnode/write: remove keep modify code block --- source/dnode/vnode/src/vnd/vnodeSvr.c | 46 +++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index b3675380c7..b31463ac00 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -16,12 +16,11 @@ #include "audit.h" #include "tencode.h" #include "tmsg.h" +#include "tstrbuild.h" #include "vnd.h" #include "vndCos.h" #include "vnode.h" #include "vnodeInt.h" -#include "audit.h" -#include "tstrbuild.h" static int32_t vnodeProcessCreateStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); static int32_t vnodeProcessAlterStbReq(SVnode *pVnode, int64_t ver, void *pReq, int32_t len, SRpcMsg *pRsp); @@ -275,6 +274,7 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int } } */ + TSKEY minKey = now - tsTickPerMin[pVnode->config.tsdbCfg.precision] * keep; TSKEY maxKey = tsMaxKeyByPrecision[pVnode->config.tsdbCfg.precision]; if (submitTbData.flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { @@ -906,7 +906,7 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, rsp.pArray = taosArrayInit(req.nReqs, sizeof(cRsp)); tbUids = taosArrayInit(req.nReqs, sizeof(int64_t)); - tbNames = taosArrayInit(req.nReqs, sizeof(char*)); + tbNames = taosArrayInit(req.nReqs, sizeof(char *)); if (rsp.pArray == NULL || tbUids == NULL || tbNames == NULL) { rcode = -1; terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -952,8 +952,8 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, taosArrayPush(rsp.pArray, &cRsp); - if(tsEnableAuditCreateTable){ - char* str = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN); + if (tsEnableAuditCreateTable) { + char *str = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN); strcpy(str, pCreateReq->name); taosArrayPush(tbNames, &str); } @@ -978,24 +978,24 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t ver, void *pReq, tEncoderInit(&encoder, pRsp->pCont, pRsp->contLen); tEncodeSVCreateTbBatchRsp(&encoder, &rsp); - if(tsEnableAuditCreateTable){ + if (tsEnableAuditCreateTable) { int64_t clusterId = pVnode->config.syncCfg.nodeInfo[0].clusterId; SName name = {0}; tNameFromString(&name, pVnode->config.dbname, T_NAME_ACCT | T_NAME_DB); SStringBuilder sb = {0}; - for(int32_t iReq = 0; iReq < req.nReqs; iReq++){ - char** key = (char**)taosArrayGet(tbNames, iReq); + for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { + char **key = (char **)taosArrayGet(tbNames, iReq); taosStringBuilderAppendStringLen(&sb, *key, strlen(*key)); - if(iReq < req.nReqs - 1){ + if (iReq < req.nReqs - 1) { taosStringBuilderAppendChar(&sb, ','); } taosMemoryFreeClear(*key); } - size_t len = 0; - char* keyJoined = taosStringBuilderGetResult(&sb, &len); + size_t len = 0; + char *keyJoined = taosStringBuilderGetResult(&sb, &len); auditRecord(NULL, clusterId, "createTable", name.dbname, "", keyJoined, len); @@ -1007,7 +1007,7 @@ _exit: pCreateReq = req.pReqs + iReq; taosMemoryFree(pCreateReq->sql); taosMemoryFree(pCreateReq->comment); - taosArrayDestroy(pCreateReq->ctb.tagName); + taosArrayDestroy(pCreateReq->ctb.tagName); } taosArrayDestroyEx(rsp.pArray, tFreeSVCreateTbRsp); taosArrayDestroy(tbUids); @@ -1166,7 +1166,7 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, in // process req tbUids = taosArrayInit(req.nReqs, sizeof(int64_t)); rsp.pArray = taosArrayInit(req.nReqs, sizeof(SVDropTbRsp)); - tbNames = taosArrayInit(req.nReqs, sizeof(char*)); + tbNames = taosArrayInit(req.nReqs, sizeof(char *)); if (tbUids == NULL || rsp.pArray == NULL || tbNames == NULL) goto _exit; for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { @@ -1188,9 +1188,9 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, in } taosArrayPush(rsp.pArray, &dropTbRsp); - - if(tsEnableAuditCreateTable){ - char* str = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN); + + if (tsEnableAuditCreateTable) { + char *str = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN); strcpy(str, pDropTbReq->name); taosArrayPush(tbNames, &str); } @@ -1199,30 +1199,30 @@ static int32_t vnodeProcessDropTbReq(SVnode *pVnode, int64_t ver, void *pReq, in tqUpdateTbUidList(pVnode->pTq, tbUids, false); tdUpdateTbUidList(pVnode->pSma, pStore, false); - if(tsEnableAuditCreateTable){ + if (tsEnableAuditCreateTable) { int64_t clusterId = pVnode->config.syncCfg.nodeInfo[0].clusterId; SName name = {0}; tNameFromString(&name, pVnode->config.dbname, T_NAME_ACCT | T_NAME_DB); SStringBuilder sb = {0}; - for(int32_t iReq = 0; iReq < req.nReqs; iReq++){ - char** key = (char**)taosArrayGet(tbNames, iReq); + for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { + char **key = (char **)taosArrayGet(tbNames, iReq); taosStringBuilderAppendStringLen(&sb, *key, strlen(*key)); - if(iReq < req.nReqs - 1){ + if (iReq < req.nReqs - 1) { taosStringBuilderAppendChar(&sb, ','); } taosMemoryFreeClear(*key); } - size_t len = 0; - char* keyJoined = taosStringBuilderGetResult(&sb, &len); + size_t len = 0; + char *keyJoined = taosStringBuilderGetResult(&sb, &len); auditRecord(NULL, clusterId, "dropTable", name.dbname, "", keyJoined, len); taosStringBuilderDestroy(&sb); } - + _exit: taosArrayDestroy(tbUids); tdUidStoreFree(pStore); From 0f5a124cb1a43fa7d1ba17fa91a3cc43cc20bbfc Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 1 Nov 2023 11:08:39 +0800 Subject: [PATCH 08/43] config/block-size: enable dynamic config for debugging --- source/common/src/tglobal.c | 13 +++++++------ source/dnode/mnode/impl/src/mndDnode.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 3d1a1ccb16..7cf1586abb 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -105,9 +105,9 @@ bool tsEnableAuditCreateTable = true; // telem #ifdef TD_ENTERPRISE -bool tsEnableTelem = false; +bool tsEnableTelem = false; #else -bool tsEnableTelem = true; +bool tsEnableTelem = true; #endif int32_t tsTelemInterval = 43200; char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.tdengine.com"; @@ -115,9 +115,9 @@ uint16_t tsTelemPort = 80; char *tsTelemUri = "/report"; #ifdef TD_ENTERPRISE -bool tsEnableCrashReport = false; +bool tsEnableCrashReport = false; #else -bool tsEnableCrashReport = true; +bool tsEnableCrashReport = true; #endif char *tsClientCrashReportUri = "/ccrashreport"; char *tsSvrCrashReportUri = "/dcrashreport"; @@ -677,7 +677,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddInt64(pCfg, "checkpointInterval", tsStreamCheckpointInterval, 60, 1200, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddFloat(pCfg, "streamSinkDataRate", tsSinkDataRate, 0.1, 5, CFG_SCOPE_SERVER) != 0) return -1; - if (cfgAddInt32(pCfg, "cacheLazyLoadThreshold", tsCacheLazyLoadThreshold, 0, 100000, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "cacheLazyLoadThreshold", tsCacheLazyLoadThreshold, 0, 100000, CFG_SCOPE_SERVER) != 0) + return -1; if (cfgAddString(pCfg, "lossyColumns", tsLossyColumns, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddFloat(pCfg, "fPrecision", tsFPrecision, 0.0f, 100000.0f, CFG_SCOPE_SERVER) != 0) return -1; @@ -695,7 +696,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddString(pCfg, "s3Accesskey", tsS3AccessKey, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddString(pCfg, "s3Endpoint", tsS3Endpoint, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER) != 0) return -1; - if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, 2048, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, -100, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 10, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER) != 0) return -1; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 6d77a48110..3b3e9eb03b 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -1228,6 +1228,22 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { strcpy(dcfgReq.config, "monitor"); snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); + } else if (strncasecmp(cfgReq.config, "s3blocksize", 11) == 0) { + int32_t optLen = strlen("s3blocksize"); + int32_t flag = -1; + int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); + if (code < 0) return code; + + if (flag > 1024 * 1024) { + mError("dnode:%d, failed to config s3blocksize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId, + flag); + terrno = TSDB_CODE_INVALID_CFG; + tFreeSMCfgDnodeReq(&cfgReq); + return -1; + } + + strcpy(dcfgReq.config, "s3blocksize"); + snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); } else if (strncasecmp(cfgReq.config, "s3blockcachesize", 16) == 0) { int32_t optLen = strlen("s3blockcachesize"); int32_t flag = -1; From 3e6c89d8ebbf33f11f0a12e5c7a7b64928a51c86 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 31 Oct 2023 23:14:02 +0800 Subject: [PATCH 09/43] fix(stream): add unsupport trans. --- source/dnode/vnode/src/tq/tq.c | 7 +++++-- source/libs/stream/src/streamStart.c | 2 +- source/libs/stream/src/streamTaskSm.c | 17 +++++++++++++---- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index e1b27049af..7ad0721531 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1269,9 +1269,12 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { /*int8_t status = */streamTaskSetSchedStatusInactive(pTask); // now the fill-history task starts to scan data from wal files. - streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); - tqScanWalAsync(pTq, false); + code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); + if (code == TSDB_CODE_SUCCESS) { + tqScanWalAsync(pTq, false); + } } + streamMetaReleaseTask(pMeta, pStreamTask); } else { diff --git a/source/libs/stream/src/streamStart.c b/source/libs/stream/src/streamStart.c index 2d951147d0..7756d7a2e0 100644 --- a/source/libs/stream/src/streamStart.c +++ b/source/libs/stream/src/streamStart.c @@ -580,7 +580,7 @@ int32_t streamProcessScanHistoryFinishRsp(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; // execute in the scan history complete call back msg, ready to process data from inputQ - streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); + int32_t code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); streamTaskSetSchedStatusInactive(pTask); taosWLockLatch(&pMeta->lock); diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 1aa4dd8e13..78728e82d1 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -105,6 +105,17 @@ int32_t streamTaskKeepCurrentVerInWal(SStreamTask* pTask) { return TSDB_CODE_SUCCESS; } +// todo check rsp code for handle Event:TASK_EVENT_SCANHIST_DONE +static bool isUnsupportedTransform(ETaskStatus state, const EStreamTaskEvent event) { + if (state == TASK_STATUS__STOP || state == TASK_STATUS__DROPPING || state == TASK_STATUS__UNINIT) { + if (event == TASK_EVENT_SCANHIST_DONE || event == TASK_EVENT_CHECKPOINT_DONE || event == TASK_EVENT_GEN_CHECKPOINT) { + return true; + } + } + + return false; +} + // todo optimize the perf of find the trans objs by using hash table static STaskStateTrans* streamTaskFindTransform(ETaskStatus state, const EStreamTaskEvent event) { int32_t numOfTrans = taosArrayGetSize(streamTaskSMTrans); @@ -115,10 +126,8 @@ static STaskStateTrans* streamTaskFindTransform(ETaskStatus state, const EStream } } - if (event == TASK_EVENT_CHECKPOINT_DONE && state == TASK_STATUS__STOP) { - - } else if (event == TASK_EVENT_GEN_CHECKPOINT && state == TASK_STATUS__UNINIT) { - // the task is set to uninit due to nodeEpset update, during processing checkpoint-trigger block. + if (isUnsupportedTransform(state, event)) { + return NULL; } else { ASSERT(0); } From 3f561fb8e4049ab6541eedda8074e4412cd67cf5 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 00:33:17 +0800 Subject: [PATCH 10/43] fix(stream): remove invalid assert. --- source/libs/stream/src/streamExec.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 15b809d6bd..c0589f6ab1 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -309,9 +309,6 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { } ETaskStatus status = streamTaskGetStatus(pStreamTask, NULL); - ASSERT(((status == TASK_STATUS__DROPPING) || (pStreamTask->hTaskInfo.id.taskId == pTask->id.taskId)) && - pTask->status.appendTranstateBlock == true); - STimeWindow* pTimeWindow = &pStreamTask->dataRange.window; // It must be halted for a source stream task, since when the related scan-history-data task start scan the history From 6f0fa5d47e99d1ffe16f1a5aa45053ce23700e8b Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 1 Nov 2023 14:56:57 +0800 Subject: [PATCH 11/43] tsdb/retention: remove incorrect right brace --- source/dnode/vnode/src/tsdb/tsdbRetention.c | 59 ++++++++++----------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 40561ddb42..0fc1e1b64b 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -324,41 +324,40 @@ static int32_t tsdbDoRetentionOnFileSet(SRTNer *rtner, STFileSet *fset) { for (int32_t ftype = 0; ftype < TSDB_FTYPE_MAX && (fobj = fset->farr[ftype], 1); ++ftype) { if (fobj == NULL) continue; - int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); + int32_t nlevel = tfsGetLevel(rtner->tsdb->pVnode->pTfs); - if (fobj->f->did.level == did.level) { - if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1 && - taosCheckExistFile(fobj->fname)) { - int32_t mtime = 0; - taosStatFile(fobj->fname, NULL, &mtime, NULL); - if (mtime < rtner->now - tsS3UploadDelaySec) { - code = tsdbMigrateDataFileS3(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); - } + if (fobj->f->did.level == did.level) { + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1 && + taosCheckExistFile(fobj->fname)) { + int32_t mtime = 0; + taosStatFile(fobj->fname, NULL, &mtime, NULL); + if (mtime < rtner->now - tsS3UploadDelaySec) { + code = tsdbMigrateDataFileS3(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); } - - continue; } - /* - if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1) { - code = tsdbMigrateDataFileS3(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); - } else { - if (tsS3Enabled) { - int64_t fsize = 0; - if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) { - code = TAOS_SYSTEM_ERROR(terrno); - tsdbError("vgId:%d %s failed since file:%s stat failed, reason:%s", TD_VID(rtner->tsdb->pVnode), - __func__, fobj->fname, tstrerror(code)); TSDB_CHECK_CODE(code, lino, _exit); - } - s3EvictCache(fobj->fname, fsize * 2); - } - */ - code = tsdbDoMigrateFileObj(rtner, fobj, &did); - TSDB_CHECK_CODE(code, lino, _exit); - //} + continue; } + /* + if (tsS3Enabled && nlevel > 1 && TSDB_FTYPE_DATA == ftype && did.level == nlevel - 1) { + code = tsdbMigrateDataFileS3(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + } else { + + if (tsS3Enabled) { + int64_t fsize = 0; + if (taosStatFile(fobj->fname, &fsize, NULL, NULL) < 0) { + code = TAOS_SYSTEM_ERROR(terrno); + tsdbError("vgId:%d %s failed since file:%s stat failed, reason:%s", TD_VID(rtner->tsdb->pVnode), + __func__, fobj->fname, tstrerror(code)); TSDB_CHECK_CODE(code, lino, _exit); + } + s3EvictCache(fobj->fname, fsize * 2); + } + */ + code = tsdbDoMigrateFileObj(rtner, fobj, &did); + TSDB_CHECK_CODE(code, lino, _exit); + //} } // stt From 52fd71ce13f07ba1788893b228b562e5191d4352 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 1 Nov 2023 18:00:31 +0800 Subject: [PATCH 12/43] config/block-size: default to -1 to enable page cache --- source/common/src/tglobal.c | 7 ++++--- source/dnode/mnode/impl/src/mndDnode.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 7cf1586abb..485b67e1a7 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -280,8 +280,8 @@ int8_t tsS3Enabled = false; int8_t tsS3Https = true; char tsS3Hostname[TSDB_FQDN_LEN] = ""; -int32_t tsS3BlockSize = 4096; // number of tsdb pages -int32_t tsS3BlockCacheSize = 16; // number of blocks +int32_t tsS3BlockSize = -1; // number of tsdb pages (4096) +int32_t tsS3BlockCacheSize = 1024; // number of blocks/pages (16) int32_t tsS3UploadDelaySec = 60 * 60; #ifndef _STORAGE @@ -697,7 +697,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddString(pCfg, "s3Endpoint", tsS3Endpoint, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, -100, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; - if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024 * 1024, CFG_SCOPE_SERVER) != 0) + return -1; if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 10, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER) != 0) return -1; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 3b3e9eb03b..e2c21ed012 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -1250,7 +1250,7 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); if (code < 0) return code; - if (flag < 4 || flag > 1024 * 1024) { + if (flag < 4 || flag > 1024 * 1024 * 1024) { mError("dnode:%d, failed to config s3BlockCacheSize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId, flag); terrno = TSDB_CODE_INVALID_CFG; From 9a9c1d689d2b905eae6375da1bbf2422e55552d8 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 13:19:53 +0800 Subject: [PATCH 13/43] fix(stream): add lock log. --- source/dnode/vnode/src/tq/tq.c | 66 +----------------------- source/dnode/vnode/src/tq/tqStreamTask.c | 1 + source/libs/stream/src/streamDispatch.c | 2 + source/libs/stream/src/streamTaskSm.c | 10 ++++ 4 files changed, 14 insertions(+), 65 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 7ad0721531..91cc8c36c1 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1152,12 +1152,10 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { // 1. get the related stream task pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId); if (pStreamTask == NULL) { - // todo delete this task, if the related stream task is dropped - qError("failed to find s-task:0x%"PRIx64", it may have been destroyed, drop fill-history task:%s", + tqError("failed to find s-task:0x%"PRIx64", it may have been destroyed, drop related fill-history task:%s", pTask->streamTaskId.taskId, pTask->id.idStr); tqDebug("s-task:%s fill-history task set status to be dropping", id); - streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); atomic_store_32(&pTask->status.inScanHistorySentinel, 0); @@ -1166,68 +1164,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { } ASSERT(pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE); -#if 0 - // 2. it cannot be paused, when the stream task in TASK_STATUS__SCAN_HISTORY status. Let's wait for the - // stream task get ready for scan history data - while (streamTaskGetStatus(pStreamTask, NULL) == TASK_STATUS__SCAN_HISTORY) { - tqDebug( - "s-task:%s level:%d related stream task:%s(status:%s) not ready for halt, wait for it and recheck in 100ms", - id, pTask->info.taskLevel, pStreamTask->id.idStr, streamGetTaskStatusStr(pStreamTask->status.taskStatus)); - taosMsleep(100); - } - - // now we can stop the stream task execution - int64_t nextProcessedVer = 0; - - while (1) { - taosThreadMutexLock(&pStreamTask->lock); - int8_t status = pStreamTask->status.taskStatus; - if (status == TASK_STATUS__DROPPING || status == TASK_STATUS__STOP) { - // return; do nothing - } - - if (status == TASK_STATUS__HALT) { -// tqDebug("s-task:%s level:%d sched-status:%d is halt by fill-history task:%s", pStreamTask->id.idStr, -// pStreamTask->info.taskLevel, pStreamTask->status.schedStatus, id); -// latestVer = walReaderGetCurrentVer(pStreamTask->exec.pWalReader); -// -// taosThreadMutexUnlock(&pStreamTask->lock); -// break; - } - - if (pStreamTask->status.taskStatus == TASK_STATUS__CK) { - qDebug("s-task:%s status:%s during generating checkpoint, wait for 1sec and retry set status:halt", - pStreamTask->id.idStr, streamGetTaskStatusStr(TASK_STATUS__CK)); - taosThreadMutexUnlock(&pStreamTask->lock); - taosMsleep(1000); - continue; - } - - // upgrade to halt status - if (status == TASK_STATUS__PAUSE) { - qDebug("s-task:%s upgrade status to %s from %s", pStreamTask->id.idStr, streamGetTaskStatusStr(TASK_STATUS__HALT), - streamGetTaskStatusStr(TASK_STATUS__PAUSE)); - } else { - qDebug("s-task:%s halt task, prev status:%s", pStreamTask->id.idStr, streamGetTaskStatusStr(status)); - } - - pStreamTask->status.keepTaskStatus = status; - pStreamTask->status.taskStatus = TASK_STATUS__HALT; - - // wal scan not start yet, reset it to be the start position - nextProcessedVer = walReaderGetCurrentVer(pStreamTask->exec.pWalReader); - if (nextProcessedVer == -1) { - nextProcessedVer = pStreamTask->dataRange.range.maxVer + 1; - } - - tqDebug("s-task:%s level:%d nextProcessedVer:%" PRId64 ", sched-status:%d is halt by fill-history task:%s", - pStreamTask->id.idStr, pStreamTask->info.taskLevel, nextProcessedVer, pStreamTask->status.schedStatus, - id); - - taosThreadMutexUnlock(&pStreamTask->lock); - break; - } -#endif streamTaskHandleEvent(pStreamTask->status.pSM, TASK_EVENT_HALT); int64_t nextProcessedVer = pStreamTask->hTaskInfo.haltVer; diff --git a/source/dnode/vnode/src/tq/tqStreamTask.c b/source/dnode/vnode/src/tq/tqStreamTask.c index 1f1dd61c3c..1672c8e609 100644 --- a/source/dnode/vnode/src/tq/tqStreamTask.c +++ b/source/dnode/vnode/src/tq/tqStreamTask.c @@ -446,6 +446,7 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) { int64_t maxVer = (pTask->info.fillHistory == 1) ? pTask->dataRange.range.maxVer : INT64_MAX; taosThreadMutexLock(&pTask->lock); + tqDebug("s-task:%s lock", pTask->id.idStr); char* p = NULL; ETaskStatus status = streamTaskGetStatus(pTask, &p); diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index cd8bbacb98..14129522d6 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -1004,6 +1004,8 @@ int32_t streamAddEndScanHistoryMsg(SStreamTask* pTask, SRpcHandleInfo* pRpcInfo, info.msg.info = *pRpcInfo; taosThreadMutexLock(&pTask->lock); + stDebug("s-task:%s lock", pTask->id.idStr); + if (pTask->pRspMsgList == NULL) { pTask->pRspMsgList = taosArrayInit(4, sizeof(SStreamContinueExecInfo)); } diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 78728e82d1..621fa7284b 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -200,6 +200,7 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt if (pTrans->attachEvent.event != 0) { attachEvent(pTask, &pTrans->attachEvent); taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlock1", pTask->id.idStr); while (1) { // wait for the task to be here @@ -223,6 +224,7 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt pSM->pActiveTrans = pTrans; pSM->startTs = taosGetTimestampMs(); taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlock2", pTask->id.idStr); int32_t code = pTrans->pAction(pTask); // todo handle error code; @@ -241,6 +243,8 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { while (1) { taosThreadMutexLock(&pTask->lock); + stDebug("s-task:%s lock", pTask->id.idStr); + if (pSM->pActiveTrans != NULL && pSM->pActiveTrans->autoInvokeEndFn) { taosThreadMutexUnlock(&pTask->lock); taosMsleep(100); @@ -281,6 +285,8 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even // do update the task status taosThreadMutexLock(&pTask->lock); + stDebug("s-task:%s lock", pTask->id.idStr); + STaskStateTrans* pTrans = pSM->pActiveTrans; if (pTrans == NULL) { @@ -291,6 +297,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even StreamTaskEventList[event].name, pSM->current.name, StreamTaskEventList[pSM->prev.evt].name); taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlockx", pTask->id.idStr); return TSDB_CODE_INVALID_PARA; } @@ -298,6 +305,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even stWarn("s-task:%s handle event:%s failed, current status:%s, active trans evt:%s", pTask->id.idStr, StreamTaskEventList[event].name, pSM->current.name, StreamTaskEventList[pTrans->event].name); taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlocky", pTask->id.idStr); return TSDB_CODE_INVALID_PARA; } @@ -327,6 +335,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even pSM->pActiveTrans = pNextTrans; pSM->startTs = taosGetTimestampMs(); taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlockf", pTask->id.idStr); int32_t code = pNextTrans->pAction(pSM->pTask); if (pNextTrans->autoInvokeEndFn) { @@ -337,6 +346,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even } } else { taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s unlockz", pTask->id.idStr); int64_t el = (taosGetTimestampMs() - pSM->startTs); stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr, From bd12ae88e1dcb6419871c7e841caace210c53664 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 13:59:51 +0800 Subject: [PATCH 14/43] fix(stream):fix the bug when event in waiting list not fulfilled. --- source/libs/stream/src/streamTaskSm.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 621fa7284b..1dd712e6e1 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -322,13 +322,16 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr, StreamTaskEventList[pTrans->event].name, el, pSM->prev.state.name, pSM->current.name); - SAttachedEventInfo* pEvtInfo = taosArrayPop(pSM->pWaitingEventList); + SAttachedEventInfo* pEvtInfo = taosArrayGet(pSM->pWaitingEventList, 0); // OK, let's handle the attached event, since the task has reached the required status now if (pSM->current.state == pEvtInfo->status) { - stDebug("s-task:%s handle the attached event:%s, state:%s", pTask->id.idStr, + stDebug("s-task:%s handle the event:%s in waiting list, state:%s", pTask->id.idStr, StreamTaskEventList[pEvtInfo->event].name, pSM->current.name); + // remove it + taosArrayPop(pSM->pWaitingEventList); + STaskStateTrans* pNextTrans = streamTaskFindTransform(pSM->current.state, pEvtInfo->event); ASSERT(pSM->pActiveTrans == NULL && pNextTrans != NULL); @@ -343,6 +346,11 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even } else { return code; } + } else { + taosThreadMutexUnlock(&pTask->lock); + stDebug("s-task:%s state:%s event:%s in waiting list, req state:%s not fulfilled, put it back", pTask->id.idStr, + pSM->current.name, StreamTaskEventList[pEvtInfo->event].name, + StreamTaskStatusList[pEvtInfo->status].name); } } else { taosThreadMutexUnlock(&pTask->lock); From 385e699cc2afe0c7568f041da8570d334ccb8d81 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 14:07:18 +0800 Subject: [PATCH 15/43] fix(stream): do some internal refactor. --- source/libs/stream/src/streamTaskSm.c | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 1dd712e6e1..78f864d6ec 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -20,6 +20,8 @@ #include "ttimer.h" #include "wal.h" +#define GET_EVT_NAME(_ev) (StreamTaskEventList[(_ev)].name) + SStreamTaskState StreamTaskStatusList[9] = { {.state = TASK_STATUS__READY, .name = "ready"}, {.state = TASK_STATUS__DROPPING, .name = "dropped"}, @@ -66,7 +68,7 @@ static int32_t attachEvent(SStreamTask* pTask, SAttachedEventInfo* pEvtInfo) { streamTaskGetStatus(pTask, &p); stDebug("s-task:%s status:%s attach event:%s required status:%s, since not allowed to handle it", pTask->id.idStr, p, - StreamTaskEventList[pEvtInfo->event].name, StreamTaskStatusList[pEvtInfo->status].name); + GET_EVT_NAME(pEvtInfo->event), StreamTaskStatusList[pEvtInfo->status].name); taosArrayPush(pTask->status.pSM->pWaitingEventList, pEvtInfo); return 0; } @@ -209,10 +211,10 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt taosThreadMutexUnlock(&pTask->lock); if ((s == pTrans->next.state) && (pSM->prev.evt == pTrans->event)) { - stDebug("s-task:%s attached event:%s handled", id, StreamTaskEventList[pTrans->event].name); + stDebug("s-task:%s attached event:%s handled", id, GET_EVT_NAME(pTrans->event)); return TSDB_CODE_SUCCESS; } else if (s != TASK_STATUS__DROPPING && s != TASK_STATUS__STOP) { // this event has been handled already - stDebug("s-task:%s not handle event:%s yet, wait for 100ms and recheck", id, StreamTaskEventList[event].name); + stDebug("s-task:%s not handle event:%s yet, wait for 100ms and recheck", id, GET_EVT_NAME(event)); taosMsleep(100); } else { stDebug("s-task:%s is dropped or stopped already, not wait.", id); @@ -249,11 +251,11 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { taosThreadMutexUnlock(&pTask->lock); taosMsleep(100); stDebug("s-task:%s status:%s handling event:%s by some other thread, wait for 100ms and check if completed", - pTask->id.idStr, pSM->current.name, StreamTaskEventList[pSM->pActiveTrans->event].name); + pTask->id.idStr, pSM->current.name, GET_EVT_NAME(pSM->pActiveTrans->event)); } else { pTrans = streamTaskFindTransform(pSM->current.state, event); if (pTrans == NULL) { - stDebug("s-task:%s failed to handle event:%s", pTask->id.idStr, StreamTaskEventList[event].name); + stDebug("s-task:%s failed to handle event:%s", pTask->id.idStr, GET_EVT_NAME(event)); taosThreadMutexUnlock(&pTask->lock); return TSDB_CODE_INVALID_PARA; // todo: set new error code// failed to handle the event. } @@ -261,8 +263,8 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { if (pSM->pActiveTrans != NULL) { // currently in some state transfer procedure, not auto invoke transfer, abort it stDebug("s-task:%s event:%s handle procedure quit, status %s -> %s failed, handle event %s now", - pTask->id.idStr, StreamTaskEventList[pSM->pActiveTrans->event].name, pSM->current.name, - pSM->pActiveTrans->next.name, StreamTaskEventList[event].name); + pTask->id.idStr, GET_EVT_NAME(pSM->pActiveTrans->event), pSM->current.name, + pSM->pActiveTrans->next.name, GET_EVT_NAME(event)); } doHandleEvent(pSM, event, pTrans); @@ -294,7 +296,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even ASSERT(s == TASK_STATUS__DROPPING || s == TASK_STATUS__PAUSE || s == TASK_STATUS__STOP); // the pSM->prev.evt may be 0, so print string is not appropriate. stDebug("s-task:%s event:%s handled failed, current status:%s, trigger event:%s", pTask->id.idStr, - StreamTaskEventList[event].name, pSM->current.name, StreamTaskEventList[pSM->prev.evt].name); + GET_EVT_NAME(event), pSM->current.name, GET_EVT_NAME(pSM->prev.evt)); taosThreadMutexUnlock(&pTask->lock); stDebug("s-task:%s unlockx", pTask->id.idStr); @@ -303,7 +305,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even if (pTrans->event != event) { stWarn("s-task:%s handle event:%s failed, current status:%s, active trans evt:%s", pTask->id.idStr, - StreamTaskEventList[event].name, pSM->current.name, StreamTaskEventList[pTrans->event].name); + GET_EVT_NAME(event), pSM->current.name, GET_EVT_NAME(pTrans->event)); taosThreadMutexUnlock(&pTask->lock); stDebug("s-task:%s unlocky", pTask->id.idStr); return TSDB_CODE_INVALID_PARA; @@ -320,14 +322,14 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even if (taosArrayGetSize(pSM->pWaitingEventList) > 0) { int64_t el = (taosGetTimestampMs() - pSM->startTs); stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr, - StreamTaskEventList[pTrans->event].name, el, pSM->prev.state.name, pSM->current.name); + GET_EVT_NAME(pTrans->event), el, pSM->prev.state.name, pSM->current.name); SAttachedEventInfo* pEvtInfo = taosArrayGet(pSM->pWaitingEventList, 0); // OK, let's handle the attached event, since the task has reached the required status now if (pSM->current.state == pEvtInfo->status) { stDebug("s-task:%s handle the event:%s in waiting list, state:%s", pTask->id.idStr, - StreamTaskEventList[pEvtInfo->event].name, pSM->current.name); + GET_EVT_NAME(pEvtInfo->event), pSM->current.name); // remove it taosArrayPop(pSM->pWaitingEventList); @@ -349,7 +351,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even } else { taosThreadMutexUnlock(&pTask->lock); stDebug("s-task:%s state:%s event:%s in waiting list, req state:%s not fulfilled, put it back", pTask->id.idStr, - pSM->current.name, StreamTaskEventList[pEvtInfo->event].name, + pSM->current.name, GET_EVT_NAME(pEvtInfo->event), StreamTaskStatusList[pEvtInfo->status].name); } } else { @@ -358,7 +360,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even int64_t el = (taosGetTimestampMs() - pSM->startTs); stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr, - StreamTaskEventList[pTrans->event].name, el, pSM->prev.state.name, pSM->current.name); + GET_EVT_NAME(pTrans->event), el, pSM->prev.state.name, pSM->current.name); } return TSDB_CODE_SUCCESS; From 00f029e44ff17b4940a79a6a2f23ace001dce75f Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 16:12:15 +0800 Subject: [PATCH 16/43] refactor: add some logs. --- include/libs/stream/tstream.h | 1 - source/dnode/vnode/src/tq/tq.c | 15 +++++ source/dnode/vnode/src/tq/tqStreamTask.c | 14 ++-- source/dnode/vnode/src/vnd/vnodeSync.c | 13 ++-- source/libs/stream/src/streamCheckpoint.c | 16 +++-- source/libs/stream/src/streamExec.c | 10 +-- source/libs/stream/src/streamMeta.c | 23 +++++-- source/libs/stream/src/streamStart.c | 79 ++--------------------- 8 files changed, 64 insertions(+), 107 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 5e145d8fbb..81a0caeb6b 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -762,7 +762,6 @@ int32_t streamQueueGetNumOfItems(const SStreamQueue* pQueue); int32_t streamRestoreParam(SStreamTask* pTask); void streamTaskPause(SStreamTask* pTask, SStreamMeta* pMeta); void streamTaskResume(SStreamTask* pTask); -void streamTaskDisablePause(SStreamTask* pTask); void streamTaskEnablePause(SStreamTask* pTask); int32_t streamTaskSetUpstreamInfo(SStreamTask* pTask, const SStreamTask* pUpstreamTask); void streamTaskUpdateUpstreamInfo(SStreamTask* pTask, int32_t nodeId, const SEpSet* pEpSet); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 91cc8c36c1..e934fd5192 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1805,6 +1805,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { // update the nodeEpset when it exists taosWLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-wlock", pMeta->vgId); // the task epset may be updated again and again, when replaying the WAL, the task may be in stop status. STaskId id = {.streamId = req.streamId, .taskId = req.taskId}; @@ -1814,6 +1815,8 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { req.taskId); rsp.code = TSDB_CODE_SUCCESS; taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); + taosArrayDestroy(req.pNodeList); return rsp.code; } @@ -1836,11 +1839,13 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { req.transId); rsp.code = TSDB_CODE_SUCCESS; taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); taosArrayDestroy(req.pNodeList); return rsp.code; } taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); // the following two functions should not be executed within the scope of meta lock to avoid deadlock streamTaskUpdateEpsetInfo(pTask, req.pNodeList); @@ -1848,6 +1853,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { // continue after lock the meta again taosWLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-wlock", pMeta->vgId); SStreamTask** ppHTask = NULL; if (HAS_RELATED_FILLHISTORY_TASK(pTask)) { @@ -1898,15 +1904,19 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { tqDebug("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, updateTasks, (numOfTasks - updateTasks)); taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); } else { if (!pTq->pVnode->restored) { tqDebug("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); pMeta->startInfo.startAllTasksFlag = 0; taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); } else { tqDebug("vgId:%d tasks are all updated and stopped, restart them", vgId); terrno = 0; + taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); while (streamMetaTaskInTimer(pMeta)) { qDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); @@ -1914,10 +1924,13 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { } taosWLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-wlock", pMeta->vgId); + int32_t code = streamMetaReopen(pMeta); if (code != 0) { tqError("vgId:%d failed to reopen stream meta", vgId); taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); taosArrayDestroy(req.pNodeList); return -1; } @@ -1925,6 +1938,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { if (streamMetaLoadAllTasks(pTq->pStreamMeta) < 0) { tqError("vgId:%d failed to load stream tasks", vgId); taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); taosArrayDestroy(req.pNodeList); return -1; } @@ -1938,6 +1952,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { } taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); } } diff --git a/source/dnode/vnode/src/tq/tqStreamTask.c b/source/dnode/vnode/src/tq/tqStreamTask.c index 1672c8e609..6dc5a77fc1 100644 --- a/source/dnode/vnode/src/tq/tqStreamTask.c +++ b/source/dnode/vnode/src/tq/tqStreamTask.c @@ -39,17 +39,15 @@ int32_t tqScanWal(STQ* pTq) { if (shouldIdle) { taosWLockLatch(&pMeta->lock); - int32_t times = (--pMeta->walScanCounter); ASSERT(pMeta->walScanCounter >= 0); - - if (pMeta->walScanCounter <= 0) { - taosWUnLockLatch(&pMeta->lock); - break; - } - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d scan wal for stream tasks for %d times in %dms", vgId, times, SCAN_WAL_IDLE_DURATION); + + if (times <= 0) { + break; + } else { + tqDebug("vgId:%d scan wal for stream tasks for %d times in %dms", vgId, times, SCAN_WAL_IDLE_DURATION); + } } taosMsleep(SCAN_WAL_IDLE_DURATION); diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index dcc31526f7..5d8fc6056c 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -554,10 +554,14 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) walApplyVer(pVnode->pWal, commitIdx); pVnode->restored = true; - taosWLockLatch(&pVnode->pTq->pStreamMeta->lock); - if (pVnode->pTq->pStreamMeta->startInfo.startAllTasksFlag) { + SStreamMeta* pMeta = pVnode->pTq->pStreamMeta; + taosWLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-wlock", pMeta->vgId); + + if (pMeta->startInfo.startAllTasksFlag) { vInfo("vgId:%d, sync restore finished, stream tasks will be launched by other thread", vgId); - taosWUnLockLatch(&pVnode->pTq->pStreamMeta->lock); + taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); return; } @@ -574,7 +578,8 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) vInfo("vgId:%d, sync restore finished, not launch stream tasks since not leader", vgId); } - taosWUnLockLatch(&pVnode->pTq->pStreamMeta->lock); + taosWUnLockLatch(&pMeta->lock); + tqDebug("vgId:%d meta-unlock", pMeta->vgId); } static void vnodeBecomeFollower(const SSyncFSM *pFsm) { diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index 9eaa9fcb92..6d4f09b768 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -185,6 +185,7 @@ int32_t streamProcessCheckpointBlock(SStreamTask* pTask, SStreamDataBlock* pBloc { // todo: remove this when the pipeline checkpoint generating is used. SStreamMeta* pMeta = pTask->pMeta; taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); if (pMeta->chkptNotReadyTasks == 0) { pMeta->chkptNotReadyTasks = pMeta->numOfStreamTasks; @@ -281,8 +282,10 @@ void streamTaskClearCheckInfo(SStreamTask* pTask) { int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { int32_t vgId = pMeta->vgId; + int32_t code = 0; taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); for (int32_t i = 0; i < taosArrayGetSize(pMeta->pTaskList); ++i) { STaskId* pId = taosArrayGet(pMeta->pTaskList, i); @@ -304,10 +307,11 @@ int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { char* str = NULL; streamTaskGetStatus(p, &str); - int32_t code = streamTaskHandleEvent(p->status.pSM, TASK_EVENT_CHECKPOINT_DONE); + code = streamTaskHandleEvent(p->status.pSM, TASK_EVENT_CHECKPOINT_DONE); if (code != TSDB_CODE_SUCCESS) { stDebug("s-task:%s vgId:%d save task status failed, since handle event failed", p->id.idStr, vgId); taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); return -1; } else { // save the task streamMetaSaveTask(pMeta, p); @@ -320,17 +324,17 @@ int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { str); } - if (streamMetaCommit(pMeta) < 0) { - taosWUnLockLatch(&pMeta->lock); + code = streamMetaCommit(pMeta); + if (code < 0) { stError("vgId:%d failed to commit stream meta after do checkpoint, checkpointId:%" PRId64 ", since %s", pMeta->vgId, checkpointId, terrstr()); - return -1; } else { - taosWUnLockLatch(&pMeta->lock); stInfo("vgId:%d commit stream meta after do checkpoint, checkpointId:%" PRId64 " DONE", pMeta->vgId, checkpointId); } - return TSDB_CODE_SUCCESS; + taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); + return code; } int32_t streamTaskBuildCheckpoint(SStreamTask* pTask) { diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index c0589f6ab1..a1951b23cc 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -356,17 +356,9 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { // 4. free it and remove fill-history task from disk meta-store streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); - // 5. clear the link between fill-history task and stream task info -// CLEAR_RELATED_FILLHISTORY_TASK(pStreamTask); - - // 6. save to disk + // 5. save to disk taosWLockLatch(&pMeta->lock); - pStreamTask->status.taskStatus = streamTaskGetStatus(pStreamTask, NULL); -// streamMetaSaveTask(pMeta, pStreamTask); -// if (streamMetaCommit(pMeta) < 0) { - // persist to disk -// } taosWUnLockLatch(&pMeta->lock); // 7. pause allowed. diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index f788e244cd..ce7f325922 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -492,6 +492,7 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t // pre-delete operation taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); STaskId id = {.streamId = streamId, .taskId = taskId}; SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); @@ -509,9 +510,11 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t } else { stDebug("vgId:%d failed to find the task:0x%x, it may be dropped already", pMeta->vgId, taskId); taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); return 0; } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); stDebug("s-task:0x%x set task status:dropping and start to unregister it", taskId); @@ -522,20 +525,25 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t if (ppTask) { if ((*ppTask)->status.timerActive == 0) { taosRUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); break; } taosMsleep(10); stDebug("s-task:%s wait for quit from timer", (*ppTask)->id.idStr); taosRUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); } else { taosRUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); break; } } // let's do delete of stream task taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); + ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); if (ppTask) { pTask = *ppTask; @@ -566,18 +574,16 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); return 0; } int32_t streamMetaBegin(SStreamMeta* pMeta) { taosWLockLatch(&pMeta->lock); - if (tdbBegin(pMeta->db, &pMeta->txn, tdbDefaultMalloc, tdbDefaultFree, NULL, - TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED) < 0) { - taosWUnLockLatch(&pMeta->lock); - return -1; - } + int32_t code = tdbBegin(pMeta->db, &pMeta->txn, tdbDefaultMalloc, tdbDefaultFree, NULL, + TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED); taosWUnLockLatch(&pMeta->lock); - return 0; + return code; } // todo add error log @@ -1013,6 +1019,7 @@ void metaHbToMnode(void* param, void* tmrId) { bool streamMetaTaskInTimer(SStreamMeta* pMeta) { bool inTimer = false; taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); void* pIter = NULL; while (1) { @@ -1028,6 +1035,8 @@ bool streamMetaTaskInTimer(SStreamMeta* pMeta) { } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); + return inTimer; } @@ -1038,6 +1047,7 @@ void streamMetaNotifyClose(SStreamMeta* pMeta) { (pMeta->role == NODE_ROLE_LEADER), pMeta->pHbInfo->hbStart, pMeta->pHbInfo->hbCount); taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); void* pIter = NULL; while (1) { @@ -1052,6 +1062,7 @@ void streamMetaNotifyClose(SStreamMeta* pMeta) { } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); // wait for the stream meta hb function stopping if (pMeta->role == NODE_ROLE_LEADER) { diff --git a/source/libs/stream/src/streamStart.c b/source/libs/stream/src/streamStart.c index 7756d7a2e0..098385c3ef 100644 --- a/source/libs/stream/src/streamStart.c +++ b/source/libs/stream/src/streamStart.c @@ -625,6 +625,8 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) { SStreamMeta* pMeta = pInfo->pMeta; taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); + SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &pInfo->id, sizeof(pInfo->id)); if (ppTask) { ASSERT((*ppTask)->status.timerActive >= 1); @@ -638,10 +640,12 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) { taosMemoryFree(pInfo); taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); return; } } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); SStreamTask* pTask = streamMetaAcquireTask(pMeta, pInfo->id.streamId, pInfo->id.taskId); if (pTask != NULL) { @@ -934,66 +938,6 @@ void streamTaskSetRangeStreamCalc(SStreamTask* pTask) { } void streamTaskPause(SStreamTask* pTask, SStreamMeta* pMeta) { -#if 0 - int8_t status = pTask->status.taskStatus; - if (status == TASK_STATUS__DROPPING) { - stDebug("vgId:%d s-task:%s task already dropped, do nothing", pMeta->vgId, pTask->id.idStr); - return; - } - - const char* str = streamGetTaskStatusStr(status); - if (status == TASK_STATUS__STOP || status == TASK_STATUS__PAUSE) { - stDebug("vgId:%d s-task:%s task already stopped/paused, status:%s, do nothing", pMeta->vgId, pTask->id.idStr, str); - return; - } - - if(pTask->info.taskLevel == TASK_LEVEL__SINK) { - int32_t num = atomic_add_fetch_32(&pMeta->numOfPausedTasks, 1); - stInfo("vgId:%d s-task:%s pause stream sink task. pause task num:%d", pMeta->vgId, pTask->id.idStr, num); - return; - } - - while (!pTask->status.pauseAllowed || (pTask->status.taskStatus == TASK_STATUS__HALT)) { - status = pTask->status.taskStatus; - if (status == TASK_STATUS__DROPPING) { - stDebug("vgId:%d s-task:%s task already dropped, do nothing", pMeta->vgId, pTask->id.idStr); - return; - } - - if (status == TASK_STATUS__STOP || status == TASK_STATUS__PAUSE) { - stDebug("vgId:%d s-task:%s task already stopped/paused, status:%s, do nothing", pMeta->vgId, pTask->id.idStr, str); - return; - } -// -// if (pTask->status.downstreamReady == 0) { -// ASSERT(pTask->execInfo.start == 0); -// stDebug("s-task:%s in check downstream procedure, abort and paused", pTask->id.idStr); -// break; -// } - - const char* pStatus = streamGetTaskStatusStr(status); - stDebug("s-task:%s wait for the task can be paused, status:%s, vgId:%d", pTask->id.idStr, pStatus, pMeta->vgId); - taosMsleep(100); - } - - // todo: use the task lock, stead of meta lock - taosWLockLatch(&pMeta->lock); - - status = pTask->status.taskStatus; - if (status == TASK_STATUS__DROPPING || status == TASK_STATUS__STOP) { - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d s-task:%s task already dropped/stopped/paused, do nothing", pMeta->vgId, pTask->id.idStr); - return; - } - - atomic_store_8(&pTask->status.keepTaskStatus, pTask->status.taskStatus); - atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__PAUSE); - int32_t num = atomic_add_fetch_32(&pMeta->numOfPausedTasks, 1); - stInfo("vgId:%d s-task:%s pause stream task. pause task num:%d", pMeta->vgId, pTask->id.idStr, num); - taosWUnLockLatch(&pMeta->lock); - -#endif - streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_PAUSE); int32_t num = atomic_add_fetch_32(&pMeta->numOfPausedTasks, 1); @@ -1029,19 +973,6 @@ void streamTaskResume(SStreamTask* pTask) { } } -// todo fix race condition -void streamTaskDisablePause(SStreamTask* pTask) { - // pre-condition check -// const char* id = pTask->id.idStr; -// while (pTask->status.taskStatus == TASK_STATUS__PAUSE) { -// stDebug("s-task:%s already in pause, wait for pause being cancelled, and set pause disabled, recheck in 100ms", id); -// taosMsleep(100); -// } -// -// stDebug("s-task:%s disable task pause", id); -// pTask->status.pauseAllowed = 0; -} - void streamTaskEnablePause(SStreamTask* pTask) { stDebug("s-task:%s enable task pause", pTask->id.idStr); pTask->status.pauseAllowed = 1; @@ -1051,6 +982,7 @@ int32_t streamMetaUpdateTaskReadyInfo(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock", pMeta->vgId); STaskId id = streamTaskExtractKey(pTask); taosHashPut(pMeta->startInfo.pReadyTaskSet, &id, sizeof(id), NULL, 0); @@ -1072,5 +1004,6 @@ int32_t streamMetaUpdateTaskReadyInfo(SStreamTask* pTask) { } taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-unlock", pMeta->vgId); return TSDB_CODE_SUCCESS; } From 7cf90dde5c29bd99d61a7d447723d94f798d7536 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 17:19:21 +0800 Subject: [PATCH 17/43] refactor: do some internal refactor. --- include/libs/stream/tstream.h | 4 ++ source/dnode/snode/src/snode.c | 10 ++-- source/dnode/vnode/src/tq/tq.c | 48 ++++++--------- source/dnode/vnode/src/tq/tqPush.c | 4 +- source/dnode/vnode/src/tq/tqRead.c | 4 +- source/dnode/vnode/src/tq/tqStreamTask.c | 28 ++++----- source/dnode/vnode/src/vnd/vnodeSync.c | 9 +-- source/libs/stream/src/streamCheckpoint.c | 14 ++--- source/libs/stream/src/streamExec.c | 8 +-- source/libs/stream/src/streamMeta.c | 73 ++++++++++++----------- source/libs/stream/src/streamStart.c | 19 +++--- source/libs/stream/src/streamState.c | 2 +- 12 files changed, 104 insertions(+), 119 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index 81a0caeb6b..2e4204ab34 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -806,6 +806,10 @@ void streamMetaStartHb(SStreamMeta* pMeta); void streamMetaInitForSnode(SStreamMeta* pMeta); bool streamMetaTaskInTimer(SStreamMeta* pMeta); int32_t streamMetaUpdateTaskReadyInfo(SStreamTask* pTask); +void streamMetaRLock(SStreamMeta* pMeta); +void streamMetaRUnLock(SStreamMeta* pMeta); +void streamMetaWLock(SStreamMeta* pMeta); +void streamMetaWUnLock(SStreamMeta* pMeta); // checkpoint int32_t streamProcessCheckpointSourceReq(SStreamTask* pTask, SStreamCheckpointSourceReq* pReq); diff --git a/source/dnode/snode/src/snode.c b/source/dnode/snode/src/snode.c index 4e84b4cd26..f2ef00c534 100644 --- a/source/dnode/snode/src/snode.c +++ b/source/dnode/snode/src/snode.c @@ -165,17 +165,17 @@ int32_t sndProcessTaskDeployReq(SSnode *pSnode, char *msg, int32_t msgLen) { ASSERT(pTask->info.taskLevel == TASK_LEVEL__AGG); // 2.save task - taosWLockLatch(&pSnode->pMeta->lock); + streamMetaWLock(pSnode->pMeta); bool added = false; code = streamMetaRegisterTask(pSnode->pMeta, -1, pTask, &added); if (code < 0) { - taosWUnLockLatch(&pSnode->pMeta->lock); + streamMetaWUnLock(pSnode->pMeta); return -1; } int32_t numOfTasks = streamMetaGetNumOfTasks(pSnode->pMeta); - taosWUnLockLatch(&pSnode->pMeta->lock); + streamMetaWUnLock(pSnode->pMeta); char* p = NULL; streamTaskGetStatus(pTask, &p); @@ -195,14 +195,14 @@ int32_t sndProcessTaskDropReq(SSnode *pSnode, char *msg, int32_t msgLen) { streamMetaUnregisterTask(pSnode->pMeta, pReq->streamId, pReq->taskId); // commit the update - taosWLockLatch(&pSnode->pMeta->lock); + streamMetaWLock(pSnode->pMeta); int32_t numOfTasks = streamMetaGetNumOfTasks(pSnode->pMeta); qDebug("vgId:%d task:0x%x dropped, remain tasks:%d", pSnode->pMeta->vgId, pReq->taskId, numOfTasks); if (streamMetaCommit(pSnode->pMeta) < 0) { // persist to disk } - taosWUnLockLatch(&pSnode->pMeta->lock); + streamMetaWUnLock(pSnode->pMeta); return 0; } diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index e934fd5192..7a14f8349f 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1023,10 +1023,10 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms int64_t streamId = pTask->id.streamId; bool added = false; - taosWLockLatch(&pStreamMeta->lock); + streamMetaWLock(pStreamMeta); code = streamMetaRegisterTask(pStreamMeta, sversion, pTask, &added); int32_t numOfTasks = streamMetaGetNumOfTasks(pStreamMeta); - taosWUnLockLatch(&pStreamMeta->lock); + streamMetaWUnLock(pStreamMeta); if (code < 0) { tqError("failed to add s-task:0x%x into vgId:%d meta, total:%d, code:%s", vgId, taskId, numOfTasks, tstrerror(code)); @@ -1406,14 +1406,14 @@ int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen) { streamMetaUnregisterTask(pMeta, pReq->streamId, pReq->taskId); // commit the update - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta); tqDebug("vgId:%d task:0x%x dropped, remain tasks:%d", vgId, pReq->taskId, numOfTasks); if (streamMetaCommit(pMeta) < 0) { // persist to disk } - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return 0; } @@ -1724,7 +1724,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp) taosThreadMutexUnlock(&pTask->lock); int32_t total = 0; - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); // set the initial value for generating check point // set the mgmt epset info according to the checkout source msg from mnode, todo update mgmt epset if needed @@ -1733,7 +1733,7 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp) } total = pMeta->numOfStreamTasks; - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); qInfo("s-task:%s (vgId:%d) level:%d receive checkpoint-source msg chkpt:%" PRId64 ", total checkpoint reqs:%d", pTask->id.idStr, vgId, pTask->info.taskLevel, req.checkpointId, total); @@ -1804,8 +1804,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { tDecoderClear(&decoder); // update the nodeEpset when it exists - taosWLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); // the task epset may be updated again and again, when replaying the WAL, the task may be in stop status. STaskId id = {.streamId = req.streamId, .taskId = req.taskId}; @@ -1814,8 +1813,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { tqError("vgId:%d failed to acquire task:0x%x when handling update, it may have been dropped already", pMeta->vgId, req.taskId); rsp.code = TSDB_CODE_SUCCESS; - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); taosArrayDestroy(req.pNodeList); return rsp.code; @@ -1838,22 +1836,19 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { tqDebug("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId, req.transId); rsp.code = TSDB_CODE_SUCCESS; - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); taosArrayDestroy(req.pNodeList); return rsp.code; } - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); // the following two functions should not be executed within the scope of meta lock to avoid deadlock streamTaskUpdateEpsetInfo(pTask, req.pNodeList); streamTaskResetStatus(pTask); // continue after lock the meta again - taosWLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); SStreamTask** ppHTask = NULL; if (HAS_RELATED_FILLHISTORY_TASK(pTask)) { @@ -1903,42 +1898,36 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { if (updateTasks < numOfTasks) { tqDebug("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, updateTasks, (numOfTasks - updateTasks)); - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); } else { if (!pTq->pVnode->restored) { tqDebug("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); pMeta->startInfo.startAllTasksFlag = 0; - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); } else { tqDebug("vgId:%d tasks are all updated and stopped, restart them", vgId); terrno = 0; - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); while (streamMetaTaskInTimer(pMeta)) { qDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); taosMsleep(100); } - taosWLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); int32_t code = streamMetaReopen(pMeta); if (code != 0) { tqError("vgId:%d failed to reopen stream meta", vgId); - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); taosArrayDestroy(req.pNodeList); return -1; } if (streamMetaLoadAllTasks(pTq->pStreamMeta) < 0) { tqError("vgId:%d failed to load stream tasks", vgId); - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); taosArrayDestroy(req.pNodeList); return -1; } @@ -1951,8 +1940,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { vInfo("vgId:%d, follower node not start stream tasks", vgId); } - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); } } diff --git a/source/dnode/vnode/src/tq/tqPush.c b/source/dnode/vnode/src/tq/tqPush.c index 50ee52f45b..f367bc96f8 100644 --- a/source/dnode/vnode/src/tq/tqPush.c +++ b/source/dnode/vnode/src/tq/tqPush.c @@ -35,9 +35,9 @@ int32_t tqPushMsg(STQ* pTq, tmsg_t msgType) { tqProcessSubmitReqForSubscribe(pTq); } - taosRLockLatch(&pTq->pStreamMeta->lock); + streamMetaRLock(pTq->pStreamMeta); int32_t numOfTasks = streamMetaGetNumOfTasks(pTq->pStreamMeta); - taosRUnLockLatch(&pTq->pStreamMeta->lock); + streamMetaRUnLock(pTq->pStreamMeta); // tqTrace("vgId:%d handle submit, restore:%d, numOfTasks:%d", TD_VID(pTq->pVnode), pTq->pVnode->restored, numOfTasks); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index dadbd30808..bd2a591a98 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -1111,7 +1111,7 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { taosWUnLockLatch(&pTq->lock); // update the table list handle for each stream scanner/wal reader - taosWLockLatch(&pTq->pStreamMeta->lock); + streamMetaWLock(pTq->pStreamMeta); while (1) { pIter = taosHashIterate(pTq->pStreamMeta->pTasksMap, pIter); if (pIter == NULL) { @@ -1128,6 +1128,6 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) { } } - taosWUnLockLatch(&pTq->pStreamMeta->lock); + streamMetaWUnLock(pTq->pStreamMeta); return 0; } diff --git a/source/dnode/vnode/src/tq/tqStreamTask.c b/source/dnode/vnode/src/tq/tqStreamTask.c index 6dc5a77fc1..e7993ac673 100644 --- a/source/dnode/vnode/src/tq/tqStreamTask.c +++ b/source/dnode/vnode/src/tq/tqStreamTask.c @@ -38,10 +38,10 @@ int32_t tqScanWal(STQ* pTq) { doScanWalForAllTasks(pTq->pStreamMeta, &shouldIdle); if (shouldIdle) { - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); int32_t times = (--pMeta->walScanCounter); ASSERT(pMeta->walScanCounter >= 0); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); if (times <= 0) { break; @@ -69,11 +69,11 @@ int32_t tqStartStreamTask(STQ* pTq) { } SArray* pTaskList = NULL; - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); pTaskList = taosArrayDup(pMeta->pTaskList, NULL); taosHashClear(pMeta->startInfo.pReadyTaskSet); pMeta->startInfo.startTs = taosGetTimestampMs(); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); // broadcast the check downstream tasks msg for (int32_t i = 0; i < numOfTasks; ++i) { @@ -146,12 +146,12 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) { return TSDB_CODE_SUCCESS; } - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList); if (numOfTasks == 0) { tqDebug("vgId:%d no stream tasks existed to run", vgId); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return 0; } @@ -162,7 +162,7 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) { if (pMeta->walScanCounter > 1) { tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return 0; } @@ -172,7 +172,7 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) { // reset the counter value, since we do not launch the scan wal operation. pMeta->walScanCounter = 0; - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return 0; } @@ -180,7 +180,7 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) { if (pRunReq == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; tqError("vgId:%d failed to create msg to start wal scanning to launch stream tasks, code:%s", vgId, terrstr()); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return -1; } @@ -191,7 +191,7 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) { SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)}; tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return 0; } @@ -207,9 +207,9 @@ int32_t tqStopStreamTasks(STQ* pTq) { } SArray* pTaskList = NULL; - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); pTaskList = taosArrayDup(pMeta->pTaskList, NULL); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); for (int32_t i = 0; i < numOfTasks; ++i) { SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i); @@ -410,9 +410,9 @@ int32_t doScanWalForAllTasks(SStreamMeta* pStreamMeta, bool* pScanIdle) { // clone the task list, to avoid the task update during scan wal files SArray* pTaskList = NULL; - taosWLockLatch(&pStreamMeta->lock); + streamMetaWLock(pStreamMeta); pTaskList = taosArrayDup(pStreamMeta->pTaskList, NULL); - taosWUnLockLatch(&pStreamMeta->lock); + streamMetaWUnLock(pStreamMeta); tqDebug("vgId:%d start to check wal to extract new submit block for %d tasks", vgId, numOfTasks); diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index 5d8fc6056c..4a0c987e57 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -555,13 +555,11 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) pVnode->restored = true; SStreamMeta* pMeta = pVnode->pTq->pStreamMeta; - taosWLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); if (pMeta->startInfo.startAllTasksFlag) { vInfo("vgId:%d, sync restore finished, stream tasks will be launched by other thread", vgId); - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return; } @@ -578,8 +576,7 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx) vInfo("vgId:%d, sync restore finished, not launch stream tasks since not leader", vgId); } - taosWUnLockLatch(&pMeta->lock); - tqDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); } static void vnodeBecomeFollower(const SSyncFSM *pFsm) { diff --git a/source/libs/stream/src/streamCheckpoint.c b/source/libs/stream/src/streamCheckpoint.c index 6d4f09b768..81840aaeb7 100644 --- a/source/libs/stream/src/streamCheckpoint.c +++ b/source/libs/stream/src/streamCheckpoint.c @@ -184,14 +184,13 @@ int32_t streamProcessCheckpointBlock(SStreamTask* pTask, SStreamDataBlock* pBloc { // todo: remove this when the pipeline checkpoint generating is used. SStreamMeta* pMeta = pTask->pMeta; - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); if (pMeta->chkptNotReadyTasks == 0) { pMeta->chkptNotReadyTasks = pMeta->numOfStreamTasks; } - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); } //todo fix race condition: set the status and append checkpoint block @@ -284,8 +283,7 @@ int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { int32_t vgId = pMeta->vgId; int32_t code = 0; - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); for (int32_t i = 0; i < taosArrayGetSize(pMeta->pTaskList); ++i) { STaskId* pId = taosArrayGet(pMeta->pTaskList, i); @@ -310,8 +308,7 @@ int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { code = streamTaskHandleEvent(p->status.pSM, TASK_EVENT_CHECKPOINT_DONE); if (code != TSDB_CODE_SUCCESS) { stDebug("s-task:%s vgId:%d save task status failed, since handle event failed", p->id.idStr, vgId); - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return -1; } else { // save the task streamMetaSaveTask(pMeta, p); @@ -332,8 +329,7 @@ int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId) { stInfo("vgId:%d commit stream meta after do checkpoint, checkpointId:%" PRId64 " DONE", pMeta->vgId, checkpointId); } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return code; } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index a1951b23cc..fd2aa47ef2 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -297,11 +297,11 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); // 2. save to disk - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); if (streamMetaCommit(pMeta) < 0) { // persist to disk } - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return TSDB_CODE_STREAM_TASK_NOT_EXIST; } else { stDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", pTask->id.idStr, @@ -357,9 +357,9 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); // 5. save to disk - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); pStreamTask->status.taskStatus = streamTaskGetStatus(pStreamTask, NULL); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); // 7. pause allowed. streamTaskEnablePause(pStreamTask); diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index ce7f325922..ee53e330db 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -447,20 +447,20 @@ int32_t streamMetaGetNumOfTasks(SStreamMeta* pMeta) { } SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) { - taosRLockLatch(&pMeta->lock); + streamMetaRLock(pMeta); STaskId id = {.streamId = streamId, .taskId = taskId}; SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); if (ppTask != NULL) { if (!streamTaskShouldStop(*ppTask)) { int32_t ref = atomic_add_fetch_32(&(*ppTask)->refCnt, 1); - taosRUnLockLatch(&pMeta->lock); + streamMetaRUnLock(pMeta); stTrace("s-task:%s acquire task, ref:%d", (*ppTask)->id.idStr, ref); return *ppTask; } } - taosRUnLockLatch(&pMeta->lock); + streamMetaRUnLock(pMeta); return NULL; } @@ -491,8 +491,7 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t SStreamTask* pTask = NULL; // pre-delete operation - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); STaskId id = {.streamId = streamId, .taskId = taskId}; SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); @@ -509,40 +508,34 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_DROPPING); } else { stDebug("vgId:%d failed to find the task:0x%x, it may be dropped already", pMeta->vgId, taskId); - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return 0; } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); stDebug("s-task:0x%x set task status:dropping and start to unregister it", taskId); while (1) { - taosRLockLatch(&pMeta->lock); + streamMetaRLock(pMeta); ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); if (ppTask) { if ((*ppTask)->status.timerActive == 0) { - taosRUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaRUnLock(pMeta); break; } taosMsleep(10); stDebug("s-task:%s wait for quit from timer", (*ppTask)->id.idStr); - taosRUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaRUnLock(pMeta); } else { - taosRUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaRUnLock(pMeta); break; } } // let's do delete of stream task - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &id, sizeof(id)); if (ppTask) { @@ -573,16 +566,15 @@ int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t t stDebug("vgId:%d failed to find the task:0x%x, it may have been dropped already", pMeta->vgId, taskId); } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return 0; } int32_t streamMetaBegin(SStreamMeta* pMeta) { - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); int32_t code = tdbBegin(pMeta->db, &pMeta->txn, tdbDefaultMalloc, tdbDefaultFree, NULL, TDB_TXN_WRITE | TDB_TXN_READ_UNCOMMITTED); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); return code; } @@ -890,7 +882,7 @@ void metaHbToMnode(void* param, void* tmrId) { stDebug("vgId:%d build stream task hb, leader:%d", pMeta->vgId, (pMeta->role == NODE_ROLE_LEADER)); SStreamHbMsg hbMsg = {0}; - taosRLockLatch(&pMeta->lock); + streamMetaRLock(pMeta); int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta); SEpSet epset = {0}; @@ -963,7 +955,7 @@ void metaHbToMnode(void* param, void* tmrId) { } hbMsg.numOfTasks = taosArrayGetSize(hbMsg.pTaskStatus); - taosRUnLockLatch(&pMeta->lock); + streamMetaRUnLock(pMeta); if (hasMnodeEpset) { int32_t code = 0; @@ -1018,8 +1010,7 @@ void metaHbToMnode(void* param, void* tmrId) { bool streamMetaTaskInTimer(SStreamMeta* pMeta) { bool inTimer = false; - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); void* pIter = NULL; while (1) { @@ -1034,9 +1025,7 @@ bool streamMetaTaskInTimer(SStreamMeta* pMeta) { } } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); - + streamMetaWUnLock(pMeta); return inTimer; } @@ -1046,8 +1035,7 @@ void streamMetaNotifyClose(SStreamMeta* pMeta) { stDebug("vgId:%d notify all stream tasks that the vnode is closing. isLeader:%d startHb%" PRId64 ", totalHb:%d", vgId, (pMeta->role == NODE_ROLE_LEADER), pMeta->pHbInfo->hbStart, pMeta->pHbInfo->hbCount); - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); void* pIter = NULL; while (1) { @@ -1061,8 +1049,7 @@ void streamMetaNotifyClose(SStreamMeta* pMeta) { streamTaskStop(pTask); } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); // wait for the stream meta hb function stopping if (pMeta->role == NODE_ROLE_LEADER) { @@ -1101,4 +1088,22 @@ void streamMetaResetStartInfo(STaskStartInfo* pStartInfo) { taosHashClear(pStartInfo->pReadyTaskSet); pStartInfo->startAllTasksFlag = 0; pStartInfo->readyTs = 0; -} \ No newline at end of file +} + +void streamMetaRLock(SStreamMeta* pMeta) { + stDebug("vgId:%d meta-rlock", pMeta->vgId); + taosRLockLatch(&pMeta->lock); +} +void streamMetaRUnLock(SStreamMeta* pMeta) { + stDebug("vgId:%d meta-runlock", pMeta->vgId); + taosRUnLockLatch(&pMeta->lock); +} +void streamMetaWLock(SStreamMeta* pMeta) { + stDebug("vgId:%d meta-wlock", pMeta->vgId); + taosWLockLatch(&pMeta->lock); +} +void streamMetaWUnLock(SStreamMeta* pMeta) { + stDebug("vgId:%d meta-wunlock", pMeta->vgId); + taosWUnLockLatch(&pMeta->lock); +} + diff --git a/source/libs/stream/src/streamStart.c b/source/libs/stream/src/streamStart.c index 098385c3ef..5ebc60dc13 100644 --- a/source/libs/stream/src/streamStart.c +++ b/source/libs/stream/src/streamStart.c @@ -583,10 +583,10 @@ int32_t streamProcessScanHistoryFinishRsp(SStreamTask* pTask) { int32_t code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); streamTaskSetSchedStatusInactive(pTask); - taosWLockLatch(&pMeta->lock); + streamMetaWLock(pMeta); streamMetaSaveTask(pMeta, pTask); streamMetaCommit(pMeta); - taosWUnLockLatch(&pMeta->lock); + streamMetaWUnLock(pMeta); // history data scan in the stream time window finished, now let's enable the pause streamTaskEnablePause(pTask); @@ -624,8 +624,7 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) { SLaunchHTaskInfo* pInfo = param; SStreamMeta* pMeta = pInfo->pMeta; - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasksMap, &pInfo->id, sizeof(pInfo->id)); if (ppTask) { @@ -639,13 +638,11 @@ static void tryLaunchHistoryTask(void* param, void* tmrId) { (*ppTask)->id.idStr, p, (*ppTask)->hTaskInfo.retryTimes, ref); taosMemoryFree(pInfo); - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return; } } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); SStreamTask* pTask = streamMetaAcquireTask(pMeta, pInfo->id.streamId, pInfo->id.taskId); if (pTask != NULL) { @@ -981,8 +978,7 @@ void streamTaskEnablePause(SStreamTask* pTask) { int32_t streamMetaUpdateTaskReadyInfo(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; - taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock", pMeta->vgId); + streamMetaWLock(pMeta); STaskId id = streamTaskExtractKey(pTask); taosHashPut(pMeta->startInfo.pReadyTaskSet, &id, sizeof(id), NULL, 0); @@ -1003,7 +999,6 @@ int32_t streamMetaUpdateTaskReadyInfo(SStreamTask* pTask) { pStartInfo->elapsedTime / 1000.0); } - taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-unlock", pMeta->vgId); + streamMetaWUnLock(pMeta); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/stream/src/streamState.c b/source/libs/stream/src/streamState.c index 4a056563ee..fb0090ec6d 100644 --- a/source/libs/stream/src/streamState.c +++ b/source/libs/stream/src/streamState.c @@ -121,7 +121,7 @@ SStreamState* streamStateOpen(char* path, void* pTask, bool specPath, int32_t sz #ifdef USE_ROCKSDB SStreamMeta* pMeta = pStreamTask->pMeta; pState->streamBackendRid = pMeta->streamBackendRid; - // taosWLockLatch(&pMeta->lock); + // streamMetaWLock(pMeta); taosThreadMutexLock(&pMeta->backendMutex); void* uniqueId = taosHashGet(pMeta->pTaskBackendUnique, pState->pTdbState->idstr, strlen(pState->pTdbState->idstr) + 1); From 9156e8449d2cedba16b4024700bbe82b37c89d52 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 17:25:59 +0800 Subject: [PATCH 18/43] fix(stream): fix deference null ptr. --- source/libs/stream/src/streamTaskSm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 78f864d6ec..bca8273a78 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -248,10 +248,12 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { stDebug("s-task:%s lock", pTask->id.idStr); if (pSM->pActiveTrans != NULL && pSM->pActiveTrans->autoInvokeEndFn) { + EStreamTaskEvent evt = pSM->pActiveTrans->event; taosThreadMutexUnlock(&pTask->lock); - taosMsleep(100); + stDebug("s-task:%s status:%s handling event:%s by some other thread, wait for 100ms and check if completed", - pTask->id.idStr, pSM->current.name, GET_EVT_NAME(pSM->pActiveTrans->event)); + pTask->id.idStr, pSM->current.name, GET_EVT_NAME(evt)); + taosMsleep(100); } else { pTrans = streamTaskFindTransform(pSM->current.state, event); if (pTrans == NULL) { From fa7ebf63eaf612249502b4001a0cf6a542558bf4 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 18:03:44 +0800 Subject: [PATCH 19/43] refactor: do some internal refactor. --- source/libs/stream/src/streamMeta.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index ee53e330db..b0bffac9ee 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -1093,17 +1093,22 @@ void streamMetaResetStartInfo(STaskStartInfo* pStartInfo) { void streamMetaRLock(SStreamMeta* pMeta) { stDebug("vgId:%d meta-rlock", pMeta->vgId); taosRLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-rlock done", pMeta->vgId); } void streamMetaRUnLock(SStreamMeta* pMeta) { stDebug("vgId:%d meta-runlock", pMeta->vgId); taosRUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-runlock done", pMeta->vgId); + } void streamMetaWLock(SStreamMeta* pMeta) { stDebug("vgId:%d meta-wlock", pMeta->vgId); taosWLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wlock done", pMeta->vgId); } void streamMetaWUnLock(SStreamMeta* pMeta) { stDebug("vgId:%d meta-wunlock", pMeta->vgId); taosWUnLockLatch(&pMeta->lock); + stDebug("vgId:%d meta-wunlock done", pMeta->vgId); } From 6dc468c55f29d967377232cbd6f96d0345fe90bc Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 19:09:21 +0800 Subject: [PATCH 20/43] fix(stream): fix dead-lock --- source/libs/stream/src/streamMeta.c | 47 +++++++++++++++++------------ 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index b0bffac9ee..e6d5f023d6 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -882,19 +882,33 @@ void metaHbToMnode(void* param, void* tmrId) { stDebug("vgId:%d build stream task hb, leader:%d", pMeta->vgId, (pMeta->role == NODE_ROLE_LEADER)); SStreamHbMsg hbMsg = {0}; + SEpSet epset = {0}; + bool hasMnodeEpset = false; + int32_t stage = 0; + streamMetaRLock(pMeta); + int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta); - - SEpSet epset = {0}; - bool hasMnodeEpset = false; - hbMsg.vgId = pMeta->vgId; + stage = pMeta->stage; + + SArray* pIdList = taosArrayDup(pMeta->pTaskList, NULL); + + streamMetaRUnLock(pMeta); + hbMsg.pTaskStatus = taosArrayInit(numOfTasks, sizeof(STaskStatusEntry)); hbMsg.pUpdateNodes = taosArrayInit(numOfTasks, sizeof(int32_t)); for (int32_t i = 0; i < numOfTasks; ++i) { - STaskId* pId = taosArrayGet(pMeta->pTaskList, i); + STaskId* pId = taosArrayGet(pIdList, i); + + streamMetaRLock(pMeta); SStreamTask** pTask = taosHashGet(pMeta->pTasksMap, pId, sizeof(*pId)); + streamMetaRUnLock(pMeta); + + if (pTask == NULL) { + continue; + } // not report the status of fill-history task if ((*pTask)->info.fillHistory == 1) { @@ -904,12 +918,12 @@ void metaHbToMnode(void* param, void* tmrId) { STaskStatusEntry entry = { .id = *pId, .status = streamTaskGetStatus(*pTask, NULL), - .nodeId = pMeta->vgId, - .stage = pMeta->stage, + .nodeId = hbMsg.vgId, + .stage = stage, .inputQUsed = SIZE_IN_MiB(streamQueueGetItemSize((*pTask)->inputq.queue)), }; - entry.inputRate = entry.inputQUsed*100.0/STREAM_TASK_QUEUE_CAPACITY_IN_SIZE; + entry.inputRate = entry.inputQUsed * 100.0 / STREAM_TASK_QUEUE_CAPACITY_IN_SIZE; if ((*pTask)->info.taskLevel == TASK_LEVEL__SINK) { entry.sinkQuota = (*pTask)->outputInfo.pTokenBucket->quotaRate; entry.sinkDataSize = SIZE_IN_MiB((*pTask)->execInfo.sink.dataSize); @@ -928,9 +942,9 @@ void metaHbToMnode(void* param, void* tmrId) { taosThreadMutexLock(&(*pTask)->lock); int32_t num = taosArrayGetSize((*pTask)->outputInfo.pDownstreamUpdateList); for (int j = 0; j < num; ++j) { - int32_t *pNodeId = taosArrayGet((*pTask)->outputInfo.pDownstreamUpdateList, j); + int32_t* pNodeId = taosArrayGet((*pTask)->outputInfo.pDownstreamUpdateList, j); - bool exist = false; + bool exist = false; int32_t numOfExisted = taosArrayGetSize(hbMsg.pUpdateNodes); for (int k = 0; k < numOfExisted; ++k) { if (*pNodeId == *(int32_t*)taosArrayGet(hbMsg.pUpdateNodes, k)) { @@ -955,7 +969,6 @@ void metaHbToMnode(void* param, void* tmrId) { } hbMsg.numOfTasks = taosArrayGetSize(hbMsg.pTaskStatus); - streamMetaRUnLock(pMeta); if (hasMnodeEpset) { int32_t code = 0; @@ -1091,24 +1104,20 @@ void streamMetaResetStartInfo(STaskStartInfo* pStartInfo) { } void streamMetaRLock(SStreamMeta* pMeta) { - stDebug("vgId:%d meta-rlock", pMeta->vgId); + stTrace("vgId:%d meta-rlock", pMeta->vgId); taosRLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-rlock done", pMeta->vgId); } void streamMetaRUnLock(SStreamMeta* pMeta) { - stDebug("vgId:%d meta-runlock", pMeta->vgId); + stTrace("vgId:%d meta-runlock", pMeta->vgId); taosRUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-runlock done", pMeta->vgId); } void streamMetaWLock(SStreamMeta* pMeta) { - stDebug("vgId:%d meta-wlock", pMeta->vgId); + stTrace("vgId:%d meta-wlock", pMeta->vgId); taosWLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wlock done", pMeta->vgId); } void streamMetaWUnLock(SStreamMeta* pMeta) { - stDebug("vgId:%d meta-wunlock", pMeta->vgId); + stTrace("vgId:%d meta-wunlock", pMeta->vgId); taosWUnLockLatch(&pMeta->lock); - stDebug("vgId:%d meta-wunlock done", pMeta->vgId); } From e1b3e00b3d17b6cd1dcd284f7d1080372021f7e6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 1 Nov 2023 20:10:20 +0800 Subject: [PATCH 21/43] fix(stream): fix memory leak. --- source/libs/stream/src/streamDispatch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 14129522d6..d9f73c1ba0 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -429,6 +429,7 @@ static void doRetryDispatchData(void* param, void* tmrId) { ASSERT(pTask->outputq.status == TASK_OUTPUT_STATUS__WAIT); int32_t code = 0; + { SArray* pList = taosArrayDup(pTask->msgInfo.pRetryList, NULL); taosArrayClear(pTask->msgInfo.pRetryList); @@ -440,7 +441,7 @@ static void doRetryDispatchData(void* param, void* tmrId) { int32_t numOfVgroups = taosArrayGetSize(vgInfo); int32_t numOfFailed = taosArrayGetSize(pList); - stDebug("s-task:%s (child taskId:%d) re-try shuffle-dispatch blocks to %d vgroup(s), msgId:%d", + stDebug("s-task:%s (child taskId:%d) retry shuffle-dispatch blocks to %d vgroup(s), msgId:%d", id, pTask->info.selfChildId, numOfFailed, msgId); for (int32_t i = 0; i < numOfFailed; i++) { @@ -471,6 +472,8 @@ static void doRetryDispatchData(void* param, void* tmrId) { code = doSendDispatchMsg(pTask, pReq, vgId, pEpSet); } + + taosArrayDestroy(pList); } if (code != TSDB_CODE_SUCCESS) { From dc8a90c864d9d3c65f1da37fe28550d86d58bf63 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 08:11:51 +0800 Subject: [PATCH 22/43] fix(stream): fix memory leak. --- source/libs/stream/src/streamDispatch.c | 6 +++--- source/libs/stream/src/streamMeta.c | 26 ++++++++++++------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index d9f73c1ba0..edfc66762d 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -41,9 +41,9 @@ static int32_t tInitStreamDispatchReq(SStreamDispatchReq* pReq, const SStreamTas int32_t numOfBlocks, int64_t dstTaskId, int32_t type); void initRpcMsg(SRpcMsg* pMsg, int32_t msgType, void* pCont, int32_t contLen) { - pMsg->msgType = msgType; - pMsg->pCont = pCont; - pMsg->contLen = contLen; + pMsg->msgType = msgType; + pMsg->pCont = pCont; + pMsg->contLen = contLen; } int32_t tEncodeStreamDispatchReq(SEncoder* pEncoder, const SStreamDispatchReq* pReq) { diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index e6d5f023d6..887e879934 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -844,6 +844,12 @@ static bool waitForEnoughDuration(SMetaHbInfo* pInfo) { return false; } +static void clearHbMsg(SStreamHbMsg* pMsg, SArray* pIdList) { + taosArrayDestroy(pMsg->pTaskStatus); + taosArrayDestroy(pMsg->pUpdateNodes); + taosArrayDestroy(pIdList); +} + void metaHbToMnode(void* param, void* tmrId) { int64_t rid = *(int64_t*)param; @@ -977,17 +983,13 @@ void metaHbToMnode(void* param, void* tmrId) { tEncodeSize(tEncodeStreamHbMsg, &hbMsg, tlen, code); if (code < 0) { stError("vgId:%d encode stream hb msg failed, code:%s", pMeta->vgId, tstrerror(code)); - taosArrayDestroy(hbMsg.pTaskStatus); - taosReleaseRef(streamMetaId, rid); - return; + goto _end; } void* buf = rpcMallocCont(tlen); if (buf == NULL) { stError("vgId:%d encode stream hb msg failed, code:%s", pMeta->vgId, tstrerror(TSDB_CODE_OUT_OF_MEMORY)); - taosArrayDestroy(hbMsg.pTaskStatus); - taosReleaseRef(streamMetaId, rid); - return; + goto _end; } SEncoder encoder; @@ -995,15 +997,12 @@ void metaHbToMnode(void* param, void* tmrId) { if ((code = tEncodeStreamHbMsg(&encoder, &hbMsg)) < 0) { rpcFreeCont(buf); stError("vgId:%d encode stream hb msg failed, code:%s", pMeta->vgId, tstrerror(code)); - taosArrayDestroy(hbMsg.pTaskStatus); - taosReleaseRef(streamMetaId, rid); - return; + goto _end; } tEncoderClear(&encoder); - SRpcMsg msg = {0}; + SRpcMsg msg = {.info.noResp = 1,}; initRpcMsg(&msg, TDMT_MND_STREAM_HEARTBEAT, buf, tlen); - msg.info.noResp = 1; pMeta->pHbInfo->hbCount += 1; @@ -1014,9 +1013,8 @@ void metaHbToMnode(void* param, void* tmrId) { stDebug("vgId:%d no tasks and no mnd epset, not send stream hb to mnode", pMeta->vgId); } - taosArrayDestroy(hbMsg.pTaskStatus); - taosArrayDestroy(hbMsg.pUpdateNodes); - + _end: + clearHbMsg(&hbMsg, pIdList); taosTmrReset(metaHbToMnode, META_HB_CHECK_INTERVAL, param, streamEnv.timer, &pMeta->pHbInfo->hbTmr); taosReleaseRef(streamMetaId, rid); } From b71a013b8d3627eee126f6a61d7b591bd7f3e252 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Wed, 1 Nov 2023 20:24:24 +0800 Subject: [PATCH 23/43] fix: nano seconds database error --- docs/en/12-taos-sql/10-function.md | 6 ++- docs/zh/12-taos-sql/10-function.md | 4 +- include/util/taoserror.h | 3 +- source/common/src/ttime.c | 2 +- source/common/test/commonTests.cpp | 2 +- source/libs/function/src/builtins.c | 2 +- source/libs/scalar/src/sclfunc.c | 2 +- source/util/src/terror.c | 3 +- .../2-query/func_to_char_timestamp.py | 38 +++++++++++++++++++ 9 files changed, 53 insertions(+), 9 deletions(-) diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index 18c7ffc345..5be14093de 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -539,7 +539,8 @@ TO_CHAR(ts, format_str_literal) - When `ms`,`us`,`ns` are used in `to_char`, like `to_char(ts, 'yyyy-mm-dd hh:mi:ss.ms.us.ns')`, The time of `ms`,`us`,`ns` corresponds to the same fraction seconds. When ts is `1697182085123`, the output of `ms` is `123`, `us` is `123000`, `ns` is `123000000`. - If we want to output some characters of format without converting, surround it with double quotes. `to_char(ts, 'yyyy-mm-dd "is formated by yyyy-mm-dd"')`. If want to output double quotes, add a back slash before double quote, like `to_char(ts, '\"yyyy-mm-dd\"')` will output `"2023-10-10"`. - For formats that output digits, the uppercase and lowercase formats are the same. -- It's recommended to put time zone in the format, if not, the default time zone zone will be that in server or client. +- It's recommended to put time zone in the format, if not, the default time zone will be that in server or client. +- The precision of the input timestamp will be recognized automatically according to the precision of the table used. #### TO_TIMESTAMP @@ -564,9 +565,10 @@ TO_TIMESTAMP(ts_str_literal, format_str_literal) - The uppercase or lowercase of `MONTH`, `MON`, `DAY`, `DY` and formtas that output digits have same effect when used in `to_timestamp`, like `to_timestamp('2023-JANUARY-01', 'YYYY-month-dd')`, `month` can be replaced by `MONTH`, or `month`. The cases are ignored. - If multi times are specified for one component, the previous will be overwritten. Like `to_timestamp('2023-22-10-10', 'yyyy-yy-MM-dd')`, the output year will be `2022`. - To avoid unexpected time zone used during the convertion, it's recommended to put time zone in the ts string, e.g. '2023-10-10 10:10:10+08'. If time zone not specified, default will be that in server or client. -- The default timestamp if some components are not specified will be: `1970-01-01 00:00:00` with specified or default local timezone. +- The default timestamp if some components are not specified will be: `1970-01-01 00:00:00` with the timezone specified or default to local timezone. - If `AM` or `PM` is specified in formats, the Hour must between `1-12`. - In some cases, `to_timestamp` can convert correctly even the format and the timestamp string are not totally matched. Like `to_timetamp('200101/2', 'yyyyMM1/dd')`, the digit `1` in format string are ignored, and the output timestsamp is `2001-01-02 00:00:00`. Spaces and tabs in formats and tiemstamp string are also ignored automatically. +- The precision of the output timestamp will be the same as the table in SELECT stmt, millisecond will be used if no table is specified. The output of `select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns')` will be truncated to millisecond precision. If a nano precision table is specified, no truncation will be applied. Like `select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns') from db_ns.table_ns limit 1`. ### Time and Date Functions diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md index 4371124623..723f299cbc 100644 --- a/docs/zh/12-taos-sql/10-function.md +++ b/docs/zh/12-taos-sql/10-function.md @@ -540,6 +540,7 @@ TO_CHAR(ts, format_str_literal) - 时间格式中无法匹配规则的内容会直接输出. 如果想要在格式串中指定某些能够匹配规则的部分不做转换, 可以使用双引号, 如`to_char(ts, 'yyyy-mm-dd "is formated by yyyy-mm-dd"')`. 如果想要输出双引号, 那么在双引号之前加一个反斜杠, 如 `to_char(ts, '\"yyyy-mm-dd\"')` 将会输出 `"2023-10-10"`. - 那些输出是数字的格式, 如`YYYY`, `DD`, 大写与小写意义相同, 即`yyyy` 和 `YYYY` 可以互换. - 推荐在时间格式中带时区信息,如果不带则默认输出的时区为服务端或客户端所配置的时区. +- 输入时间戳的精度由所查询表的精度确定. #### TO_TIMESTAMP @@ -560,13 +561,14 @@ TO_TIMESTAMP(ts_str_literal, format_str_literal) **支持的格式**: 与`to_char`相同 **使用说明**: -- 若`ms`, `us`, `ns`同时指定, 那么结果时间戳包含上述三个字段的和. 如 `to_timestamp('2023-10-10 10:10:10.123.000456.000000789', 'yyyy-mm-dd hh:mi:ss.ms.us.ns')` 输出是 `2023-10-10 10:10:10.123456789`. +- 若`ms`, `us`, `ns`同时指定, 那么结果时间戳包含上述三个字段的和. 如 `to_timestamp('2023-10-10 10:10:10.123.000456.000000789', 'yyyy-mm-dd hh:mi:ss.ms.us.ns')` 输出为 `2023-10-10 10:10:10.123456789`对应的时间戳. - `MONTH`, `MON`, `DAY`, `DY` 以及其他输出为数字的格式的大小写意义相同, 如 `to_timestamp('2023-JANUARY-01', 'YYYY-month-dd')`, `month`可以被替换为`MONTH` 或者`Month`. - 如果同一字段被指定了多次, 那么前面的指定将会被覆盖. 如 `to_timestamp('2023-22-10-10', 'yyyy-yy-MM-dd')`, 输出年份是`2022`. - 为避免转换时使用了非预期的时区,推荐在时间中携带时区信息,例如'2023-10-10 10:10:10+08',如果未指定时区则默认时区为服务端或客户端指定的时区。 - 如果没有指定完整的时间,那么默认时间值为指定或默认时区的 `1970-01-01 00:00:00`, 未指定部分使用该默认值中的对应部分. - 如果格式串中有`AM`, `PM`等, 那么小时必须是12小时制, 范围必须是01-12. - `to_timestamp`转换具有一定的容错机制, 在格式串和时间戳串不完全对应时, 有时也可转换, 如: `to_timestamp('200101/2', 'yyyyMM1/dd')`, 格式串中多出来的1会被丢弃. 格式串与时间戳串中多余的空格字符(空格, tab等)也会被 自动忽略. 如`to_timestamp(' 23 年 - 1 月 - 01 日 ', 'yy 年-MM月-dd日')` 可以被成功转换. 虽然`MM`等字段需要两个数字对应(只有一位时前面补0), 在`to_timestamp`时, 一个数字也可以成功转换. +- 输出时间戳的精度与查询表的精度相同, 若查询未指定表, 则输出精度为毫秒. 如`select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns')`的输出将会把微妙和纳秒进行截断. 如果指定一张纳秒表, 那么就不会发生截断, 如`select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns') from db_ns.table_ns limit 1`. ### 时间和日期函数 diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 8748ea99a2..00009bf6da 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -741,7 +741,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_FUNC_FUNTION_PARA_VALUE TAOS_DEF_ERROR_CODE(0, 0x2803) #define TSDB_CODE_FUNC_NOT_BUILTIN_FUNTION TAOS_DEF_ERROR_CODE(0, 0x2804) #define TSDB_CODE_FUNC_DUP_TIMESTAMP TAOS_DEF_ERROR_CODE(0, 0x2805) -#define TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED TAOS_DEF_ERROR_CODE(0, 0x2806) +#define TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_FORMAT_ERR TAOS_DEF_ERROR_CODE(0, 0x2806) +#define TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_TS_ERR TAOS_DEF_ERROR_CODE(0, 0x2807) //udf #define TSDB_CODE_UDF_STOPPING TAOS_DEF_ERROR_CODE(0, 0x2901) diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index 6b5bb8680e..4b0848e5e9 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -1320,7 +1320,7 @@ static void tm2char(const SArray* formats, const struct STm* tm, char* s, int32_ s += 4; break; case TSFKW_DDD: - sprintf(s, "%d", tm->tm.tm_yday); + sprintf(s, "%03d", tm->tm.tm_yday + 1); s += strlen(s); break; case TSFKW_DD: diff --git a/source/common/test/commonTests.cpp b/source/common/test/commonTests.cpp index dc320ebcb2..c65d8761b7 100644 --- a/source/common/test/commonTests.cpp +++ b/source/common/test/commonTests.cpp @@ -344,7 +344,7 @@ TEST(timeTest, ts2char) { "day-\"日\"", TSDB_TIME_PRECISION_MILLI, "2023-023-23-3-2023-023-23-3-年-OCTOBER -OCT-October -Oct-october " - "-oct-月-285-13-6-285-13-6-FRIDAY -Friday -friday -日"); + "-oct-月-286-13-6-286-13-6-FRIDAY -Friday -friday -日"); #endif ts = 1697182085123L; // Friday, October 13, 2023 3:28:05.123 PM GMT+08:00 test_ts2char(ts, "HH24:hh24:HH12:hh12:HH:hh:MI:mi:SS:ss:MS:ms:US:us:NS:ns:PM:AM:pm:am", TSDB_TIME_PRECISION_MILLI, diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 84aff9fa88..fdbc0b4038 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -3315,7 +3315,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "to_timestamp", .type = FUNCTION_TYPE_TO_TIMESTAMP, - .classification = FUNC_MGT_SCALAR_FUNC, + .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC, .translateFunc = translateToTimestamp, .getEnvFunc = NULL, .initFunc = NULL, diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 48886b1eec..dbdd79cc65 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1230,7 +1230,7 @@ int32_t toTimestampFunction(SScalarParam* pInput, int32_t inputNum, SScalarParam code = taosChar2Ts(format, &formats, tsStr, &ts, precision, errMsg, 128); if (code) { qError("func to_timestamp failed %s", errMsg); - code = TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED; + code = code == -1 ? TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_FORMAT_ERR : TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_TS_ERR; break; } colDataSetVal(pOutput->columnData, i, (char *)&ts, false); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 30daad62bf..0ffa77e365 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -604,7 +604,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_FUNTION_PARA_TYPE, "Invalid function par TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_FUNTION_PARA_VALUE, "Invalid function para value") TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_NOT_BUILTIN_FUNTION, "Not buildin function") TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_DUP_TIMESTAMP, "Duplicate timestamps not allowed in function") -TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED, "Func to_timestamp failed, check log for detail") +TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_FORMAT_ERR, "Func to_timestamp failed, format mismatch") +TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_TO_TIMESTAMP_FAILED_TS_ERR, "Func to_timestamp failed, wrong timestamp") //udf TAOS_DEFINE_ERROR(TSDB_CODE_UDF_STOPPING, "udf is stopping") diff --git a/tests/system-test/2-query/func_to_char_timestamp.py b/tests/system-test/2-query/func_to_char_timestamp.py index 639811d275..d955e00a82 100644 --- a/tests/system-test/2-query/func_to_char_timestamp.py +++ b/tests/system-test/2-query/func_to_char_timestamp.py @@ -166,6 +166,44 @@ class TDTestCase: def run(self): self.prepareTestEnv() self.test_to_timestamp() + self.test_ns_to_timestamp() + + def create_tables(self): + tdSql.execute("create database if not exists test_us precision 'us'") + tdSql.execute("create database if not exists test_ns precision 'ns'") + tdSql.execute("use test_us") + tdSql.execute(f"CREATE STABLE `meters_us` (`ts` TIMESTAMP, `ip_value` FLOAT, `ip_quality` INT, `ts2` timestamp) TAGS (`t1` INT)") + tdSql.execute(f"CREATE TABLE `ctb1_us` USING `meters_us` (`t1`) TAGS (1)") + tdSql.execute(f"CREATE TABLE `ctb2_us` USING `meters_us` (`t1`) TAGS (2)") + tdSql.execute("use test_ns") + tdSql.execute(f"CREATE STABLE `meters_ns` (`ts` TIMESTAMP, `ip_value` FLOAT, `ip_quality` INT, `ts2` timestamp) TAGS (`t1` INT)") + tdSql.execute(f"CREATE TABLE `ctb1_ns` USING `meters_ns` (`t1`) TAGS (1)") + tdSql.execute(f"CREATE TABLE `ctb2_ns` USING `meters_ns` (`t1`) TAGS (2)") + + def insert_ns_data(self): + tdLog.debug("start to insert data ............") + tdSql.execute(f"INSERT INTO `test_us`.`ctb1_us` VALUES ('2023-07-01 00:00:00.123456', 10.30000, 100, '2023-07-01 00:00:00.123456')") + tdSql.execute(f"INSERT INTO `test_us`.`ctb2_us` VALUES ('2023-08-01 00:00:00.123456', 20.30000, 200, '2023-07-01 00:00:00.123456')") + tdSql.execute(f"INSERT INTO `test_ns`.`ctb1_ns` VALUES ('2023-07-01 00:00:00.123456789', 10.30000, 100, '2023-07-01 00:00:00.123456000')") + tdSql.execute(f"INSERT INTO `test_ns`.`ctb2_ns` VALUES ('2023-08-01 00:00:00.123456789', 20.30000, 200, '2023-08-01 00:00:00.123456789')") + tdLog.debug("insert data ............ [OK]") + + def test_ns_to_timestamp(self): + self.create_tables() + self.insert_ns_data() + tdSql.query("select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns')", queryTimes=1) + tdSql.checkData(0, 0, 1690855810123) + tdSql.execute('use test_ns', queryTimes=1) + tdSql.query("select to_timestamp('2023-08-1 10:10:10.123456789', 'yyyy-mm-dd hh:mi:ss.ns')", queryTimes=1) + tdSql.checkData(0, 0, 1690855810123) + tdSql.query("select to_char(ts2, 'yyyy-mm-dd hh:mi:ss.ns') from meters_ns", queryTimes=1) + tdSql.checkData(0, 0, '2023-07-01 12:00:00.123456000') + tdSql.checkData(1, 0, '2023-08-01 12:00:00.123456789') + + tdSql.query("select to_timestamp(to_char(ts2, 'yyyy-mm-dd hh:mi:ss.ns'), 'yyyy-mm-dd hh:mi:ss.ns') from meters_ns", queryTimes=1) + tdSql.checkData(0, 0, 1688140800123456000) + tdSql.checkData(1, 0, 1690819200123456789) + def stop(self): tdSql.close() From d0327e07b833bb3086a294ad44ba562e82e7c18f Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Thu, 2 Nov 2023 09:42:19 +0800 Subject: [PATCH 24/43] tsdb/pg-cache: use pgno for cache key instead of blkno --- source/dnode/vnode/src/tsdb/tsdbCache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 7cea469c34..94e6152487 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -3169,7 +3169,7 @@ int32_t tsdbCacheGetPageS3(SLRUCache *pCache, STsdbFD *pFD, int64_t pgno, LRUHan char key[128] = {0}; int keyLen = 0; - getBCacheKey(pFD->fid, pFD->cid, pFD->blkno, key, &keyLen); + getBCacheKey(pFD->fid, pFD->cid, pgno, key, &keyLen); *handle = taosLRUCacheLookup(pCache, key, keyLen); return code; From 46d3be1f08eeebee07e6d3c53eb05cbbc649e4e6 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Thu, 2 Nov 2023 10:10:03 +0800 Subject: [PATCH 25/43] config/page-cache-size: new parameter for pcache size --- source/common/src/tglobal.c | 17 +++++++++++++---- source/dnode/mnode/impl/src/mndDnode.c | 18 +++++++++++++++++- source/dnode/vnode/src/inc/vndCos.h | 1 + source/dnode/vnode/src/tsdb/tsdbCache.c | 2 +- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 485b67e1a7..3c16554ac6 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -280,8 +280,9 @@ int8_t tsS3Enabled = false; int8_t tsS3Https = true; char tsS3Hostname[TSDB_FQDN_LEN] = ""; -int32_t tsS3BlockSize = -1; // number of tsdb pages (4096) -int32_t tsS3BlockCacheSize = 1024; // number of blocks/pages (16) +int32_t tsS3BlockSize = -1; // number of tsdb pages (4096) +int32_t tsS3BlockCacheSize = 16; // number of blocks +int32_t tsS3PageCacheSize = 1024; // number of pages int32_t tsS3UploadDelaySec = 60 * 60; #ifndef _STORAGE @@ -697,8 +698,8 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { if (cfgAddString(pCfg, "s3Endpoint", tsS3Endpoint, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddString(pCfg, "s3BucketName", tsS3BucketName, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3BlockSize", tsS3BlockSize, -100, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; - if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024 * 1024, CFG_SCOPE_SERVER) != 0) - return -1; + if (cfgAddInt32(pCfg, "s3BlockCacheSize", tsS3BlockCacheSize, 4, 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; + if (cfgAddInt32(pCfg, "s3PageCacheSize", tsS3PageCacheSize, 4, 1024 * 1024 * 1024, CFG_SCOPE_SERVER) != 0) return -1; if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 10, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER) != 0) return -1; @@ -1132,6 +1133,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsS3BlockSize = cfgGetItem(pCfg, "s3BlockSize")->i32; tsS3BlockCacheSize = cfgGetItem(pCfg, "s3BlockCacheSize")->i32; + tsS3PageCacheSize = cfgGetItem(pCfg, "s3PageCacheSize")->i32; tsS3UploadDelaySec = cfgGetItem(pCfg, "s3UploadDelaySec")->i32; GRANT_CFG_GET; @@ -1726,6 +1728,13 @@ void taosCfgDynamicOptions(const char *option, const char *value) { return; } + if (strcasecmp(option, "s3PageCacheSize") == 0) { + int32_t newS3PageCacheSize = atoi(value); + uInfo("s3PageCacheSize set from %d to %d", tsS3PageCacheSize, newS3PageCacheSize); + tsS3PageCacheSize = newS3PageCacheSize; + return; + } + if (strcasecmp(option, "s3UploadDelaySec") == 0) { int32_t newS3UploadDelaysec = atoi(value); uInfo("s3UploadDelaySec set from %d to %d", tsS3UploadDelaySec, newS3UploadDelaysec); diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index e2c21ed012..46f7c6c3e2 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -1250,7 +1250,7 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); if (code < 0) return code; - if (flag < 4 || flag > 1024 * 1024 * 1024) { + if (flag < 4 || flag > 1024 * 1024) { mError("dnode:%d, failed to config s3BlockCacheSize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId, flag); terrno = TSDB_CODE_INVALID_CFG; @@ -1260,6 +1260,22 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { strcpy(dcfgReq.config, "s3blockcachesize"); snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); + } else if (strncasecmp(cfgReq.config, "s3pagecachesize", 16) == 0) { + int32_t optLen = strlen("s3pagecachesize"); + int32_t flag = -1; + int32_t code = mndMCfgGetValInt32(&cfgReq, optLen, &flag); + if (code < 0) return code; + + if (flag < 4 || flag > 1024 * 1024 * 1024) { + mError("dnode:%d, failed to config s3PageCacheSize since value:%d. Valid range: [4, 1024 * 1024]", cfgReq.dnodeId, + flag); + terrno = TSDB_CODE_INVALID_CFG; + tFreeSMCfgDnodeReq(&cfgReq); + return -1; + } + + strcpy(dcfgReq.config, "s3pagecachesize"); + snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); } else if (strncasecmp(cfgReq.config, "s3uploaddelaysec", 16) == 0) { int32_t optLen = strlen("s3uploaddelaysec"); int32_t flag = -1; diff --git a/source/dnode/vnode/src/inc/vndCos.h b/source/dnode/vnode/src/inc/vndCos.h index 6612b5c653..8581b039f8 100644 --- a/source/dnode/vnode/src/inc/vndCos.h +++ b/source/dnode/vnode/src/inc/vndCos.h @@ -27,6 +27,7 @@ extern "C" { extern int8_t tsS3Enabled; extern int32_t tsS3BlockSize; extern int32_t tsS3BlockCacheSize; +extern int32_t tsS3PageCacheSize; extern int32_t tsS3UploadDelaySec; int32_t s3Init(); diff --git a/source/dnode/vnode/src/tsdb/tsdbCache.c b/source/dnode/vnode/src/tsdb/tsdbCache.c index 94e6152487..bf6f0cf4d6 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCache.c +++ b/source/dnode/vnode/src/tsdb/tsdbCache.c @@ -92,7 +92,7 @@ static int32_t tsdbOpenPgCache(STsdb *pTsdb) { // SLRUCache *pCache = taosLRUCacheInit(10 * 1024 * 1024, 0, .5); int32_t szPage = pTsdb->pVnode->config.tsdbPageSize; - SLRUCache *pCache = taosLRUCacheInit((int64_t)tsS3BlockCacheSize * szPage, 0, .5); + SLRUCache *pCache = taosLRUCacheInit((int64_t)tsS3PageCacheSize * szPage, 0, .5); if (pCache == NULL) { code = TSDB_CODE_OUT_OF_MEMORY; goto _err; From 05b3d518037407cbd99f85114138ef9e04264ee6 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 08:46:18 +0800 Subject: [PATCH 26/43] fix(stream): add qualified status in assert --- source/libs/stream/src/streamTaskSm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index bca8273a78..6c91bbf2d8 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -139,9 +139,10 @@ static STaskStateTrans* streamTaskFindTransform(ETaskStatus state, const EStream void streamTaskRestoreStatus(SStreamTask* pTask) { SStreamTaskSM* pSM = pTask->status.pSM; - taosThreadMutexLock(&pTask->lock); - ASSERT(pSM->pActiveTrans == NULL); + taosThreadMutexLock(&pTask->lock); + + ASSERT(pSM->pActiveTrans == NULL); ASSERT(pSM->current.state == TASK_STATUS__PAUSE || pSM->current.state == TASK_STATUS__HALT); SStreamTaskState state = pSM->current; @@ -289,13 +290,13 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even // do update the task status taosThreadMutexLock(&pTask->lock); - stDebug("s-task:%s lock", pTask->id.idStr); STaskStateTrans* pTrans = pSM->pActiveTrans; - if (pTrans == NULL) { ETaskStatus s = pSM->current.state; - ASSERT(s == TASK_STATUS__DROPPING || s == TASK_STATUS__PAUSE || s == TASK_STATUS__STOP); + ASSERT(s == TASK_STATUS__DROPPING || s == TASK_STATUS__PAUSE || s == TASK_STATUS__STOP || + s == TASK_STATUS__UNINIT || s == TASK_STATUS__READY); + // the pSM->prev.evt may be 0, so print string is not appropriate. stDebug("s-task:%s event:%s handled failed, current status:%s, trigger event:%s", pTask->id.idStr, GET_EVT_NAME(event), pSM->current.name, GET_EVT_NAME(pSM->prev.evt)); @@ -309,7 +310,6 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even stWarn("s-task:%s handle event:%s failed, current status:%s, active trans evt:%s", pTask->id.idStr, GET_EVT_NAME(event), pSM->current.name, GET_EVT_NAME(pTrans->event)); taosThreadMutexUnlock(&pTask->lock); - stDebug("s-task:%s unlocky", pTask->id.idStr); return TSDB_CODE_INVALID_PARA; } @@ -342,7 +342,6 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even pSM->pActiveTrans = pNextTrans; pSM->startTs = taosGetTimestampMs(); taosThreadMutexUnlock(&pTask->lock); - stDebug("s-task:%s unlockf", pTask->id.idStr); int32_t code = pNextTrans->pAction(pSM->pTask); if (pNextTrans->autoInvokeEndFn) { @@ -358,7 +357,6 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even } } else { taosThreadMutexUnlock(&pTask->lock); - stDebug("s-task:%s unlockz", pTask->id.idStr); int64_t el = (taosGetTimestampMs() - pSM->startTs); stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr, From 95efa07e9237e5db14517d94d5c38d185d4d9598 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 09:43:48 +0800 Subject: [PATCH 27/43] fix(stream): add full unsupported event filtering. --- include/util/taoserror.h | 1 + source/dnode/vnode/src/tq/tq.c | 89 ++++++++++++------------ source/dnode/vnode/src/tq/tqStreamTask.c | 9 ++- source/libs/stream/src/streamTaskSm.c | 49 +++++++++---- source/util/src/terror.c | 2 + 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index b89ea93c7b..55dba97862 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -807,6 +807,7 @@ int32_t* taosGetErrno(); // stream #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) #define TSDB_CODE_STREAM_EXEC_CANCELLED TAOS_DEF_ERROR_CODE(0, 0x4102) +#define TSDB_CODE_STREAM_INVALID_STATETRANS TAOS_DEF_ERROR_CODE(0, 0x4103) // TDLite #define TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS TAOS_DEF_ERROR_CODE(0, 0x5100) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 7a14f8349f..e8662c74df 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1064,6 +1064,47 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms return code; } +static void doStartStep2(SStreamTask* pTask, SStreamTask* pStreamTask, STQ* pTq) { + const char* id = pTask->id.idStr; + int64_t nextProcessedVer = pStreamTask->hTaskInfo.haltVer; + + // if it's an source task, extract the last version in wal. + SVersionRange *pRange = &pTask->dataRange.range; + + bool done = streamHistoryTaskSetVerRangeStep2(pTask, nextProcessedVer); + pTask->execInfo.step2Start = taosGetTimestampMs(); + + if (done) { + qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); + streamTaskPutTranstateIntoInputQ(pTask); + streamExecTask(pTask); // exec directly + } else { + STimeWindow* pWindow = &pTask->dataRange.window; + tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 + ", do secondary scan-history from WAL after halt the related stream task:%s", + id, pTask->info.taskLevel, pRange->minVer, pRange->maxVer, pWindow->skey, pWindow->ekey, + pStreamTask->id.idStr); + ASSERT(pTask->status.schedStatus == TASK_SCHED_STATUS__WAITING); + + streamSetParamForStreamScannerStep2(pTask, pRange, pWindow); + + int64_t dstVer = pTask->dataRange.range.minVer; + pTask->chkInfo.nextProcessVer = dstVer; + + walReaderSetSkipToVersion(pTask->exec.pWalReader, dstVer); + tqDebug("s-task:%s wal reader start scan WAL verRange:%" PRId64 "-%" PRId64 ", set sched-status:%d", id, dstVer, + pTask->dataRange.range.maxVer, TASK_SCHED_STATUS__INACTIVE); + + /*int8_t status = */streamTaskSetSchedStatusInactive(pTask); + + // now the fill-history task starts to scan data from wal files. + int32_t code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); + if (code == TSDB_CODE_SUCCESS) { + tqScanWalAsync(pTq, false); + } + } +} + // this function should be executed by only one thread int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { SStreamScanHistoryReq* pReq = (SStreamScanHistoryReq*)pMsg->pCont; @@ -1146,7 +1187,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { tqDebug("s-task:%s scan-history(step 1) ended, elapsed time:%.2fs", id, el); if (pTask->info.fillHistory) { - SVersionRange* pRange = NULL; SStreamTask* pStreamTask = NULL; // 1. get the related stream task @@ -1165,50 +1205,11 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { ASSERT(pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE); - streamTaskHandleEvent(pStreamTask->status.pSM, TASK_EVENT_HALT); - int64_t nextProcessedVer = pStreamTask->hTaskInfo.haltVer; - - // if it's an source task, extract the last version in wal. - pRange = &pTask->dataRange.range; - bool done = streamHistoryTaskSetVerRangeStep2(pTask, nextProcessedVer); - pTask->execInfo.step2Start = taosGetTimestampMs(); - - if (done) { - qDebug("s-task:%s scan-history from WAL stage(step 2) ended, elapsed time:%.2fs", id, 0.0); - streamTaskPutTranstateIntoInputQ(pTask); -// streamTaskRestoreStatus(pTask); - -// if (pTask->status.taskStatus == TASK_STATUS__PAUSE) { -// pTask->status.keepTaskStatus = TASK_STATUS__READY; -// qDebug("s-task:%s prev status is %s, update the kept status to be:%s when after step 2", id, -// streamGetTaskStatusStr(TASK_STATUS__PAUSE), streamGetTaskStatusStr(pTask->status.keepTaskStatus)); -// } - - streamExecTask(pTask); // exec directly + code = streamTaskHandleEvent(pStreamTask->status.pSM, TASK_EVENT_HALT); + if (code == TSDB_CODE_SUCCESS) { + doStartStep2(pTask, pStreamTask, pTq); } else { - STimeWindow* pWindow = &pTask->dataRange.window; - tqDebug("s-task:%s level:%d verRange:%" PRId64 " - %" PRId64 " window:%" PRId64 "-%" PRId64 - ", do secondary scan-history from WAL after halt the related stream task:%s", - id, pTask->info.taskLevel, pRange->minVer, pRange->maxVer, pWindow->skey, pWindow->ekey, - pStreamTask->id.idStr); - ASSERT(pTask->status.schedStatus == TASK_SCHED_STATUS__WAITING); - - streamSetParamForStreamScannerStep2(pTask, pRange, pWindow); - - int64_t dstVer = pTask->dataRange.range.minVer; - pTask->chkInfo.nextProcessVer = dstVer; - - walReaderSetSkipToVersion(pTask->exec.pWalReader, dstVer); - tqDebug("s-task:%s wal reader start scan WAL verRange:%" PRId64 "-%" PRId64 ", set sched-status:%d", id, dstVer, - pTask->dataRange.range.maxVer, TASK_SCHED_STATUS__INACTIVE); - - /*int8_t status = */streamTaskSetSchedStatusInactive(pTask); - - // now the fill-history task starts to scan data from wal files. - code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE); - if (code == TSDB_CODE_SUCCESS) { - tqScanWalAsync(pTq, false); - } + tqError("s-task:%s failed to halt s-task:%s, not launch step2", id, pStreamTask->id.idStr); } streamMetaReleaseTask(pMeta, pStreamTask); diff --git a/source/dnode/vnode/src/tq/tqStreamTask.c b/source/dnode/vnode/src/tq/tqStreamTask.c index e7993ac673..2d94f23009 100644 --- a/source/dnode/vnode/src/tq/tqStreamTask.c +++ b/source/dnode/vnode/src/tq/tqStreamTask.c @@ -59,6 +59,7 @@ int32_t tqScanWal(STQ* pTq) { } int32_t tqStartStreamTask(STQ* pTq) { + int32_t code = TSDB_CODE_SUCCESS; int32_t vgId = TD_VID(pTq->pVnode); SStreamMeta* pMeta = pTq->pStreamMeta; @@ -102,12 +103,16 @@ int32_t tqStartStreamTask(STQ* pTq) { } EStreamTaskEvent event = (HAS_RELATED_FILLHISTORY_TASK(pTask)) ? TASK_EVENT_INIT_STREAM_SCANHIST : TASK_EVENT_INIT; - streamTaskHandleEvent(pTask->status.pSM, event); + int32_t ret = streamTaskHandleEvent(pTask->status.pSM, event); + if (ret != TSDB_CODE_SUCCESS) { + code = ret; + } + streamMetaReleaseTask(pMeta, pTask); } taosArrayDestroy(pTaskList); - return 0; + return code; } int32_t tqLaunchStreamTaskAsync(STQ* pTq) { diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 6c91bbf2d8..508efe9856 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -82,13 +82,6 @@ int32_t streamTaskInitStatus(SStreamTask* pTask) { return 0; } -int32_t streamTaskSetReadyForWal(SStreamTask* pTask) { - if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) { - stDebug("s-task:%s ready for extract data from wal", pTask->id.idStr); - } - return TSDB_CODE_SUCCESS; -} - static int32_t streamTaskDoCheckpoint(SStreamTask* pTask) { stDebug("s-task:%s start to do checkpoint", pTask->id.idStr); return 0; @@ -108,9 +101,31 @@ int32_t streamTaskKeepCurrentVerInWal(SStreamTask* pTask) { } // todo check rsp code for handle Event:TASK_EVENT_SCANHIST_DONE -static bool isUnsupportedTransform(ETaskStatus state, const EStreamTaskEvent event) { - if (state == TASK_STATUS__STOP || state == TASK_STATUS__DROPPING || state == TASK_STATUS__UNINIT) { - if (event == TASK_EVENT_SCANHIST_DONE || event == TASK_EVENT_CHECKPOINT_DONE || event == TASK_EVENT_GEN_CHECKPOINT) { +static bool isInvalidStateTransfer(ETaskStatus state, const EStreamTaskEvent event) { + if (event == TASK_EVENT_INIT_STREAM_SCANHIST || event == TASK_EVENT_INIT || event == TASK_EVENT_INIT_SCANHIST) { + return (state != TASK_STATUS__UNINIT); + } + + if (event == TASK_EVENT_SCANHIST_DONE) { + return (state != TASK_STATUS__SCAN_HISTORY && state != TASK_STATUS__STREAM_SCAN_HISTORY); + } + + if (event == TASK_EVENT_GEN_CHECKPOINT) { + return (state != TASK_STATUS__READY); + } + + if (event == TASK_EVENT_CHECKPOINT_DONE) { + return (state != TASK_STATUS__CK); + } + + // todo refactor later + if (event == TASK_EVENT_RESUME) { + return true; + } + + if (event == TASK_EVENT_HALT) { + if (state == TASK_STATUS__DROPPING || state == TASK_STATUS__UNINIT || state == TASK_STATUS__STOP || + state == TASK_STATUS__SCAN_HISTORY) { return true; } } @@ -128,7 +143,7 @@ static STaskStateTrans* streamTaskFindTransform(ETaskStatus state, const EStream } } - if (isUnsupportedTransform(state, event)) { + if (isInvalidStateTransfer(state, event)) { return NULL; } else { ASSERT(0); @@ -219,7 +234,7 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt taosMsleep(100); } else { stDebug("s-task:%s is dropped or stopped already, not wait.", id); - return TSDB_CODE_INVALID_PARA; + return TSDB_CODE_STREAM_INVALID_STATETRANS; } } @@ -260,7 +275,7 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { if (pTrans == NULL) { stDebug("s-task:%s failed to handle event:%s", pTask->id.idStr, GET_EVT_NAME(event)); taosThreadMutexUnlock(&pTask->lock); - return TSDB_CODE_INVALID_PARA; // todo: set new error code// failed to handle the event. + return TSDB_CODE_STREAM_INVALID_STATETRANS; } if (pSM->pActiveTrans != NULL) { @@ -303,14 +318,14 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even taosThreadMutexUnlock(&pTask->lock); stDebug("s-task:%s unlockx", pTask->id.idStr); - return TSDB_CODE_INVALID_PARA; + return TSDB_CODE_STREAM_INVALID_STATETRANS; } if (pTrans->event != event) { stWarn("s-task:%s handle event:%s failed, current status:%s, active trans evt:%s", pTask->id.idStr, GET_EVT_NAME(event), pSM->current.name, GET_EVT_NAME(pTrans->event)); taosThreadMutexUnlock(&pTask->lock); - return TSDB_CODE_INVALID_PARA; + return TSDB_CODE_STREAM_INVALID_STATETRANS; } keepPrevInfo(pSM); @@ -469,6 +484,10 @@ void doInitStateTransferTable(void) { streamTaskKeepCurrentVerInWal, NULL, true); taosArrayPush(streamTaskSMTrans, &trans); + trans = createStateTransform(TASK_STATUS__HALT, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, + streamTaskKeepCurrentVerInWal, NULL, true); + taosArrayPush(streamTaskSMTrans, &trans); + SAttachedEventInfo info = {.status = TASK_STATUS__READY, .event = TASK_EVENT_HALT}; trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, streamTaskKeepCurrentVerInWal, &info, true); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 12a37a041a..8bebe7f34e 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -670,6 +670,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT, "Replay is disabled // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_EXEC_CANCELLED, "Stream task exec cancelled") +TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INVALID_STATETRANS, "Invalid task state transfer") + // TDLite TAOS_DEFINE_ERROR(TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS, "Invalid TDLite open flags") TAOS_DEFINE_ERROR(TSDB_CODE_TDLITE_IVLD_OPEN_DIR, "Invalid TDLite open directory") From c48c801e19b00f7fa36293823585ecc7a78957a1 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 10:22:03 +0800 Subject: [PATCH 28/43] fix(stream): return error code. --- source/libs/stream/src/streamTaskSm.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source/libs/stream/src/streamTaskSm.c b/source/libs/stream/src/streamTaskSm.c index 508efe9856..09656cbe97 100644 --- a/source/libs/stream/src/streamTaskSm.c +++ b/source/libs/stream/src/streamTaskSm.c @@ -218,7 +218,6 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt if (pTrans->attachEvent.event != 0) { attachEvent(pTask, &pTrans->attachEvent); taosThreadMutexUnlock(&pTask->lock); - stDebug("s-task:%s unlock1", pTask->id.idStr); while (1) { // wait for the task to be here @@ -242,7 +241,6 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt pSM->pActiveTrans = pTrans; pSM->startTs = taosGetTimestampMs(); taosThreadMutexUnlock(&pTask->lock); - stDebug("s-task:%s unlock2", pTask->id.idStr); int32_t code = pTrans->pAction(pTask); // todo handle error code; @@ -256,12 +254,12 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt } int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { + int32_t code = TSDB_CODE_SUCCESS; SStreamTask* pTask = pSM->pTask; STaskStateTrans* pTrans = NULL; while (1) { taosThreadMutexLock(&pTask->lock); - stDebug("s-task:%s lock", pTask->id.idStr); if (pSM->pActiveTrans != NULL && pSM->pActiveTrans->autoInvokeEndFn) { EStreamTaskEvent evt = pSM->pActiveTrans->event; @@ -285,12 +283,12 @@ int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event) { pSM->pActiveTrans->next.name, GET_EVT_NAME(event)); } - doHandleEvent(pSM, event, pTrans); + code = doHandleEvent(pSM, event, pTrans); break; } } - return TSDB_CODE_SUCCESS; + return code; } static void keepPrevInfo(SStreamTaskSM* pSM) { From 1cd12845202a6d3d1272f88c70aa3726a6234423 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Thu, 2 Nov 2023 12:43:06 +0800 Subject: [PATCH 29/43] config/pcache: default page cache to 4096 --- source/common/src/tglobal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 3c16554ac6..8e824b4d67 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -282,7 +282,7 @@ char tsS3Hostname[TSDB_FQDN_LEN] = ""; int32_t tsS3BlockSize = -1; // number of tsdb pages (4096) int32_t tsS3BlockCacheSize = 16; // number of blocks -int32_t tsS3PageCacheSize = 1024; // number of pages +int32_t tsS3PageCacheSize = 4096; // number of pages int32_t tsS3UploadDelaySec = 60 * 60; #ifndef _STORAGE From be6a6976dbbbcf1c6bffd01896d231cd2bcff73b Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Thu, 2 Nov 2023 14:34:19 +0800 Subject: [PATCH 30/43] fix: adjust view not exist log level --- source/libs/catalog/src/ctgAsync.c | 9 +++++++-- source/libs/catalog/src/ctgRemote.c | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 00567f0acb..8d34505093 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -1906,8 +1906,13 @@ _return: SMetaRes* pRes = taosArrayGet(ctx->pResList, pFetch->resIdx); pRes->code = code; pRes->pRes = NULL; - ctgTaskError("Get view %d.%s.%s meta failed with error %s", pName->acctId, pName->dbname, pName->tname, - tstrerror(code)); + if (TSDB_CODE_MND_VIEW_NOT_EXIST == code) { + ctgTaskDebug("Get view %d.%s.%s meta failed with %s", pName->acctId, pName->dbname, pName->tname, + tstrerror(code)); + } else { + ctgTaskError("Get view %d.%s.%s meta failed with error %s", pName->acctId, pName->dbname, pName->tname, + tstrerror(code)); + } if (0 == atomic_sub_fetch_32(&ctx->fetchNum, 1)) { TSWAP(pTask->res, ctx->pResList); taskDone = true; diff --git a/source/libs/catalog/src/ctgRemote.c b/source/libs/catalog/src/ctgRemote.c index 3a12d822f4..f374c7fe6e 100644 --- a/source/libs/catalog/src/ctgRemote.c +++ b/source/libs/catalog/src/ctgRemote.c @@ -320,7 +320,11 @@ int32_t ctgProcessRspMsg(void* out, int32_t reqType, char* msg, int32_t msgSize, } case TDMT_MND_VIEW_META: { if (TSDB_CODE_SUCCESS != rspCode) { - qError("error rsp for get view-meta, error:%s, viewFName:%s", tstrerror(rspCode), target); + if (TSDB_CODE_MND_VIEW_NOT_EXIST == rspCode) { + qDebug("no success rsp for get view-meta, error:%s, viewFName:%s", tstrerror(rspCode), target); + } else { + qError("error rsp for get view-meta, error:%s, viewFName:%s", tstrerror(rspCode), target); + } CTG_ERR_RET(rspCode); } From 0a227e807fa186e1c9359946c5adb6dc512e9c6b Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 17:12:20 +0800 Subject: [PATCH 31/43] refactor: set different tq level. --- source/dnode/vnode/src/tq/tq.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index e8662c74df..94c0967602 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1824,17 +1824,17 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { if (pMeta->updateInfo.transId != req.transId) { pMeta->updateInfo.transId = req.transId; - tqDebug("s-task:%s receive new trans to update nodeEp msg from mnode, transId:%d", pTask->id.idStr, req.transId); + tqInfo("s-task:%s receive new trans to update nodeEp msg from mnode, transId:%d", pTask->id.idStr, req.transId); // info needs to be kept till the new trans to update the nodeEp arrived. taosHashClear(pMeta->updateInfo.pTasks); } else { - tqDebug("s-task:%s recv trans to update nodeEp from mnode, transId:%d", pTask->id.idStr, req.transId); + tqInfo("s-task:%s recv trans to update nodeEp from mnode, transId:%d", pTask->id.idStr, req.transId); } STaskUpdateEntry entry = {.streamId = req.streamId, .taskId = req.taskId, .transId = req.transId}; void* exist = taosHashGet(pMeta->updateInfo.pTasks, &entry, sizeof(STaskUpdateEntry)); if (exist != NULL) { - tqDebug("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId, + tqInfo("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId, req.transId); rsp.code = TSDB_CODE_SUCCESS; streamMetaWUnLock(pMeta); @@ -1859,7 +1859,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { pMeta->vgId, req.taskId); CLEAR_RELATED_FILLHISTORY_TASK(pTask); } else { - tqDebug("s-task:%s fill-history task update nodeEp along with stream task", (*ppHTask)->id.idStr); + tqInfo("s-task:%s fill-history task update nodeEp along with stream task", (*ppHTask)->id.idStr); streamTaskUpdateEpsetInfo(*ppHTask, req.pNodeList); } } @@ -1882,10 +1882,10 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { if (ppHTask != NULL) { streamTaskStop(*ppHTask); - tqDebug("s-task:%s task nodeEp update completed, streamTask and related fill-history task closed", pTask->id.idStr); + tqInfo("s-task:%s task nodeEp update completed, streamTask and related fill-history task closed", pTask->id.idStr); taosHashPut(pMeta->updateInfo.pTasks, &(*ppHTask)->id, sizeof(pTask->id), NULL, 0); } else { - tqDebug("s-task:%s task nodeEp update completed, streamTask closed", pTask->id.idStr); + tqInfo("s-task:%s task nodeEp update completed, streamTask closed", pTask->id.idStr); } rsp.code = 0; @@ -1897,22 +1897,22 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { pMeta->startInfo.startAllTasksFlag = 1; if (updateTasks < numOfTasks) { - tqDebug("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, + tqInfo("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, updateTasks, (numOfTasks - updateTasks)); streamMetaWUnLock(pMeta); } else { if (!pTq->pVnode->restored) { - tqDebug("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); + tqInfo("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); pMeta->startInfo.startAllTasksFlag = 0; streamMetaWUnLock(pMeta); } else { - tqDebug("vgId:%d tasks are all updated and stopped, restart them", vgId); + tqInfo("vgId:%d tasks are all updated and stopped, restart them", vgId); terrno = 0; streamMetaWUnLock(pMeta); while (streamMetaTaskInTimer(pMeta)) { - qDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); + tqInfo("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); taosMsleep(100); } From 706f1e47443aa912c9e89e319704aad4078f934d Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 18:07:36 +0800 Subject: [PATCH 32/43] fix(stream): fix deadlock in transfer state. --- source/libs/stream/src/streamExec.c | 11 ++++------- source/libs/stream/src/streamMeta.c | 8 ++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index fd2aa47ef2..7064e48641 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -329,6 +329,7 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { // start the task state transfer procedure. char* p = NULL; streamTaskGetStatus(pStreamTask, &p); + if (pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) { // update the scan data range for source task. stDebug("s-task:%s level:%d stream task window %" PRId64 " - %" PRId64 " update to %" PRId64 " - %" PRId64 @@ -347,9 +348,8 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { streamTaskReleaseState(pTask); streamTaskReloadState(pStreamTask); - // 3. resume the state of stream task, after this function, the stream task will run immidately. But it can not be - // pause, since the pause allowed attribute is not set yet. - streamTaskResume(pStreamTask); // todo refactor: use streamTaskResume. + // 3. resume the state of stream task, after this function, the stream task will run immediately. + streamTaskResume(pStreamTask); stDebug("s-task:%s fill-history task set status to be dropping, save the state into disk", pTask->id.idStr); @@ -357,12 +357,9 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); // 5. save to disk - streamMetaWLock(pMeta); pStreamTask->status.taskStatus = streamTaskGetStatus(pStreamTask, NULL); - streamMetaWUnLock(pMeta); - // 7. pause allowed. - streamTaskEnablePause(pStreamTask); + // 6. pause allowed. if ((pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) && taosQueueEmpty(pStreamTask->inputq.queue->pQueue)) { SStreamRefDataBlock* pItem = taosAllocateQitem(sizeof(SStreamRefDataBlock), DEF_QITEM, 0); diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index 887e879934..76945f17a9 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -260,13 +260,9 @@ int32_t streamMetaReopen(SStreamMeta* pMeta) { } } - pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId); - while (pMeta->streamBackend == NULL) { + while ((pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId)) == NULL) { + stInfo("vgId:%d failed to init stream backend, retry in 100ms", pMeta->vgId); taosMsleep(100); - pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId); - if (pMeta->streamBackend == NULL) { - stInfo("vgId:%d failed to init stream backend, retry in 100ms", pMeta->vgId); - } } pMeta->streamBackendRid = taosAddRef(streamBackendId, pMeta->streamBackend); From c4079332ff8739b4f7119447b4e59d87cca40e94 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 18:16:47 +0800 Subject: [PATCH 33/43] fix(stream):update the log level. --- source/dnode/vnode/src/tq/tq.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 94c0967602..85e82c8709 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1828,13 +1828,13 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { // info needs to be kept till the new trans to update the nodeEp arrived. taosHashClear(pMeta->updateInfo.pTasks); } else { - tqInfo("s-task:%s recv trans to update nodeEp from mnode, transId:%d", pTask->id.idStr, req.transId); + tqDebug("s-task:%s recv trans to update nodeEp from mnode, transId:%d", pTask->id.idStr, req.transId); } STaskUpdateEntry entry = {.streamId = req.streamId, .taskId = req.taskId, .transId = req.transId}; void* exist = taosHashGet(pMeta->updateInfo.pTasks, &entry, sizeof(STaskUpdateEntry)); if (exist != NULL) { - tqInfo("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId, + tqDebug("s-task:%s (vgId:%d) already update in trans:%d, discard the nodeEp update msg", pTask->id.idStr, vgId, req.transId); rsp.code = TSDB_CODE_SUCCESS; streamMetaWUnLock(pMeta); @@ -1859,7 +1859,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { pMeta->vgId, req.taskId); CLEAR_RELATED_FILLHISTORY_TASK(pTask); } else { - tqInfo("s-task:%s fill-history task update nodeEp along with stream task", (*ppHTask)->id.idStr); + tqDebug("s-task:%s fill-history task update nodeEp along with stream task", (*ppHTask)->id.idStr); streamTaskUpdateEpsetInfo(*ppHTask, req.pNodeList); } } @@ -1882,10 +1882,10 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { if (ppHTask != NULL) { streamTaskStop(*ppHTask); - tqInfo("s-task:%s task nodeEp update completed, streamTask and related fill-history task closed", pTask->id.idStr); + tqDebug("s-task:%s task nodeEp update completed, streamTask and related fill-history task closed", pTask->id.idStr); taosHashPut(pMeta->updateInfo.pTasks, &(*ppHTask)->id, sizeof(pTask->id), NULL, 0); } else { - tqInfo("s-task:%s task nodeEp update completed, streamTask closed", pTask->id.idStr); + tqDebug("s-task:%s task nodeEp update completed, streamTask closed", pTask->id.idStr); } rsp.code = 0; @@ -1897,12 +1897,12 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { pMeta->startInfo.startAllTasksFlag = 1; if (updateTasks < numOfTasks) { - tqInfo("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, + tqDebug("vgId:%d closed tasks:%d, unclosed:%d, all tasks will be started when nodeEp update completed", vgId, updateTasks, (numOfTasks - updateTasks)); streamMetaWUnLock(pMeta); } else { if (!pTq->pVnode->restored) { - tqInfo("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); + tqDebug("vgId:%d vnode restore not completed, not restart the tasks, clear the start after nodeUpdate flag", vgId); pMeta->startInfo.startAllTasksFlag = 0; streamMetaWUnLock(pMeta); } else { @@ -1912,7 +1912,7 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { streamMetaWUnLock(pMeta); while (streamMetaTaskInTimer(pMeta)) { - tqInfo("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); + tqDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId); taosMsleep(100); } @@ -1934,11 +1934,11 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) { } if (vnodeIsRoleLeader(pTq->pVnode) && !tsDisableStream) { - vInfo("vgId:%d restart all stream tasks after all tasks being updated", vgId); + tqInfo("vgId:%d restart all stream tasks after all tasks being updated", vgId); tqResetStreamTaskStatus(pTq); tqLaunchStreamTaskAsync(pTq); } else { - vInfo("vgId:%d, follower node not start stream tasks", vgId); + tqInfo("vgId:%d, follower node not start stream tasks", vgId); } streamMetaWUnLock(pMeta); From 7852b2cecf2199b3d2db1dbc5728c735971f957a Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 1 Nov 2023 15:11:01 +0800 Subject: [PATCH 34/43] fix: set ack of response properly in syncSnapSendRsp --- source/libs/sync/src/syncSnapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index 0b94d377f1..dd5449611b 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -861,7 +861,7 @@ static int32_t syncSnapSendRsp(SSyncSnapshotReceiver *pReceiver, SyncSnapshotSen pRspMsg->lastIndex = pMsg->lastIndex; pRspMsg->lastTerm = pMsg->lastTerm; pRspMsg->startTime = pMsg->startTime; - pRspMsg->ack = pReceiver->ack; // receiver maybe already closed + pRspMsg->ack = pMsg->seq; pRspMsg->code = code; pRspMsg->snapBeginIndex = pReceiver->snapshotParam.start; From 3221aef1a350c0ae40d277ba7a475ad584e8d0a0 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Wed, 1 Nov 2023 20:21:23 +0800 Subject: [PATCH 35/43] refact: improve code with syncSnapSendMsg --- source/libs/sync/src/syncSnapshot.c | 133 +++++++++++----------------- 1 file changed, 51 insertions(+), 82 deletions(-) diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index dd5449611b..dbd3ad54ed 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -23,6 +23,8 @@ #include "syncReplication.h" #include "syncUtil.h" +int32_t syncSnapSendMsg(SSyncSnapshotSender *pSender, int32_t seq, void *pBlock, int32_t len, int32_t typ); + static void syncSnapBufferReset(SSyncSnapBuffer *pBuf) { taosThreadMutexLock(&pBuf->mutex); for (int64_t i = pBuf->start; i < pBuf->end; ++i) { @@ -160,8 +162,11 @@ int32_t snapshotSenderStart(SSyncSnapshotSender *pSender) { } int dataLen = 0; - if (snapInfo.data) { - SSyncTLV *datHead = snapInfo.data; + void *pData = snapInfo.data; + int32_t type = 0; + if (pData) { + type = snapInfo.type; + SSyncTLV *datHead = pData; if (datHead->typ != TDMT_SYNC_PREP_SNAPSHOT) { sSError(pSender, "unexpected data typ in data of snapshot info. typ: %d", datHead->typ); terrno = TSDB_CODE_INVALID_DATA_FMT; @@ -170,37 +175,12 @@ int32_t snapshotSenderStart(SSyncSnapshotSender *pSender) { dataLen = sizeof(SSyncTLV) + datHead->len; } - SRpcMsg rpcMsg = {0}; - if (syncBuildSnapshotSend(&rpcMsg, dataLen, pSender->pSyncNode->vgId) != 0) { - sSError(pSender, "snapshot sender build msg failed since %s", terrstr()); + if (syncSnapSendMsg(pSender, pSender->seq, pData, dataLen, type) != 0) { goto _out; } - SyncSnapshotSend *pMsg = rpcMsg.pCont; - pMsg->srcId = pSender->pSyncNode->myRaftId; - pMsg->destId = pSender->pSyncNode->replicasId[pSender->replicaIndex]; - pMsg->term = pSender->term; - pMsg->beginIndex = pSender->snapshotParam.start; - pMsg->lastIndex = pSender->snapshot.lastApplyIndex; - pMsg->lastTerm = pSender->snapshot.lastApplyTerm; - pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex; - pMsg->lastConfig = pSender->lastConfig; - pMsg->startTime = pSender->startTime; - pMsg->seq = pSender->seq; - - if (dataLen > 0) { - pMsg->payloadType = snapInfo.type; - memcpy(pMsg->data, snapInfo.data, dataLen); - } - - // send msg - if (syncNodeSendMsgById(&pMsg->destId, pSender->pSyncNode, &rpcMsg) != 0) { - sSError(pSender, "snapshot sender send msg failed since %s", terrstr()); - goto _out; - } - - sSInfo(pSender, "snapshot sender start, to dnode:%d.", DID(&pMsg->destId)); - + SRaftId destId = pSender->pSyncNode->replicasId[pSender->replicaIndex]; + sSInfo(pSender, "snapshot sender start, to dnode:%d.", DID(&destId)); code = 0; _out: if (snapInfo.data) { @@ -232,6 +212,43 @@ void snapshotSenderStop(SSyncSnapshotSender *pSender, bool finish) { sSInfo(pSender, "snapshot sender stop, to dnode:%d, finish:%d", DID(&destId), finish); } +int32_t syncSnapSendMsg(SSyncSnapshotSender *pSender, int32_t seq, void *pBlock, int32_t blockLen, int32_t typ) { + int32_t code = -1; + SRpcMsg rpcMsg = {0}; + + if (syncBuildSnapshotSend(&rpcMsg, blockLen, pSender->pSyncNode->vgId) != 0) { + sSError(pSender, "failed to build snap replication msg since %s", terrstr()); + goto _OUT; + } + + SyncSnapshotSend *pMsg = rpcMsg.pCont; + pMsg->srcId = pSender->pSyncNode->myRaftId; + pMsg->destId = pSender->pSyncNode->replicasId[pSender->replicaIndex]; + pMsg->term = pSender->term; + pMsg->beginIndex = pSender->snapshotParam.start; + pMsg->lastIndex = pSender->snapshot.lastApplyIndex; + pMsg->lastTerm = pSender->snapshot.lastApplyTerm; + pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex; + pMsg->lastConfig = pSender->lastConfig; + pMsg->startTime = pSender->startTime; + pMsg->seq = seq; + + if (pBlock != NULL && blockLen > 0) { + memcpy(pMsg->data, pBlock, blockLen); + } + pMsg->payloadType = typ; + + // send msg + if (syncNodeSendMsgById(&pMsg->destId, pSender->pSyncNode, &rpcMsg) != 0) { + sSError(pSender, "failed to send snap replication msg since %s", terrstr()); + goto _OUT; + } + + code = 0; +_OUT: + return code; +} + // when sender receive ack, call this function to send msg from seq // seq = ack + 1, already updated static int32_t snapshotSend(SSyncSnapshotSender *pSender) { @@ -273,33 +290,10 @@ static int32_t snapshotSend(SSyncSnapshotSender *pSender) { ASSERT(pSender->seq >= SYNC_SNAPSHOT_SEQ_BEGIN && pSender->seq <= SYNC_SNAPSHOT_SEQ_END); - int32_t blockLen = (pBlk != NULL) ? pBlk->blockLen : 0; - // build msg - SRpcMsg rpcMsg = {0}; - if (syncBuildSnapshotSend(&rpcMsg, blockLen, pSender->pSyncNode->vgId) != 0) { - sSError(pSender, "vgId:%d, snapshot sender build msg failed since %s", pSender->pSyncNode->vgId, terrstr()); - goto _OUT; - } - - SyncSnapshotSend *pMsg = rpcMsg.pCont; - pMsg->srcId = pSender->pSyncNode->myRaftId; - pMsg->destId = pSender->pSyncNode->replicasId[pSender->replicaIndex]; - pMsg->term = raftStoreGetTerm(pSender->pSyncNode); - pMsg->beginIndex = pSender->snapshotParam.start; - pMsg->lastIndex = pSender->snapshot.lastApplyIndex; - pMsg->lastTerm = pSender->snapshot.lastApplyTerm; - pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex; - pMsg->lastConfig = pSender->lastConfig; - pMsg->startTime = pSender->startTime; - pMsg->seq = pSender->seq; - - if (pBlk != NULL && pBlk->pBlock != NULL && pBlk->blockLen > 0) { - memcpy(pMsg->data, pBlk->pBlock, pBlk->blockLen); - } - // send msg - if (syncNodeSendMsgById(&pMsg->destId, pSender->pSyncNode, &rpcMsg) != 0) { - sSError(pSender, "snapshot sender send msg failed since %s", terrstr()); + int32_t blockLen = (pBlk) ? pBlk->blockLen : 0; + void *pBlock = (pBlk) ? pBlk->pBlock : NULL; + if (syncSnapSendMsg(pSender, pSender->seq, pBlock, blockLen, 0) != 0) { goto _OUT; } @@ -336,32 +330,7 @@ int32_t snapshotReSend(SSyncSnapshotSender *pSender) { if (nowMs < pBlk->sendTimeMs + SYNC_SNAP_RESEND_MS) { continue; } - // build msg - SRpcMsg rpcMsg = {0}; - if (syncBuildSnapshotSend(&rpcMsg, pBlk->blockLen, pSender->pSyncNode->vgId) != 0) { - sSError(pSender, "snapshot sender build msg failed since %s", terrstr()); - goto _out; - } - - SyncSnapshotSend *pMsg = rpcMsg.pCont; - pMsg->srcId = pSender->pSyncNode->myRaftId; - pMsg->destId = pSender->pSyncNode->replicasId[pSender->replicaIndex]; - pMsg->term = pSender->term; - pMsg->beginIndex = pSender->snapshotParam.start; - pMsg->lastIndex = pSender->snapshot.lastApplyIndex; - pMsg->lastTerm = pSender->snapshot.lastApplyTerm; - pMsg->lastConfigIndex = pSender->snapshot.lastConfigIndex; - pMsg->lastConfig = pSender->lastConfig; - pMsg->startTime = pSender->startTime; - pMsg->seq = pBlk->seq; - - if (pBlk->pBlock != NULL && pBlk->blockLen > 0) { - memcpy(pMsg->data, pBlk->pBlock, pBlk->blockLen); - } - - // send msg - if (syncNodeSendMsgById(&pMsg->destId, pSender->pSyncNode, &rpcMsg) != 0) { - sSError(pSender, "snapshot sender resend msg failed since %s", terrstr()); + if (syncSnapSendMsg(pSender, pBlk->seq, pBlk->pBlock, pBlk->blockLen, 0) != 0) { goto _out; } pBlk->sendTimeMs = nowMs; From 995a1e1f8e26bf00cd5a612d5ec020e2bd6b241b Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 2 Nov 2023 18:36:01 +0800 Subject: [PATCH 36/43] enh: send rsp on duplicate msgs in syncSnapBufferRecv --- source/libs/sync/src/syncSnapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index dbd3ad54ed..709e2549ee 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -862,7 +862,7 @@ static int32_t syncSnapBufferRecv(SSyncSnapshotReceiver *pReceiver, SyncSnapshot pRcvBuf->entries[pMsg->seq % pRcvBuf->size] = pMsg; ppMsg[0] = NULL; pRcvBuf->end = TMAX(pMsg->seq + 1, pRcvBuf->end); - } else { + } else if (pMsg->seq < pRcvBuf->start) { syncSnapSendRsp(pReceiver, pMsg, code); goto _out; } From ce4fb52926fc30902dd731ad14ce52be512ca182 Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Thu, 2 Nov 2023 18:54:06 +0800 Subject: [PATCH 37/43] enh: resend end msg on timeout in snapshotReSend --- source/libs/sync/src/syncSnapshot.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index 709e2549ee..cbdcbef3a6 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -240,7 +240,7 @@ int32_t syncSnapSendMsg(SSyncSnapshotSender *pSender, int32_t seq, void *pBlock, // send msg if (syncNodeSendMsgById(&pMsg->destId, pSender->pSyncNode, &rpcMsg) != 0) { - sSError(pSender, "failed to send snap replication msg since %s", terrstr()); + sSError(pSender, "failed to send snap replication msg since %s. seq:%d", terrstr(), seq); goto _OUT; } @@ -335,6 +335,12 @@ int32_t snapshotReSend(SSyncSnapshotSender *pSender) { } pBlk->sendTimeMs = nowMs; } + + if (pSender->seq == SYNC_SNAPSHOT_SEQ_END && pSndBuf->end <= pSndBuf->start) { + if (syncSnapSendMsg(pSender, pSender->seq, NULL, 0, 0) != 0) { + goto _out; + } + } code = 0; _out:; taosThreadMutexUnlock(&pSndBuf->mutex); From 7a32b3a209cf9dc56b9e1a18b13c91029e29cbde Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 2 Nov 2023 19:12:36 +0800 Subject: [PATCH 38/43] fix(stream): not transfer state if state is not appropriate. --- include/util/taoserror.h | 1 + source/dnode/vnode/src/tq/tq.c | 4 ---- source/libs/stream/src/streamExec.c | 16 +++++++++++----- source/util/src/terror.c | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 55dba97862..8cfc7ff7d8 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -808,6 +808,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) #define TSDB_CODE_STREAM_EXEC_CANCELLED TAOS_DEF_ERROR_CODE(0, 0x4102) #define TSDB_CODE_STREAM_INVALID_STATETRANS TAOS_DEF_ERROR_CODE(0, 0x4103) +#define TSDB_CODE_STREAM_TASK_IVLD_STATUS TAOS_DEF_ERROR_CODE(0, 0x4104) // TDLite #define TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS TAOS_DEF_ERROR_CODE(0, 0x5100) diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 85e82c8709..fff58feeb1 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -1167,10 +1167,6 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) { return 0; } - if (pTask->info.fillHistory == 1) { - ASSERT(pTask->status.pauseAllowed == true); - } - streamScanHistoryData(pTask); double el = (taosGetTimestampMs() - pTask->execInfo.step1Start) / 1000.0; diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 7064e48641..49f691c558 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -285,13 +285,14 @@ static void waitForTaskIdle(SStreamTask* pTask, SStreamTask* pStreamTask) { int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { SStreamMeta* pMeta = pTask->pMeta; + const char* id = pTask->id.idStr; SStreamTask* pStreamTask = streamMetaAcquireTask(pMeta, pTask->streamTaskId.streamId, pTask->streamTaskId.taskId); if (pStreamTask == NULL) { stError( "s-task:%s failed to find related stream task:0x%x, it may have been destroyed or closed, destroy the related " "fill-history task", - pTask->id.idStr, (int32_t) pTask->streamTaskId.taskId); + id, (int32_t) pTask->streamTaskId.taskId); // 1. free it and remove fill-history task from disk meta-store streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); @@ -304,7 +305,7 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { streamMetaWUnLock(pMeta); return TSDB_CODE_STREAM_TASK_NOT_EXIST; } else { - stDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", pTask->id.idStr, + stDebug("s-task:%s fill-history task end, update related stream task:%s info, transfer exec state", id, pStreamTask->id.idStr); } @@ -318,7 +319,7 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { } else { ASSERT(status == TASK_STATUS__READY|| status == TASK_STATUS__DROPPING || status == TASK_STATUS__STOP); streamTaskHandleEvent(pStreamTask->status.pSM, TASK_EVENT_HALT); - stDebug("s-task:%s halt by related fill-history task:%s", pStreamTask->id.idStr, pTask->id.idStr); + stDebug("s-task:%s halt by related fill-history task:%s", pStreamTask->id.idStr, id); } // wait for the stream task to handle all in the inputQ, and to be idle @@ -328,7 +329,12 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { // In case of source tasks and agg tasks, we should HALT them, and wait for them to be idle. And then, it's safe to // start the task state transfer procedure. char* p = NULL; - streamTaskGetStatus(pStreamTask, &p); + status = streamTaskGetStatus(pStreamTask, &p); + if (status == TASK_STATUS__STOP || status == TASK_STATUS__DROPPING) { + stError("s-task:%s failed to transfer state from fill-history task:%s, status:%s", id, pStreamTask->id.idStr, p); + streamMetaReleaseTask(pMeta, pStreamTask); + return TSDB_CODE_STREAM_TASK_IVLD_STATUS; + } if (pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) { // update the scan data range for source task. @@ -351,7 +357,7 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) { // 3. resume the state of stream task, after this function, the stream task will run immediately. streamTaskResume(pStreamTask); - stDebug("s-task:%s fill-history task set status to be dropping, save the state into disk", pTask->id.idStr); + stDebug("s-task:%s fill-history task set status to be dropping, save the state into disk", id); // 4. free it and remove fill-history task from disk meta-store streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &pTask->id); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 8bebe7f34e..83824f643d 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -670,7 +670,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT, "Replay is disabled // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_EXEC_CANCELLED, "Stream task exec cancelled") -TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INVALID_STATETRANS, "Invalid task state transfer") +TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_INVALID_STATETRANS, "Invalid task state to handle event") +TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_IVLD_STATUS,"Invalid task status to proceed") // TDLite TAOS_DEFINE_ERROR(TSDB_CODE_TDLITE_IVLD_OPEN_FLAGS, "Invalid TDLite open flags") From 456c8d23f313e01e7414c27adafde9494c2e6d7c Mon Sep 17 00:00:00 2001 From: Benguang Zhao Date: Fri, 3 Nov 2023 10:09:07 +0800 Subject: [PATCH 39/43] fix: set cursor properly in syncSnapBufferRecv --- source/libs/sync/src/syncSnapshot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/sync/src/syncSnapshot.c b/source/libs/sync/src/syncSnapshot.c index cbdcbef3a6..8e186af51f 100644 --- a/source/libs/sync/src/syncSnapshot.c +++ b/source/libs/sync/src/syncSnapshot.c @@ -874,7 +874,7 @@ static int32_t syncSnapBufferRecv(SSyncSnapshotReceiver *pReceiver, SyncSnapshot } for (int64_t seq = pRcvBuf->cursor + 1; seq < pRcvBuf->end; ++seq) { - if (pRcvBuf->entries[seq]) { + if (pRcvBuf->entries[seq % pRcvBuf->size]) { pRcvBuf->cursor = seq; } else { break; From 4698e9270fe2c92a1f516fb8aabfda488f2c954b Mon Sep 17 00:00:00 2001 From: wangjiaming Date: Fri, 3 Nov 2023 10:26:13 +0800 Subject: [PATCH 40/43] Update 10-function.md --- docs/en/12-taos-sql/10-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index 5be14093de..d1b4aedf50 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -540,7 +540,7 @@ TO_CHAR(ts, format_str_literal) - If we want to output some characters of format without converting, surround it with double quotes. `to_char(ts, 'yyyy-mm-dd "is formated by yyyy-mm-dd"')`. If want to output double quotes, add a back slash before double quote, like `to_char(ts, '\"yyyy-mm-dd\"')` will output `"2023-10-10"`. - For formats that output digits, the uppercase and lowercase formats are the same. - It's recommended to put time zone in the format, if not, the default time zone will be that in server or client. -- The precision of the input timestamp will be recognized automatically according to the precision of the table used. +- The precision of the input timestamp will be recognized automatically according to the precision of the table used, milli seconds will be used if no table is specified. #### TO_TIMESTAMP From 603bfe1a48df6dd2539d9d2c4a4b66afed5dd7f5 Mon Sep 17 00:00:00 2001 From: wangjiaming Date: Fri, 3 Nov 2023 10:27:12 +0800 Subject: [PATCH 41/43] Update 10-function.md --- docs/zh/12-taos-sql/10-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/12-taos-sql/10-function.md b/docs/zh/12-taos-sql/10-function.md index 723f299cbc..c1dc6a6363 100644 --- a/docs/zh/12-taos-sql/10-function.md +++ b/docs/zh/12-taos-sql/10-function.md @@ -540,7 +540,7 @@ TO_CHAR(ts, format_str_literal) - 时间格式中无法匹配规则的内容会直接输出. 如果想要在格式串中指定某些能够匹配规则的部分不做转换, 可以使用双引号, 如`to_char(ts, 'yyyy-mm-dd "is formated by yyyy-mm-dd"')`. 如果想要输出双引号, 那么在双引号之前加一个反斜杠, 如 `to_char(ts, '\"yyyy-mm-dd\"')` 将会输出 `"2023-10-10"`. - 那些输出是数字的格式, 如`YYYY`, `DD`, 大写与小写意义相同, 即`yyyy` 和 `YYYY` 可以互换. - 推荐在时间格式中带时区信息,如果不带则默认输出的时区为服务端或客户端所配置的时区. -- 输入时间戳的精度由所查询表的精度确定. +- 输入时间戳的精度由所查询表的精度确定, 若未指定表, 则精度为毫秒. #### TO_TIMESTAMP From 153bd80a4e744ecba5fabae58abb5297ebf4b1d4 Mon Sep 17 00:00:00 2001 From: dapan1121 <72057773+dapan1121@users.noreply.github.com> Date: Fri, 3 Nov 2023 10:27:18 +0800 Subject: [PATCH 42/43] Update 10-function.md --- docs/en/12-taos-sql/10-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/12-taos-sql/10-function.md b/docs/en/12-taos-sql/10-function.md index d1b4aedf50..2ea144c56a 100644 --- a/docs/en/12-taos-sql/10-function.md +++ b/docs/en/12-taos-sql/10-function.md @@ -540,7 +540,7 @@ TO_CHAR(ts, format_str_literal) - If we want to output some characters of format without converting, surround it with double quotes. `to_char(ts, 'yyyy-mm-dd "is formated by yyyy-mm-dd"')`. If want to output double quotes, add a back slash before double quote, like `to_char(ts, '\"yyyy-mm-dd\"')` will output `"2023-10-10"`. - For formats that output digits, the uppercase and lowercase formats are the same. - It's recommended to put time zone in the format, if not, the default time zone will be that in server or client. -- The precision of the input timestamp will be recognized automatically according to the precision of the table used, milli seconds will be used if no table is specified. +- The precision of the input timestamp will be recognized automatically according to the precision of the table used, milliseconds will be used if no table is specified. #### TO_TIMESTAMP From bb48b457caeea7916d61a57c89e4c2be1aff3a8d Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Fri, 3 Nov 2023 11:28:16 +0800 Subject: [PATCH 43/43] fix: return error response while fetching in quick response mode --- source/libs/qworker/src/qworker.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/source/libs/qworker/src/qworker.c b/source/libs/qworker/src/qworker.c index afce4a496a..7376aa3a9c 100644 --- a/source/libs/qworker/src/qworker.c +++ b/source/libs/qworker/src/qworker.c @@ -434,27 +434,31 @@ int32_t qwQuickRspFetchReq(QW_FPARAMS_DEF, SQWTaskCtx * ctx, SQWMsg *qwMsg, i void *rsp = NULL; int32_t dataLen = 0; SOutputData sOutput = {0}; - if (qwGetQueryResFromSink(QW_FPARAMS(), ctx, &dataLen, &rsp, &sOutput)) { + if (TSDB_CODE_SUCCESS == code) { + code = qwGetQueryResFromSink(QW_FPARAMS(), ctx, &dataLen, &rsp, &sOutput); + } + + if (NULL == rsp && TSDB_CODE_SUCCESS == code) { return TSDB_CODE_SUCCESS; } - if (rsp) { + if (NULL != rsp) { bool qComplete = (DS_BUF_EMPTY == sOutput.bufStatus && sOutput.queryEnd); qwBuildFetchRsp(rsp, &sOutput, dataLen, qComplete); if (qComplete) { atomic_store_8((int8_t *)&ctx->queryEnd, true); } - - qwMsg->connInfo = ctx->dataConnInfo; - QW_SET_EVENT_PROCESSED(ctx, QW_EVENT_FETCH); - - qwBuildAndSendFetchRsp(ctx->fetchMsgType + 1, &qwMsg->connInfo, rsp, dataLen, code); - rsp = NULL; - - QW_TASK_DLOG("fetch rsp send, handle:%p, code:%x - %s, dataLen:%d", qwMsg->connInfo.handle, code, tstrerror(code), - dataLen); } + + qwMsg->connInfo = ctx->dataConnInfo; + QW_SET_EVENT_PROCESSED(ctx, QW_EVENT_FETCH); + + qwBuildAndSendFetchRsp(ctx->fetchMsgType + 1, &qwMsg->connInfo, rsp, dataLen, code); + rsp = NULL; + + QW_TASK_DLOG("fetch rsp send, handle:%p, code:%x - %s, dataLen:%d", qwMsg->connInfo.handle, code, tstrerror(code), + dataLen); } }