TDengine/source/dnode/vnode/src/sma/smaTimeRange.c

391 lines
12 KiB
C
Raw Normal View History

2022-06-13 03:29:53 +00:00
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sma.h"
2023-01-03 05:35:49 +00:00
#include "tq.h"
2022-06-13 03:29:53 +00:00
#include "tsdb.h"
#define SMA_STORAGE_MINUTES_MAX 86400
#define SMA_STORAGE_MINUTES_DAY 1440
#define SMA_STORAGE_SPLIT_FACTOR 14400 // least records in tsma file
static int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t version, const char *pMsg);
static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg);
static int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days);
2022-07-09 07:44:37 +00:00
int32_t tdProcessTSmaInsert(SSma *pSma, int64_t indexUid, const char *msg) {
int32_t code = TSDB_CODE_SUCCESS;
if ((code = tdProcessTSmaInsertImpl(pSma, indexUid, msg)) < 0) {
2023-07-05 08:45:12 +00:00
smaError("vgId:%d, insert tsma data failed since %s", SMA_VID(pSma), tstrerror(code));
2022-07-09 07:44:37 +00:00
}
2023-01-12 13:13:15 +00:00
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2022-07-09 07:44:37 +00:00
}
int32_t tdProcessTSmaCreate(SSma *pSma, int64_t ver, const char *msg) {
int32_t code = tdProcessTSmaCreateImpl(pSma, ver, msg);
2022-07-09 07:44:37 +00:00
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2022-07-09 07:44:37 +00:00
}
int32_t smaGetTSmaDays(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days) {
2023-03-29 04:16:12 +00:00
int32_t code = tdProcessTSmaGetDaysImpl(pCfg, pCont, contLen, days);
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2022-07-09 07:44:37 +00:00
}
2022-06-13 03:29:53 +00:00
/**
* @brief Judge the tsma file split days
*
* @param pCfg
* @param pCont
* @param contLen
* @param days unit is minute
* @return int32_t
*/
static int32_t tdProcessTSmaGetDaysImpl(SVnodeCfg *pCfg, void *pCont, uint32_t contLen, int32_t *days) {
2023-03-29 04:16:12 +00:00
int32_t code = 0;
int32_t lino = 0;
2022-06-13 03:29:53 +00:00
SDecoder coder = {0};
tDecoderInit(&coder, pCont, contLen);
STSma tsma = {0};
if (tDecodeSVCreateTSmaReq(&coder, &tsma) < 0) {
2023-03-29 04:16:12 +00:00
code = TSDB_CODE_MSG_DECODE_ERROR;
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
}
2023-03-29 04:16:12 +00:00
2022-06-13 03:29:53 +00:00
STsdbCfg *pTsdbCfg = &pCfg->tsdbCfg;
2024-07-19 02:59:21 +00:00
int64_t sInterval = -1;
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(convertTimeFromPrecisionToUnit(tsma.interval, pTsdbCfg->precision, TIME_UNIT_SECOND, &sInterval));
if (0 == sInterval) {
2022-06-13 03:29:53 +00:00
*days = pTsdbCfg->days;
2023-03-29 04:16:12 +00:00
goto _exit;
2022-06-13 03:29:53 +00:00
}
int64_t records = pTsdbCfg->days * 60 / sInterval;
if (records >= SMA_STORAGE_SPLIT_FACTOR) {
*days = pTsdbCfg->days;
} else {
2024-07-19 02:59:21 +00:00
int64_t mInterval = -1;
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(convertTimeFromPrecisionToUnit(tsma.interval, pTsdbCfg->precision, TIME_UNIT_MINUTE, &mInterval));
2022-06-13 03:29:53 +00:00
int64_t daysPerFile = mInterval * SMA_STORAGE_MINUTES_DAY * 2;
if (daysPerFile > SMA_STORAGE_MINUTES_MAX) {
*days = SMA_STORAGE_MINUTES_MAX;
} else {
*days = (int32_t)daysPerFile;
}
if (*days < pTsdbCfg->days) {
*days = pTsdbCfg->days;
}
}
2023-03-29 04:16:12 +00:00
_exit:
if (code) {
smaWarn("vgId:%d, failed at line %d to get tsma days %d since %s", pCfg->vgId, lino, *days, tstrerror(code));
} else {
smaDebug("vgId:%d, succeed to get tsma days %d", pCfg->vgId, *days);
}
2022-06-13 03:29:53 +00:00
tDecoderClear(&coder);
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2022-06-13 03:29:53 +00:00
}
/**
* @brief create tsma meta and result stable
*
* @param pSma
* @param version
* @param pMsg
* @return int32_t
*/
static int32_t tdProcessTSmaCreateImpl(SSma *pSma, int64_t ver, const char *pMsg) {
2022-12-25 13:54:09 +00:00
int32_t code = 0;
int32_t lino = 0;
SSmaCfg *pCfg = (SSmaCfg *)pMsg;
2022-12-25 18:37:31 +00:00
SName stbFullName = {0};
2022-12-25 13:54:09 +00:00
SVCreateStbReq pReq = {0};
2022-06-13 03:29:53 +00:00
if (TD_VID(pSma->pVnode) == pCfg->dstVgId) {
// create tsma meta in dstVgId
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(metaCreateTSma(SMA_META(pSma), ver, pCfg));
2022-06-13 03:29:53 +00:00
// create stable to save tsma result in dstVgId
2022-08-06 10:06:02 +00:00
tNameFromString(&stbFullName, pCfg->dstTbName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
pReq.name = (char *)tNameGetTableName(&stbFullName);
2022-06-13 03:29:53 +00:00
pReq.suid = pCfg->dstTbUid;
pReq.schemaRow = pCfg->schemaRow;
pReq.schemaTag = pCfg->schemaTag;
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(metaCreateSTable(SMA_META(pSma), ver, &pReq));
2022-12-25 13:54:09 +00:00
} else {
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(TSDB_CODE_TSMA_INVALID_STAT);
2022-12-25 13:54:09 +00:00
}
2022-08-06 10:06:02 +00:00
2022-12-25 13:54:09 +00:00
_exit:
if (code) {
smaError("vgId:%d, failed at line %d to create sma index %s %" PRIi64 " on stb:%" PRIi64 ", dstSuid:%" PRIi64
2024-07-23 11:30:55 +00:00
" dstTb:%s dstVg:%d since %s",
2022-12-25 13:54:09 +00:00
SMA_VID(pSma), lino, pCfg->indexName, pCfg->indexUid, pCfg->tableUid, pCfg->dstTbUid, pReq.name,
2024-07-23 11:30:55 +00:00
pCfg->dstVgId, tstrerror(code));
2022-12-25 13:54:09 +00:00
} else {
2022-08-06 10:06:02 +00:00
smaDebug("vgId:%d, success to create sma index %s %" PRIi64 " on stb:%" PRIi64 ", dstSuid:%" PRIi64
" dstTb:%s dstVg:%d",
SMA_VID(pSma), pCfg->indexName, pCfg->indexUid, pCfg->tableUid, pCfg->dstTbUid, pReq.name, pCfg->dstVgId);
2022-06-13 03:29:53 +00:00
}
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2022-06-13 03:29:53 +00:00
}
2023-10-24 01:49:14 +00:00
int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *pTSchema, int64_t suid,
const char *stbFullName, SBatchDeleteReq *pDeleteReq, void **ppData, int32_t *pLen) {
2023-03-29 04:16:12 +00:00
int32_t code = 0;
int32_t lino = 0;
2023-01-03 03:24:11 +00:00
void *pBuf = NULL;
int32_t len = 0;
SSubmitReq2 *pReq = NULL;
SArray *tagArray = NULL;
2024-07-23 11:30:55 +00:00
SHashObj *pTableIndexMap = NULL;
2023-01-03 03:24:11 +00:00
int32_t numOfBlocks = taosArrayGetSize(pBlocks);
2023-01-03 03:24:11 +00:00
2023-03-29 04:16:12 +00:00
tagArray = taosArrayInit(1, sizeof(STagVal));
pReq = taosMemoryCalloc(1, sizeof(SSubmitReq2));
2023-01-03 03:24:11 +00:00
if (!tagArray || !pReq) {
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
}
pReq->aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData));
if (pReq->aSubmitTbData == NULL) {
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
2023-01-03 03:24:11 +00:00
}
2024-07-23 11:30:55 +00:00
pTableIndexMap = taosHashInit(numOfBlocks, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
if (pTableIndexMap == NULL) {
TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
}
2023-01-03 03:24:11 +00:00
// SSubmitTbData req
for (int32_t i = 0; i < numOfBlocks; ++i) {
2023-01-03 03:24:11 +00:00
SSDataBlock *pDataBlock = taosArrayGet(pBlocks, i);
if (pDataBlock->info.type == STREAM_DELETE_RESULT) {
pDeleteReq->suid = suid;
pDeleteReq->deleteReqs = taosArrayInit(0, sizeof(SSingleDeleteReq));
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(tqBuildDeleteReq(pVnode->pTq, stbFullName, pDataBlock, pDeleteReq, "", true));
2023-01-03 03:24:11 +00:00
continue;
}
2024-02-22 02:58:32 +00:00
SSubmitTbData tbData = {.suid = suid, .uid = 0, .sver = pTSchema->version, .flags = SUBMIT_REQ_AUTO_CREATE_TABLE};
2023-01-03 03:24:11 +00:00
int32_t cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1;
2024-07-22 01:13:39 +00:00
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(buildAutoCreateTableReq(stbFullName, suid, cid, pDataBlock, tagArray, true, &tbData.pCreateTbReq));
2023-01-03 03:24:11 +00:00
{
uint64_t groupId = pDataBlock->info.id.groupId;
2023-01-03 03:24:11 +00:00
int32_t *index = taosHashGet(pTableIndexMap, &groupId, sizeof(groupId));
if (index == NULL) { // no data yet, append it
code = tqSetDstTableDataPayload(suid, pTSchema, i, pDataBlock, &tbData, INT64_MIN, "");
if (code != TSDB_CODE_SUCCESS) {
continue;
}
2023-01-03 03:24:11 +00:00
taosArrayPush(pReq->aSubmitTbData, &tbData);
2023-01-03 03:24:11 +00:00
int32_t size = (int32_t)taosArrayGetSize(pReq->aSubmitTbData) - 1;
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(taosHashPut(pTableIndexMap, &groupId, sizeof(groupId), &size, sizeof(size)));
} else {
code = tqSetDstTableDataPayload(suid, pTSchema, i, pDataBlock, &tbData, INT64_MIN, "");
if (code != TSDB_CODE_SUCCESS) {
continue;
}
SSubmitTbData *pExisted = taosArrayGet(pReq->aSubmitTbData, *index);
code = doMergeExistedRows(pExisted, &tbData, "id");
if (code != TSDB_CODE_SUCCESS) {
continue;
2023-01-03 03:24:11 +00:00
}
}
}
}
// encode
2023-05-12 06:26:15 +00:00
tEncodeSize(tEncodeSubmitReq, pReq, len, code);
2023-03-29 04:16:12 +00:00
if (TSDB_CODE_SUCCESS == code) {
2023-01-03 03:24:11 +00:00
SEncoder encoder;
len += sizeof(SSubmitReq2Msg);
2023-03-29 04:16:12 +00:00
if (!(pBuf = rpcMallocCont(len))) {
2024-07-23 11:30:55 +00:00
code = TSDB_CODE_OUT_OF_MEMORY;
2023-03-29 04:16:12 +00:00
TSDB_CHECK_CODE(code, lino, _exit);
2023-01-03 03:24:11 +00:00
}
2023-03-29 04:16:12 +00:00
((SSubmitReq2Msg *)pBuf)->header.vgId = TD_VID(pVnode);
((SSubmitReq2Msg *)pBuf)->header.contLen = htonl(len);
((SSubmitReq2Msg *)pBuf)->version = htobe64(1);
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
2024-07-23 11:30:55 +00:00
if ((code = tEncodeSubmitReq(&encoder, pReq)) < 0) {
2023-03-29 04:16:12 +00:00
tEncoderClear(&encoder);
TSDB_CHECK_CODE(code, lino, _exit);
2023-01-03 03:24:11 +00:00
}
tEncoderClear(&encoder);
}
2023-03-29 04:16:12 +00:00
_exit:
2023-01-03 03:24:11 +00:00
taosArrayDestroy(tagArray);
2024-07-23 11:30:55 +00:00
taosHashCleanup(pTableIndexMap);
if (pReq != NULL) {
2023-05-04 08:15:14 +00:00
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
2023-01-12 18:12:04 +00:00
taosMemoryFree(pReq);
}
2023-01-03 03:24:11 +00:00
2023-03-29 04:16:12 +00:00
if (code) {
2023-01-03 03:24:11 +00:00
rpcFreeCont(pBuf);
taosArrayDestroy(pDeleteReq->deleteReqs);
2023-03-29 04:16:12 +00:00
smaWarn("vgId:%d, failed at line %d since %s", TD_VID(pVnode), lino, tstrerror(code));
} else {
if (ppData) *ppData = pBuf;
if (pLen) *pLen = len;
2023-01-03 03:24:11 +00:00
}
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2023-01-03 03:24:11 +00:00
}
2023-06-16 11:04:12 +00:00
static int32_t tsmaProcessDelReq(SSma *pSma, int64_t indexUid, SBatchDeleteReq *pDelReq) {
int32_t code = 0;
int32_t lino = 0;
if (taosArrayGetSize(pDelReq->deleteReqs) > 0) {
int32_t len = 0;
tEncodeSize(tEncodeSBatchDeleteReq, pDelReq, len, code);
TSDB_CHECK_CODE(code, lino, _exit);
void *pBuf = rpcMallocCont(len + sizeof(SMsgHead));
if (!pBuf) {
2024-07-23 11:30:55 +00:00
code = TSDB_CODE_OUT_OF_MEMORY;
2023-06-16 11:04:12 +00:00
TSDB_CHECK_CODE(code, lino, _exit);
}
SEncoder encoder;
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SMsgHead)), len);
tEncodeSBatchDeleteReq(&encoder, pDelReq);
tEncoderClear(&encoder);
((SMsgHead *)pBuf)->vgId = TD_VID(pSma->pVnode);
SRpcMsg delMsg = {.msgType = TDMT_VND_BATCH_DEL, .pCont = pBuf, .contLen = len + sizeof(SMsgHead)};
code = tmsgPutToQueue(&pSma->pVnode->msgCb, WRITE_QUEUE, &delMsg);
TSDB_CHECK_CODE(code, lino, _exit);
}
_exit:
taosArrayDestroy(pDelReq->deleteReqs);
if (code) {
2023-06-16 21:05:43 +00:00
smaError("vgId:%d, failed at line %d to process delete req for smaIndex %" PRIi64 " since %s", SMA_VID(pSma), lino,
indexUid, tstrerror(code));
2023-06-16 11:04:12 +00:00
}
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
2023-06-16 11:04:12 +00:00
}
2022-06-13 03:29:53 +00:00
/**
* @brief Insert/Update Time-range-wise SMA data.
*
* @param pSma
* @param msg
* @return int32_t
*/
static int32_t tdProcessTSmaInsertImpl(SSma *pSma, int64_t indexUid, const char *msg) {
2023-03-15 04:30:44 +00:00
int32_t code = 0;
int32_t lino = 0;
2022-06-13 03:29:53 +00:00
const SArray *pDataBlocks = (const SArray *)msg;
if (taosArrayGetSize(pDataBlocks) <= 0) {
2023-03-15 04:30:44 +00:00
code = TSDB_CODE_TSMA_INVALID_PARA;
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
}
if (tdCheckAndInitSmaEnv(pSma, TSDB_SMA_TYPE_TIME_RANGE) != 0) {
2023-03-15 04:30:44 +00:00
code = TSDB_CODE_TSMA_INIT_FAILED;
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
}
2022-06-30 08:20:43 +00:00
SSmaEnv *pEnv = SMA_TSMA_ENV(pSma);
SSmaStat *pStat = NULL;
STSmaStat *pTsmaStat = NULL;
2022-06-13 03:29:53 +00:00
if (!pEnv || !(pStat = SMA_ENV_STAT(pEnv))) {
2023-03-15 04:30:44 +00:00
code = TSDB_CODE_TSMA_INVALID_ENV;
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
}
2022-08-14 16:16:44 +00:00
pTsmaStat = SMA_STAT_TSMA(pStat);
2022-06-13 03:29:53 +00:00
2022-06-30 08:20:43 +00:00
if (!pTsmaStat->pTSma) {
2022-06-13 03:29:53 +00:00
STSma *pTSma = metaGetSmaInfoByIndex(SMA_META(pSma), indexUid);
if (!pTSma) {
2024-07-23 11:30:55 +00:00
code = TSDB_CODE_TSMA_INVALID_PTR;
2023-03-15 04:30:44 +00:00
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-30 08:20:43 +00:00
}
pTsmaStat->pTSma = pTSma;
2022-10-10 03:00:55 +00:00
pTsmaStat->pTSchema = metaGetTbTSchema(SMA_META(pSma), pTSma->dstTbUid, -1, 1);
2022-06-30 08:20:43 +00:00
if (!pTsmaStat->pTSchema) {
2024-07-23 11:30:55 +00:00
code = TSDB_CODE_TSMA_INVALID_PTR;
2023-03-15 04:30:44 +00:00
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
}
}
2023-03-15 04:30:44 +00:00
if (ASSERTS(pTsmaStat->pTSma->indexUid == indexUid, "indexUid:%" PRIi64 " != %" PRIi64, pTsmaStat->pTSma->indexUid,
indexUid)) {
code = TSDB_CODE_APP_ERROR;
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-30 08:20:43 +00:00
}
2022-06-13 03:29:53 +00:00
SBatchDeleteReq deleteReq = {0};
2022-12-03 12:06:55 +00:00
void *pSubmitReq = NULL;
int32_t contLen = 0;
2022-06-13 03:29:53 +00:00
2023-10-24 01:49:14 +00:00
code = smaBlockToSubmit(pSma->pVnode, (const SArray *)msg, pTsmaStat->pTSchema, pTsmaStat->pTSma->dstTbUid,
pTsmaStat->pTSma->dstTbName, &deleteReq, &pSubmitReq, &contLen);
2023-03-15 04:30:44 +00:00
TSDB_CHECK_CODE(code, lino, _exit);
2024-07-23 11:30:55 +00:00
TAOS_CHECK_EXIT(tsmaProcessDelReq(pSma, indexUid, &deleteReq));
2023-06-16 11:04:12 +00:00
2022-06-30 08:20:43 +00:00
#if 0
2022-12-25 13:54:09 +00:00
if (!strncasecmp("td.tsma.rst.tb", pTsmaStat->pTSma->dstTbName, 14)) {
2024-07-23 11:30:55 +00:00
code = TSDB_CODE_APP_ERROR;
2022-12-25 13:54:09 +00:00
smaError("vgId:%d, tsma insert for smaIndex %" PRIi64 " failed since %s, %s", SMA_VID(pSma), indexUid,
2024-07-23 11:30:55 +00:00
pTsmaStat->pTSma->indexUid, tstrerror(code), pTsmaStat->pTSma->dstTbName);
2022-12-25 13:54:09 +00:00
goto _err;
}
2022-06-30 08:20:43 +00:00
#endif
2022-06-14 12:19:25 +00:00
SRpcMsg submitReqMsg = {
.msgType = TDMT_VND_SUBMIT,
.pCont = pSubmitReq,
.contLen = contLen,
2022-06-14 12:19:25 +00:00
};
2023-03-15 04:30:44 +00:00
code = tmsgPutToQueue(&pSma->pVnode->msgCb, WRITE_QUEUE, &submitReqMsg);
TSDB_CHECK_CODE(code, lino, _exit);
2022-06-13 03:29:53 +00:00
2023-03-15 04:30:44 +00:00
_exit:
if (code) {
2023-03-29 10:38:35 +00:00
smaError("vgId:%d, %s failed at line %d since %s, smaIndex:%" PRIi64, SMA_VID(pSma), __func__, lino,
tstrerror(code), indexUid);
2023-03-15 04:30:44 +00:00
}
2024-07-23 11:30:55 +00:00
TAOS_RETURN(code);
}