Merge remote-tracking branch 'origin/3.0' into feat/TD-27337
This commit is contained in:
commit
8d9c093b99
|
@ -1,6 +1,7 @@
|
|||
# curl
|
||||
ExternalProject_Add(curl2
|
||||
URL https://curl.se/download/curl-8.2.1.tar.gz
|
||||
URL https://github.com/curl/curl/releases/download/curl-8_2_1/curl-8.2.1.tar.gz
|
||||
#URL https://curl.se/download/curl-8.2.1.tar.gz
|
||||
URL_HASH MD5=b25588a43556068be05e1624e0e74d41
|
||||
DOWNLOAD_NO_PROGRESS 1
|
||||
DOWNLOAD_DIR "${TD_CONTRIB_DIR}/deps-download"
|
||||
|
|
|
@ -2545,12 +2545,6 @@ _err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// this message is sent from mnode to mnode(read thread to write thread),
|
||||
// so there is no need for serialization or deserialization
|
||||
typedef struct {
|
||||
SHashObj* rebSubHash; // SHashObj<key, SMqRebSubscribe>
|
||||
} SMqDoRebalanceMsg;
|
||||
|
||||
typedef struct {
|
||||
int64_t streamId;
|
||||
int64_t checkpointId;
|
||||
|
|
|
@ -30,7 +30,8 @@ int32_t tqStreamTaskProcessCheckpointReadyMsg(SStreamMeta* pMeta, SRpcMsg* pMsg)
|
|||
int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, int64_t sversion, char* msg, int32_t msgLen, bool isLeader, bool restored);
|
||||
int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen);
|
||||
int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLeader);
|
||||
int32_t startStreamTasks(SStreamMeta* pMeta);
|
||||
int32_t resetStreamTaskStatus(SStreamMeta* pMeta);
|
||||
int32_t tqStreamTaskResetStatus(SStreamMeta* pMeta);
|
||||
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta);
|
||||
int32_t tqStreamTaskProcessTaskResetReq(SStreamMeta* pMeta, SRpcMsg* pMsg);
|
||||
|
||||
#endif // TDENGINE_TQ_COMMON_H
|
||||
|
|
|
@ -53,6 +53,7 @@ extern "C" {
|
|||
#define STREAM_EXEC_EXTRACT_DATA_IN_WAL_ID (-1)
|
||||
#define STREAM_EXEC_START_ALL_TASKS_ID (-2)
|
||||
#define STREAM_EXEC_RESTART_ALL_TASKS_ID (-3)
|
||||
#define STREAM_EXEC_STOP_ALL_TASKS_ID (-4)
|
||||
|
||||
typedef struct SStreamTask SStreamTask;
|
||||
typedef struct SStreamQueue SStreamQueue;
|
||||
|
@ -80,7 +81,7 @@ typedef enum ETaskStatus {
|
|||
TASK_STATUS__HALT, // pause, but not be manipulated by user command
|
||||
TASK_STATUS__PAUSE, // pause
|
||||
TASK_STATUS__CK, // stream task is in checkpoint status, no data are allowed to put into inputQ anymore
|
||||
TASK_STATUS__STREAM_SCAN_HISTORY,
|
||||
// TASK_STATUS__STREAM_SCAN_HISTORY,
|
||||
} ETaskStatus;
|
||||
|
||||
enum {
|
||||
|
@ -137,15 +138,14 @@ enum {
|
|||
typedef enum EStreamTaskEvent {
|
||||
TASK_EVENT_INIT = 0x1,
|
||||
TASK_EVENT_INIT_SCANHIST = 0x2,
|
||||
TASK_EVENT_INIT_STREAM_SCANHIST = 0x3,
|
||||
TASK_EVENT_SCANHIST_DONE = 0x4,
|
||||
TASK_EVENT_STOP = 0x5,
|
||||
TASK_EVENT_GEN_CHECKPOINT = 0x6,
|
||||
TASK_EVENT_CHECKPOINT_DONE = 0x7,
|
||||
TASK_EVENT_PAUSE = 0x8,
|
||||
TASK_EVENT_RESUME = 0x9,
|
||||
TASK_EVENT_HALT = 0xA,
|
||||
TASK_EVENT_DROPPING = 0xB,
|
||||
TASK_EVENT_SCANHIST_DONE = 0x3,
|
||||
TASK_EVENT_STOP = 0x4,
|
||||
TASK_EVENT_GEN_CHECKPOINT = 0x5,
|
||||
TASK_EVENT_CHECKPOINT_DONE = 0x6,
|
||||
TASK_EVENT_PAUSE = 0x7,
|
||||
TASK_EVENT_RESUME = 0x8,
|
||||
TASK_EVENT_HALT = 0x9,
|
||||
TASK_EVENT_DROPPING = 0xA,
|
||||
} EStreamTaskEvent;
|
||||
|
||||
typedef struct {
|
||||
|
@ -314,6 +314,7 @@ typedef struct SCheckpointInfo {
|
|||
int32_t checkpointNotReadyTasks;
|
||||
bool dispatchCheckpointTrigger;
|
||||
int64_t msgVer;
|
||||
int32_t transId;
|
||||
} SCheckpointInfo;
|
||||
|
||||
typedef struct SStreamStatus {
|
||||
|
@ -324,6 +325,7 @@ typedef struct SStreamStatus {
|
|||
int8_t keepTaskStatus;
|
||||
bool appendTranstateBlock; // has append the transfer state data block already, todo: remove it
|
||||
int32_t timerActive; // timer is active
|
||||
int8_t allowedAddInTimer; // allowed to add into timer
|
||||
int32_t inScanHistorySentinel;
|
||||
} SStreamStatus;
|
||||
|
||||
|
@ -460,14 +462,18 @@ struct SStreamTask {
|
|||
char reserve[256];
|
||||
};
|
||||
|
||||
typedef int32_t (*startComplete_fn_t)(struct SStreamMeta*);
|
||||
|
||||
typedef struct STaskStartInfo {
|
||||
int64_t startTs;
|
||||
int64_t readyTs;
|
||||
int32_t tasksWillRestart;
|
||||
int32_t taskStarting; // restart flag, sentinel to guard the restart procedure.
|
||||
SHashObj* pReadyTaskSet; // tasks that are all ready for running stream processing
|
||||
SHashObj* pFailedTaskSet; // tasks that are done the check downstream process, may be successful or failed
|
||||
int32_t taskStarting; // restart flag, sentinel to guard the restart procedure.
|
||||
SHashObj* pReadyTaskSet; // tasks that are all ready for running stream processing
|
||||
SHashObj* pFailedTaskSet; // tasks that are done the check downstream process, may be successful or failed
|
||||
int64_t elapsedTime;
|
||||
int32_t restartCount; // restart task counter
|
||||
startComplete_fn_t completeFn; // complete callback function
|
||||
} STaskStartInfo;
|
||||
|
||||
typedef struct STaskUpdateInfo {
|
||||
|
@ -489,8 +495,9 @@ typedef struct SStreamMeta {
|
|||
int32_t vgId;
|
||||
int64_t stage;
|
||||
int32_t role;
|
||||
bool sendMsgBeforeClosing; // send hb to mnode before close all tasks when switch to follower.
|
||||
STaskStartInfo startInfo;
|
||||
SRWLatch lock;
|
||||
TdThreadRwlock lock;
|
||||
int32_t walScanCounter;
|
||||
void* streamBackend;
|
||||
int64_t streamBackendRid;
|
||||
|
@ -629,6 +636,7 @@ typedef struct {
|
|||
int32_t nodeId;
|
||||
SEpSet mgmtEps;
|
||||
int32_t mnodeId;
|
||||
int32_t transId;
|
||||
int64_t expireTime;
|
||||
} SStreamCheckpointSourceReq;
|
||||
|
||||
|
@ -671,8 +679,8 @@ typedef struct STaskStatusEntry {
|
|||
int64_t verStart; // start version in WAL, only valid for source task
|
||||
int64_t verEnd; // end version in WAL, only valid for source task
|
||||
int64_t processedVer; // only valid for source task
|
||||
int32_t relatedHTask; // has related fill-history task
|
||||
int64_t activeCheckpointId; // current active checkpoint id
|
||||
int32_t chkpointTransId; // checkpoint trans id
|
||||
bool checkpointFailed; // denote if the checkpoint is failed or not
|
||||
bool inputQChanging; // inputQ is changing or not
|
||||
int64_t inputQUnchangeCounter;
|
||||
|
@ -784,6 +792,7 @@ int8_t streamTaskSetSchedStatusInactive(SStreamTask* pTask);
|
|||
int32_t streamTaskClearHTaskAttr(SStreamTask* pTask);
|
||||
|
||||
int32_t streamTaskHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event);
|
||||
int32_t streamTaskHandleEventAsync(SStreamTaskSM* pSM, EStreamTaskEvent event, void* pFn);
|
||||
int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent event);
|
||||
void streamTaskRestoreStatus(SStreamTask* pTask);
|
||||
|
||||
|
@ -811,6 +820,7 @@ int32_t streamTaskReleaseState(SStreamTask* pTask);
|
|||
int32_t streamTaskReloadState(SStreamTask* pTask);
|
||||
void streamTaskCloseUpstreamInput(SStreamTask* pTask, int32_t taskId);
|
||||
void streamTaskOpenAllUpstreamInput(SStreamTask* pTask);
|
||||
int32_t streamTaskSetDb(SStreamMeta* pMeta, void* pTask, char* key);
|
||||
|
||||
void streamTaskStatusInit(STaskStatusEntry* pEntry, const SStreamTask* pTask);
|
||||
void streamTaskStatusCopy(STaskStatusEntry* pDst, const STaskStatusEntry* pSrc);
|
||||
|
@ -828,22 +838,21 @@ int32_t streamProcessScanHistoryFinishRsp(SStreamTask* pTask);
|
|||
// stream task meta
|
||||
void streamMetaInit();
|
||||
void streamMetaCleanup();
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage);
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage, startComplete_fn_t fn);
|
||||
void streamMetaClose(SStreamMeta* streamMeta);
|
||||
int32_t streamMetaSaveTask(SStreamMeta* pMeta, SStreamTask* pTask); // save to stream meta store
|
||||
int32_t streamMetaRemoveTask(SStreamMeta* pMeta, STaskId* pKey);
|
||||
int32_t streamMetaRegisterTask(SStreamMeta* pMeta, int64_t ver, SStreamTask* pTask, bool* pAdded);
|
||||
int32_t streamMetaUnregisterTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
int32_t streamMetaGetNumOfTasks(SStreamMeta* pMeta);
|
||||
SStreamTask* streamMetaAcquireTaskNoLock(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId);
|
||||
void streamMetaReleaseTask(SStreamMeta* pMeta, SStreamTask* pTask);
|
||||
void streamMetaClear(SStreamMeta* pMeta);
|
||||
void streamMetaInitBackend(SStreamMeta* pMeta);
|
||||
int32_t streamMetaCommit(SStreamMeta* pMeta);
|
||||
int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta);
|
||||
int64_t streamMetaGetLatestCheckpointId(SStreamMeta* pMeta);
|
||||
void streamMetaNotifyClose(SStreamMeta* pMeta);
|
||||
int32_t streamTaskSetDb(SStreamMeta* pMeta, void* pTask, char* key);
|
||||
void streamMetaStartHb(SStreamMeta* pMeta);
|
||||
bool streamMetaTaskInTimer(SStreamMeta* pMeta);
|
||||
int32_t streamMetaUpdateTaskDownstreamStatus(SStreamMeta* pMeta, int64_t streamId, int32_t taskId, int64_t startTs,
|
||||
|
@ -853,6 +862,11 @@ void streamMetaRUnLock(SStreamMeta* pMeta);
|
|||
void streamMetaWLock(SStreamMeta* pMeta);
|
||||
void streamMetaWUnLock(SStreamMeta* pMeta);
|
||||
void streamMetaResetStartInfo(STaskStartInfo* pMeta);
|
||||
SArray* streamMetaSendMsgBeforeCloseTasks(SStreamMeta* pMeta);
|
||||
void streamMetaUpdateStageRole(SStreamMeta* pMeta, int64_t stage, bool isLeader);
|
||||
int32_t streamMetaLoadAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta);
|
||||
int32_t streamMetaStopAllTasks(SStreamMeta* pMeta);
|
||||
|
||||
// checkpoint
|
||||
int32_t streamProcessCheckpointSourceReq(SStreamTask* pTask, SStreamCheckpointSourceReq* pReq);
|
||||
|
|
|
@ -355,6 +355,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL TAOS_DEF_ERROR_CODE(0, 0x03D5)
|
||||
#define TSDB_CODE_MND_LAST_TRANS_NOT_FINISHED TAOS_DEF_ERROR_CODE(0, 0x03D6) //internal
|
||||
#define TSDB_CODE_MND_TRANS_SYNC_TIMEOUT TAOS_DEF_ERROR_CODE(0, 0x03D7)
|
||||
#define TSDB_CODE_MND_TRANS_CTX_SWITCH TAOS_DEF_ERROR_CODE(0, 0x03D8)
|
||||
#define TSDB_CODE_MND_TRANS_UNKNOW_ERROR TAOS_DEF_ERROR_CODE(0, 0x03DF)
|
||||
|
||||
// mnode-mq
|
||||
|
|
|
@ -1028,11 +1028,16 @@ static void tmqMgmtInit(void) {
|
|||
}
|
||||
}
|
||||
|
||||
#define SET_ERROR_MSG(MSG) if(errstr!=NULL)snprintf(errstr,errstrLen,MSG);
|
||||
tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
||||
if(conf == NULL) return NULL;
|
||||
if(conf == NULL) {
|
||||
SET_ERROR_MSG("configure is null")
|
||||
return NULL;
|
||||
}
|
||||
taosThreadOnce(&tmqInit, tmqMgmtInit);
|
||||
if (tmqInitRes != 0) {
|
||||
terrno = tmqInitRes;
|
||||
SET_ERROR_MSG("tmq timer init error")
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1040,6 +1045,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
if (pTmq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tscError("failed to create consumer, groupId:%s, code:%s", conf->groupId, terrstr());
|
||||
SET_ERROR_MSG("malloc tmq failed")
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1055,6 +1061,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
conf->groupId[0] == 0) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tscError("consumer:0x%" PRIx64 " setup failed since %s, groupId:%s", pTmq->consumerId, terrstr(), pTmq->groupId);
|
||||
SET_ERROR_MSG("malloc tmq element failed or group is empty")
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
|
@ -1086,6 +1093,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
if (tsem_init(&pTmq->rspSem, 0, 0) != 0) {
|
||||
tscError("consumer:0x %" PRIx64 " setup failed since %s, consumer group %s", pTmq->consumerId, terrstr(),
|
||||
pTmq->groupId);
|
||||
SET_ERROR_MSG("init t_sem failed")
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
|
@ -1094,11 +1102,13 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
if (pTmq->pTscObj == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " setup failed since %s, groupId:%s", pTmq->consumerId, terrstr(), pTmq->groupId);
|
||||
tsem_destroy(&pTmq->rspSem);
|
||||
SET_ERROR_MSG("init tscObj failed")
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
pTmq->refId = taosAddRef(tmqMgmt.rsetId, pTmq);
|
||||
if (pTmq->refId < 0) {
|
||||
SET_ERROR_MSG("add tscObj ref failed")
|
||||
goto _failed;
|
||||
}
|
||||
|
||||
|
|
|
@ -789,7 +789,7 @@ static int32_t taosAddServerCfg(SConfig *pCfg) {
|
|||
if (cfgAddInt32(pCfg, "s3PageCacheSize", tsS3PageCacheSize, 4, 1024 * 1024 * 1024, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 10, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER,
|
||||
if (cfgAddInt32(pCfg, "s3UploadDelaySec", tsS3UploadDelaySec, 60 * 1, 60 * 60 * 24 * 30, CFG_SCOPE_SERVER,
|
||||
CFG_DYN_ENT_SERVER) != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1432,6 +1432,13 @@ static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize,
|
|||
static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (strcasecmp(name, "resetlog") == 0) {
|
||||
// trigger, no item in cfg
|
||||
taosResetLog();
|
||||
cfgDumpCfg(tsCfg, 0, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
|
||||
uError("failed to config:%s, not support", name);
|
||||
|
@ -1445,12 +1452,6 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (strcasecmp(name, "resetlog") == 0) {
|
||||
taosResetLog();
|
||||
cfgDumpCfg(tsCfg, 0, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
{ // 'bool/int32_t/int64_t/float/double' variables with general modification function
|
||||
static OptionNameAndVar debugOptions[] = {
|
||||
{"dDebugFlag", &dDebugFlag}, {"vDebugFlag", &vDebugFlag}, {"mDebugFlag", &mDebugFlag},
|
||||
|
@ -1774,4 +1775,4 @@ void taosSetAllDebugFlag(int32_t flag, bool rewrite) {
|
|||
uInfo("all debug flag are set to %d", flag);
|
||||
}
|
||||
|
||||
int8_t taosGranted() { return atomic_load_8(&tsGrant); }
|
||||
int8_t taosGranted() { return atomic_load_8(&tsGrant); }
|
||||
|
|
|
@ -108,11 +108,11 @@ SArray *mmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_SNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_DROP_VNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_SYNC_CONFIG_CHANGE_RSP, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CONFIG_DNODE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_VNODE_TYPE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_DND_CHECK_VNODE_LEARNER_CATCHUP_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_SYNC_CONFIG_CHANGE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CONNECT, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_MND_CREATE_ACCT, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
|
|
|
@ -90,7 +90,7 @@ SArray *smGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_SCAN_HISTORY_FINISH, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_SCAN_HISTORY_FINISH_RSP, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_CHECKPOINT_READY, smPutNodeMsgToStreamQueue, 1) == NULL) goto _OVER;
|
||||
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TASK_RESET, smPutNodeMsgToMgmtQueue, 1) == NULL) goto _OVER;
|
||||
|
||||
code = 0;
|
||||
_OVER:
|
||||
|
|
|
@ -46,10 +46,7 @@ SSdbRow *mndConsumerActionDecode(SSdbRaw *pRaw);
|
|||
int32_t mndSetConsumerCommitLogs(SMnode *pMnode, STrans *pTrans, SMqConsumerObj *pConsumer);
|
||||
int32_t mndSetConsumerDropLogs(SMnode *pMnode, STrans *pTrans, SMqConsumerObj *pConsumer);
|
||||
|
||||
bool mndRebTryStart();
|
||||
void mndRebEnd();
|
||||
void mndRebCntInc();
|
||||
void mndRebCntDec();
|
||||
const char *mndConsumerStatusName(int status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -44,12 +44,11 @@ typedef struct SStreamTransMgmt {
|
|||
} SStreamTransMgmt;
|
||||
|
||||
typedef struct SStreamExecInfo {
|
||||
SArray * pNodeList;
|
||||
SArray *pNodeList;
|
||||
int64_t ts; // snapshot ts
|
||||
SStreamTransMgmt transMgmt;
|
||||
int64_t activeCheckpoint; // active check point id
|
||||
SHashObj * pTaskMap;
|
||||
SArray * pTaskList;
|
||||
SHashObj *pTaskMap;
|
||||
SArray *pTaskList;
|
||||
TdThreadMutex lock;
|
||||
} SStreamExecInfo;
|
||||
|
||||
|
|
|
@ -32,14 +32,13 @@ void mndReleaseSubscribe(SMnode *pMnode, SMqSubscribeObj *pSub);
|
|||
|
||||
int32_t mndMakeSubscribeKey(char *key, const char *cgroup, const char *topicName);
|
||||
|
||||
//static FORCE_INLINE int32_t mndMakePartitionKey(char *key, const char *cgroup, const char *topicName, int32_t vgId) {
|
||||
// return snprintf(key, TSDB_PARTITION_KEY_LEN, "%d:%s:%s", vgId, cgroup, topicName);
|
||||
//}
|
||||
|
||||
//int32_t mndDropSubByDB(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
||||
int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topic);
|
||||
int32_t mndSetDropSubCommitLogs(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub);
|
||||
|
||||
bool mndRebTryStart();
|
||||
void mndRebCntInc();
|
||||
void mndRebCntDec();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -97,7 +97,7 @@ SSdbRaw *mndTransEncode(STrans *pTrans);
|
|||
SSdbRow *mndTransDecode(SSdbRaw *pRaw);
|
||||
void mndTransDropData(STrans *pTrans);
|
||||
|
||||
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans);
|
||||
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -290,11 +290,11 @@ int32_t mndAddCompactDetailToTran(SMnode *pMnode, STrans *pTrans, SCompactObj* p
|
|||
|
||||
SSdbRaw *pVgRaw = mndCompactDetailActionEncode(&compactDetail);
|
||||
if (pVgRaw == NULL) return -1;
|
||||
if (mndTransAppendRedolog(pTrans, pVgRaw) != 0) {
|
||||
if (mndTransAppendCommitlog(pTrans, pVgRaw) != 0) {
|
||||
sdbFreeRaw(pVgRaw);
|
||||
return -1;
|
||||
}
|
||||
(void)sdbSetRawStatus(pVgRaw, SDB_STATUS_READY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,6 @@
|
|||
#define MND_CONSUMER_RESERVE_SIZE 64
|
||||
|
||||
#define MND_MAX_GROUP_PER_TOPIC 100
|
||||
#define MND_CONSUMER_LOST_HB_CNT 6
|
||||
#define MND_CONSUMER_LOST_CLEAR_THRESHOLD 43200
|
||||
|
||||
static int32_t mqRebInExecCnt = 0;
|
||||
|
||||
static const char *mndConsumerStatusName(int status);
|
||||
|
||||
static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
|
@ -45,7 +39,6 @@ static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter);
|
|||
static int32_t mndProcessSubscribeReq(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessAskEpReq(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessMqHbReq(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg);
|
||||
static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg);
|
||||
|
||||
|
@ -63,7 +56,7 @@ int32_t mndInitConsumer(SMnode *pMnode) {
|
|||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_SUBSCRIBE, mndProcessSubscribeReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_HB, mndProcessMqHbReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_ASK_EP, mndProcessAskEpReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_TIMER, mndProcessMqTimerMsg);
|
||||
// mndSetMsgHandle(pMnode, TDMT_MND_TMQ_TIMER, mndProcessMqTimerMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_CONSUMER_RECOVER, mndProcessConsumerRecoverMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, mndProcessConsumerClearMsg);
|
||||
|
||||
|
@ -95,36 +88,6 @@ void mndDropConsumerFromSdb(SMnode *pMnode, int64_t consumerId, SRpcHandleInfo*
|
|||
return;
|
||||
}
|
||||
|
||||
bool mndRebTryStart() {
|
||||
int32_t old = atomic_val_compare_exchange_32(&mqRebInExecCnt, 0, 1);
|
||||
mDebug("tq timer, rebalance counter old val:%d", old);
|
||||
return old == 0;
|
||||
}
|
||||
|
||||
void mndRebEnd() { mndRebCntDec(); }
|
||||
|
||||
void mndRebCntInc() {
|
||||
int32_t val = atomic_add_fetch_32(&mqRebInExecCnt, 1);
|
||||
mInfo("rebalance trans start, rebalance counter:%d", val);
|
||||
}
|
||||
|
||||
void mndRebCntDec() {
|
||||
while (1) {
|
||||
int32_t val = atomic_load_32(&mqRebInExecCnt);
|
||||
if (val <= 0) {
|
||||
mError("rebalance trans end, rebalance counter:%d should not be less equalled than 0, ignore counter desc", val);
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t newVal = val - 1;
|
||||
int32_t oldVal = atomic_val_compare_exchange_32(&mqRebInExecCnt, val, newVal);
|
||||
if (oldVal == val) {
|
||||
mDebug("rebalance trans end, rebalance counter:%d", newVal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t validateTopics(STrans *pTrans, const SArray *pTopicList, SMnode *pMnode, const char *pUser, bool enableReplay) {
|
||||
SMqTopicObj *pTopic = NULL;
|
||||
int32_t code = 0;
|
||||
|
@ -257,162 +220,6 @@ FAIL:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebInfo *pRebInfo = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebInfo == NULL) {
|
||||
pRebInfo = tNewSMqRebSubscribe(key);
|
||||
if (pRebInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebInfo, sizeof(SMqRebInfo));
|
||||
taosMemoryFree(pRebInfo);
|
||||
pRebInfo = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
}
|
||||
return pRebInfo;
|
||||
}
|
||||
|
||||
static void freeRebalanceItem(void *param) {
|
||||
SMqRebInfo *pInfo = param;
|
||||
taosArrayDestroy(pInfo->newConsumers);
|
||||
taosArrayDestroy(pInfo->removedConsumers);
|
||||
}
|
||||
|
||||
static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SMqConsumerObj *pConsumer;
|
||||
void *pIter = NULL;
|
||||
|
||||
mDebug("start to process mq timer");
|
||||
|
||||
// rebalance cannot be parallel
|
||||
if (!mndRebTryStart()) {
|
||||
mInfo("mq rebalance already in progress, do nothing");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SMqDoRebalanceMsg *pRebMsg = rpcMallocCont(sizeof(SMqDoRebalanceMsg));
|
||||
if (pRebMsg == NULL) {
|
||||
mError("failed to create the rebalance msg, size:%d, quit mq timer", (int32_t)sizeof(SMqDoRebalanceMsg));
|
||||
mndRebEnd();
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pRebMsg->rebSubHash = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
|
||||
if (pRebMsg->rebSubHash == NULL) {
|
||||
mError("failed to create rebalance hashmap");
|
||||
rpcFreeCont(pRebMsg);
|
||||
mndRebEnd();
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
taosHashSetFreeFp(pRebMsg->rebSubHash, freeRebalanceItem);
|
||||
|
||||
// iterate all consumers, find all modification
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t hbStatus = atomic_add_fetch_32(&pConsumer->hbStatus, 1);
|
||||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
mInfo("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", createTime:%" PRId64 ", hbstatus:%d",
|
||||
pConsumer->consumerId, status, mndConsumerStatusName(status), pConsumer->subscribeTime, pConsumer->createTime,
|
||||
hbStatus);
|
||||
|
||||
if (status == MQ_CONSUMER_STATUS_READY) {
|
||||
if (taosArrayGetSize(pConsumer->assignedTopics) == 0) { // unsubscribe or close
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
} else if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
int32_t topicNum = taosArrayGetSize(pConsumer->currentTopics);
|
||||
for (int32_t i = 0; i < topicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
}else{
|
||||
int32_t newTopicNum = taosArrayGetSize(pConsumer->currentTopics);
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char * topic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||
SMqSubscribeObj *pSub = mndAcquireSubscribe(pMnode, pConsumer->cgroup, topic);
|
||||
if (pSub == NULL) {
|
||||
continue;
|
||||
}
|
||||
taosRLockLatch(&pSub->lock);
|
||||
|
||||
// 2.2 iterate all vg assigned to the consumer of that topic
|
||||
SMqConsumerEp *pConsumerEp = taosHashGet(pSub->consumerHash, &pConsumer->consumerId, sizeof(int64_t));
|
||||
int32_t vgNum = taosArrayGetSize(pConsumerEp->vgs);
|
||||
|
||||
for (int32_t j = 0; j < vgNum; j++) {
|
||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
|
||||
SVgObj * pVgroup = mndAcquireVgroup(pMnode, pVgEp->vgId);
|
||||
if (!pVgroup) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, topic);
|
||||
mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
mInfo("vnode splitted, vgId:%d rebalance will be triggered", pVgEp->vgId);
|
||||
}
|
||||
mndReleaseVgroup(pMnode, pVgroup);
|
||||
}
|
||||
taosRUnLockLatch(&pSub->lock);
|
||||
mndReleaseSubscribe(pMnode, pSub);
|
||||
}
|
||||
}
|
||||
} else if (status == MQ_CONSUMER_STATUS_LOST) {
|
||||
if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) { // clear consumer if lost a day
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
}
|
||||
} else { // MQ_CONSUMER_STATUS_REBALANCE
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
|
||||
int32_t newTopicNum = taosArrayGetSize(pConsumer->rebNewTopics);
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *newTopic = taosArrayGetP(pConsumer->rebNewTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, newTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->newConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
|
||||
int32_t removedTopicNum = taosArrayGetSize(pConsumer->rebRemovedTopics);
|
||||
for (int32_t i = 0; i < removedTopicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->rebRemovedTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(pRebMsg->rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
}
|
||||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
}
|
||||
|
||||
if (taosHashGetSize(pRebMsg->rebSubHash) != 0) {
|
||||
mInfo("mq rebalance will be triggered");
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = TDMT_MND_TMQ_DO_REBALANCE,
|
||||
.pCont = pRebMsg,
|
||||
.contLen = sizeof(SMqDoRebalanceMsg),
|
||||
};
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
||||
} else {
|
||||
taosHashCleanup(pRebMsg->rebSubHash);
|
||||
rpcFreeCont(pRebMsg);
|
||||
mDebug("mq timer finished, no need to re-balance");
|
||||
mndRebEnd();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessMqHbReq(SRpcMsg *pMsg) {
|
||||
int32_t code = 0;
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
|
@ -1251,7 +1058,7 @@ static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter) {
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
||||
|
||||
static const char *mndConsumerStatusName(int status) {
|
||||
const char *mndConsumerStatusName(int status) {
|
||||
switch (status) {
|
||||
case MQ_CONSUMER_STATUS_READY:
|
||||
return "ready";
|
||||
|
|
|
@ -251,7 +251,7 @@ int32_t doAddSinkTask(SStreamObj* pStream, SArray* pTaskList, SMnode* pMnode, in
|
|||
|
||||
static int32_t addSourceTask(SMnode* pMnode, SVgObj* pVgroup, SArray* pTaskList, SArray* pSinkTaskList,
|
||||
SStreamObj* pStream, SSubplan* plan, uint64_t uid, SEpSet* pEpset, bool fillHistory,
|
||||
bool hasExtraSink, int64_t firstWindowSkey, bool hasFillHistory) {
|
||||
bool hasExtraSink, int64_t nextWindowSkey, bool hasFillHistory) {
|
||||
SStreamTask* pTask =
|
||||
tNewStreamTask(uid, TASK_LEVEL__SOURCE, fillHistory, pStream->conf.triggerParam, pTaskList, hasFillHistory);
|
||||
if (pTask == NULL) {
|
||||
|
@ -262,7 +262,7 @@ static int32_t addSourceTask(SMnode* pMnode, SVgObj* pVgroup, SArray* pTaskList,
|
|||
STimeWindow* pWindow = &pTask->dataRange.window;
|
||||
|
||||
pWindow->skey = INT64_MIN;
|
||||
pWindow->ekey = firstWindowSkey - 1;
|
||||
pWindow->ekey = nextWindowSkey - 1;
|
||||
mDebug("add source task 0x%x window:%" PRId64 " - %" PRId64, pTask->id.taskId, pWindow->skey, pWindow->ekey);
|
||||
|
||||
// sink or dispatch
|
||||
|
@ -382,7 +382,7 @@ static int32_t doAddSourceTask(SArray* pTaskList, bool isFillhistory, int64_t ui
|
|||
|
||||
epsetAssign(&(pTask)->info.mnodeEpset, pEpset);
|
||||
|
||||
// todo set the correct ts, which should be last key of queried table.
|
||||
// set the correct ts, which is the last key of queried table.
|
||||
STimeWindow* pWindow = &pTask->dataRange.window;
|
||||
pWindow->skey = INT64_MIN;
|
||||
pWindow->ekey = nextWindowSkey - 1;
|
||||
|
|
|
@ -62,7 +62,7 @@ static void mndCancelGetNextStreamTask(SMnode *pMnode, void *pIter);
|
|||
static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq);
|
||||
static int32_t mndProcessResumeStreamReq(SRpcMsg *pReq);
|
||||
static int32_t mndBuildStreamCheckpointSourceReq2(void **pBuf, int32_t *pLen, int32_t nodeId, int64_t checkpointId,
|
||||
int64_t streamId, int32_t taskId);
|
||||
int64_t streamId, int32_t taskId, int32_t transId);
|
||||
static int32_t mndProcessNodeCheck(SRpcMsg *pReq);
|
||||
static int32_t mndProcessNodeCheckReq(SRpcMsg *pMsg);
|
||||
static SArray *extractNodeListFromStream(SMnode *pMnode);
|
||||
|
@ -685,6 +685,40 @@ _OVER:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t extractNodeEpset(SMnode *pMnode, SEpSet *pEpSet, bool* hasEpset, int32_t taskId, int32_t nodeId) {
|
||||
*hasEpset = false;
|
||||
|
||||
if (nodeId == SNODE_HANDLE) {
|
||||
SSnodeObj *pObj = NULL;
|
||||
void *pIter = NULL;
|
||||
|
||||
pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
|
||||
if (pIter != NULL) {
|
||||
addEpIntoEpSet(pEpSet, pObj->pDnode->fqdn, pObj->pDnode->port);
|
||||
sdbRelease(pMnode->pSdb, pObj);
|
||||
sdbCancelFetch(pMnode->pSdb, pIter);
|
||||
*hasEpset = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
mError("failed to acquire snode epset");
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
} else {
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, nodeId);
|
||||
if (pVgObj != NULL) {
|
||||
SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
|
||||
epsetAssign(pEpSet, &epset);
|
||||
*hasEpset = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
mDebug("orphaned task:0x%x need to be dropped, nodeId:%d, no redo action", taskId, nodeId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndPersistTaskDropReq(SMnode *pMnode, STrans *pTrans, SStreamTask *pTask) {
|
||||
SVDropStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVDropStreamTaskReq));
|
||||
if (pReq == NULL) {
|
||||
|
@ -698,28 +732,17 @@ static int32_t mndPersistTaskDropReq(SMnode *pMnode, STrans *pTrans, SStreamTask
|
|||
|
||||
STransAction action = {0};
|
||||
SEpSet epset = {0};
|
||||
if (pTask->info.nodeId == SNODE_HANDLE) {
|
||||
SSnodeObj *pObj = NULL;
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pMnode->pSdb, SDB_SNODE, pIter, (void **)&pObj);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
bool hasEpset = false;
|
||||
|
||||
addEpIntoEpSet(&epset, pObj->pDnode->fqdn, pObj->pDnode->port);
|
||||
sdbRelease(pMnode->pSdb, pObj);
|
||||
}
|
||||
} else {
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId);
|
||||
if (pVgObj != NULL) {
|
||||
epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
} else {
|
||||
mDebug("orphaned task:0x%x need to be dropped, nodeId:%d, no redo action", pTask->id.taskId, pTask->info.nodeId);
|
||||
taosMemoryFree(pReq);
|
||||
return 0;
|
||||
}
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// no valid epset, return directly without redoAction
|
||||
if (!hasEpset) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// The epset of nodeId of this task may have been expired now, let's use the newest epset from mnode.
|
||||
|
@ -769,7 +792,7 @@ static int32_t checkForNumOfStreams(SMnode *pMnode, SStreamObj *pStreamObj) { /
|
|||
if (pStream->targetStbUid == pStreamObj->targetStbUid) {
|
||||
mError("Cannot write the same stable as other stream:%s", pStream->name);
|
||||
sdbCancelFetch(pMnode->pSdb, pIter);
|
||||
terrno = TSDB_CODE_MND_TOO_MANY_STREAMS;
|
||||
terrno = TSDB_CODE_MND_INVALID_TARGET_TABLE;
|
||||
return terrno;
|
||||
}
|
||||
}
|
||||
|
@ -974,13 +997,14 @@ static int32_t mndProcessStreamRemainChkptTmr(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
static int32_t mndBuildStreamCheckpointSourceReq2(void **pBuf, int32_t *pLen, int32_t nodeId, int64_t checkpointId,
|
||||
int64_t streamId, int32_t taskId) {
|
||||
int64_t streamId, int32_t taskId, int32_t transId) {
|
||||
SStreamCheckpointSourceReq req = {0};
|
||||
req.checkpointId = checkpointId;
|
||||
req.nodeId = nodeId;
|
||||
req.expireTime = -1;
|
||||
req.streamId = streamId; // pTask->id.streamId;
|
||||
req.taskId = taskId; // pTask->id.taskId;
|
||||
req.transId = transId;
|
||||
|
||||
int32_t code;
|
||||
int32_t blen;
|
||||
|
@ -1070,7 +1094,7 @@ static int32_t mndProcessStreamCheckpointTrans(SMnode *pMnode, SStreamObj *pStre
|
|||
void * buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, checkpointId, pTask->id.streamId,
|
||||
pTask->id.taskId) < 0) {
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
taosWUnLockLatch(&pStream->lock);
|
||||
goto _ERR;
|
||||
|
@ -1139,7 +1163,7 @@ static int32_t mndAddStreamCheckpointToTrans(STrans *pTrans, SStreamObj *pStream
|
|||
void * buf;
|
||||
int32_t tlen;
|
||||
if (mndBuildStreamCheckpointSourceReq2(&buf, &tlen, pTask->info.nodeId, chkptId, pTask->id.streamId,
|
||||
pTask->id.taskId) < 0) {
|
||||
pTask->id.taskId, pTrans->id) < 0) {
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
taosWUnLockLatch(&pStream->lock);
|
||||
return -1;
|
||||
|
@ -1776,9 +1800,20 @@ static int32_t mndPauseStreamTask(SMnode *pMnode, STrans *pTrans, SStreamTask *p
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId);
|
||||
SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
taosMemoryFree(pReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// no valid epset, return directly without redoAction
|
||||
if (!hasEpset) {
|
||||
taosMemoryFree(pReq);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
STransAction action = {0};
|
||||
initTransAction(&action, pReq, sizeof(SVPauseStreamTaskReq), TDMT_STREAM_TASK_PAUSE, &epset, 0);
|
||||
|
@ -1920,17 +1955,25 @@ static int32_t mndProcessPauseStreamReq(SRpcMsg *pReq) {
|
|||
static int32_t mndResumeStreamTask(STrans *pTrans, SMnode *pMnode, SStreamTask *pTask, int8_t igUntreated) {
|
||||
SVResumeStreamTaskReq *pReq = taosMemoryCalloc(1, sizeof(SVResumeStreamTaskReq));
|
||||
if (pReq == NULL) {
|
||||
mError("failed to malloc in resume stream, size:%" PRIzu ", code:%s", sizeof(SVResumeStreamTaskReq),
|
||||
tstrerror(TSDB_CODE_OUT_OF_MEMORY));
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pReq->head.vgId = htonl(pTask->info.nodeId);
|
||||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
pReq->igUntreated = igUntreated;
|
||||
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId);
|
||||
SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
taosMemoryFree(pReq);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STransAction action = {0};
|
||||
initTransAction(&action, pReq, sizeof(SVResumeStreamTaskReq), TDMT_STREAM_TASK_RESUME, &epset, 0);
|
||||
|
@ -2208,6 +2251,8 @@ static SVgroupChangeInfo mndFindChangedNodeInfo(SMnode *pMnode, const SArray *pP
|
|||
epsetAssign(&updateInfo.newEp, &pCurrent->epset);
|
||||
taosArrayPush(info.pUpdateNodeList, &updateInfo);
|
||||
}
|
||||
|
||||
// todo handle the snode info
|
||||
if (pCurrent->nodeId != SNODE_HANDLE) {
|
||||
SVgObj *pVgroup = mndAcquireVgroup(pMnode, pCurrent->nodeId);
|
||||
taosHashPut(info.pDBMap, pVgroup->dbName, strlen(pVgroup->dbName), NULL, 0);
|
||||
|
@ -2286,12 +2331,28 @@ static SArray *mndTakeVgroupSnapshot(SMnode *pMnode, bool *allReady) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChangeInfo) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
||||
// check all streams that involved this vnode should update the epset info
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
STrans * pTrans = NULL;
|
||||
void *pIter = NULL;
|
||||
STrans *pTrans = NULL;
|
||||
|
||||
// conflict check for nodeUpdate trans, here we randomly chose one stream to add into the trans pool
|
||||
while(1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_TASK_UPDATE_NAME, false);
|
||||
sdbRelease(pSdb, pStream);
|
||||
|
||||
if (conflict) {
|
||||
mWarn("nodeUpdate trans in progress, current nodeUpdate ignored");
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
|
@ -2307,6 +2368,8 @@ static int32_t mndProcessVgroupChange(SMnode *pMnode, SVgroupChangeInfo *pChange
|
|||
sdbCancelFetch(pSdb, pIter);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
mndStreamRegisterTrans(pTrans, MND_STREAM_TASK_RESET_NAME, pStream->uid);
|
||||
}
|
||||
|
||||
void *p = taosHashGet(pChangeInfo->pDBMap, pStream->targetDb, strlen(pStream->targetDb));
|
||||
|
@ -2553,7 +2616,7 @@ static int32_t mndProcessNodeCheckReq(SRpcMsg *pMsg) {
|
|||
|
||||
code = mndProcessVgroupChange(pMnode, &changeInfo);
|
||||
|
||||
// keep the new vnode snapshot
|
||||
// keep the new vnode snapshot if success
|
||||
if (code == TSDB_CODE_SUCCESS || code == TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mDebug("create trans successfully, update cached node list");
|
||||
taosArrayDestroy(execInfo.pNodeList);
|
||||
|
@ -2704,9 +2767,18 @@ int32_t createStreamResetStatusTrans(SMnode *pMnode, SStreamObj *pStream) {
|
|||
pReq->taskId = pTask->id.taskId;
|
||||
pReq->streamId = pTask->id.streamId;
|
||||
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId);
|
||||
SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(pReq);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hasEpset) {
|
||||
taosMemoryFree(pReq);
|
||||
continue;
|
||||
}
|
||||
|
||||
STransAction action = {0};
|
||||
initTransAction(&action, pReq, sizeof(SVResetStreamTaskReq), TDMT_VND_STREAM_TASK_RESET, &epset, 0);
|
||||
|
@ -2766,39 +2838,36 @@ int32_t killActiveCheckpointTrans(SMnode *pMnode, const char *pDBName, size_t le
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mndResetStatusFromCheckpoint(SMnode *pMnode, int32_t transId) {
|
||||
static int32_t mndResetStatusFromCheckpoint(SMnode *pMnode, int64_t streamId, int32_t transId) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
STrans *pTrans = mndAcquireTrans(pMnode, transId);
|
||||
if (pTrans != NULL) {
|
||||
mInfo("kill checkpoint transId:%d to reset task status", transId);
|
||||
mndKillTrans(pMnode, pTrans);
|
||||
mndReleaseTrans(pMnode, pTrans);
|
||||
} else {
|
||||
mError("failed to acquire checkpoint trans:%d", transId);
|
||||
}
|
||||
|
||||
// set all tasks status to be normal, refactor later to be stream level, instead of vnode level.
|
||||
SSdb * pSdb = pMnode->pSdb;
|
||||
SStreamObj *pStream = NULL;
|
||||
void * pIter = NULL;
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pStream);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
SStreamObj *pStream = mndGetStreamObj(pMnode, streamId);
|
||||
if (pStream == NULL) {
|
||||
code = TSDB_CODE_STREAM_TASK_NOT_EXIST;
|
||||
mError("failed to acquire the streamObj:0x%" PRIx64 " to reset checkpoint, may have been dropped", pStream->uid);
|
||||
} else {
|
||||
bool conflict = streamTransConflictOtherTrans(pMnode, pStream->uid, MND_STREAM_TASK_RESET_NAME, false);
|
||||
if (conflict) {
|
||||
mError("stream:%s other trans exists in DB:%s & %s failed to start reset-status trans", pStream->name,
|
||||
pStream->sourceDb, pStream->targetDb);
|
||||
continue;
|
||||
}
|
||||
|
||||
mDebug("stream:%s (0x%" PRIx64 ") reset checkpoint procedure, create reset trans", pStream->name, pStream->uid);
|
||||
int32_t code = createStreamResetStatusTrans(pMnode, pStream);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
return code;
|
||||
mError("stream:%s other trans exists in DB:%s, dstTable:%s failed to start reset-status trans", pStream->name,
|
||||
pStream->sourceDb, pStream->targetSTbName);
|
||||
} else {
|
||||
mDebug("stream:%s (0x%" PRIx64 ") reset checkpoint procedure, transId:%d, create reset trans", pStream->name,
|
||||
pStream->uid, transId);
|
||||
code = createStreamResetStatusTrans(pMnode, pStream);
|
||||
mndReleaseStream(pMnode, pStream);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static SStreamTask *mndGetStreamTask(STaskId *pId, SStreamObj *pStream) {
|
||||
|
@ -2817,38 +2886,38 @@ static SStreamTask *mndGetStreamTask(STaskId *pId, SStreamObj *pStream) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
int32_t numOfReady = 0;
|
||||
int32_t numOfTotal = 0;
|
||||
for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
numOfTotal++;
|
||||
|
||||
if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
if (pEntry->status == TASK_STATUS__READY) {
|
||||
numOfReady++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numOfReady > 0) {
|
||||
mDebug("stream:0x%" PRIx64
|
||||
" %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history task",
|
||||
pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
//static bool needDropRelatedFillhistoryTask(STaskStatusEntry *pTaskEntry, SStreamExecInfo *pExecNode) {
|
||||
// if (pTaskEntry->status == TASK_STATUS__STREAM_SCAN_HISTORY && pTaskEntry->statusLastDuration >= 10) {
|
||||
// if (!pTaskEntry->inputQChanging && pTaskEntry->inputQUnchangeCounter > 10) {
|
||||
// int32_t numOfReady = 0;
|
||||
// int32_t numOfTotal = 0;
|
||||
// for (int32_t k = 0; k < taosArrayGetSize(pExecNode->pTaskList); ++k) {
|
||||
// STaskId *pId = taosArrayGet(pExecNode->pTaskList, k);
|
||||
// if (pTaskEntry->id.streamId == pId->streamId) {
|
||||
// numOfTotal++;
|
||||
//
|
||||
// if (pTaskEntry->id.taskId != pId->taskId) {
|
||||
// STaskStatusEntry *pEntry = taosHashGet(execInfo.pTaskMap, pId, sizeof(*pId));
|
||||
// if (pEntry->status == TASK_STATUS__READY) {
|
||||
// numOfReady++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (numOfReady > 0) {
|
||||
// mDebug("stream:0x%" PRIx64
|
||||
// " %d tasks are ready, %d tasks in stream-scan-history for more than 50s, drop related fill-history task",
|
||||
// pTaskEntry->id.streamId, numOfReady, numOfTotal - numOfReady);
|
||||
// return true;
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
|
||||
// currently only handle the sink task
|
||||
// 1. sink task, drop related fill-history task msg is missing
|
||||
|
@ -2878,11 +2947,17 @@ static int32_t mndDropRelatedFillhistoryTask(SMnode *pMnode, STaskStatusEntry *p
|
|||
|
||||
mDebug("build and send drop related fill-history task for task:0x%x", pTask->id.taskId);
|
||||
|
||||
SVgObj *pVgObj = mndAcquireVgroup(pMnode, pTask->info.nodeId);
|
||||
SEpSet epset = mndGetVgroupEpset(pMnode, pVgObj);
|
||||
mndReleaseVgroup(pMnode, pVgObj);
|
||||
SEpSet epset;
|
||||
bool hasEpset = false;
|
||||
int32_t code = extractNodeEpset(pMnode, &epset, &hasEpset, pTask->id.taskId, pTask->info.nodeId);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (hasEpset) {
|
||||
tmsgSendReq(&epset, &msg);
|
||||
}
|
||||
|
||||
tmsgSendReq(&epset, &msg);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2930,6 +3005,8 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
|
||||
bool checkpointFailed = false;
|
||||
int64_t activeCheckpointId = 0;
|
||||
int64_t streamId = 0;
|
||||
int32_t transId = 0;
|
||||
|
||||
SDecoder decoder = {0};
|
||||
tDecoderInit(&decoder, pReq->pCont, pReq->contLen);
|
||||
|
@ -2972,7 +3049,9 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
|
||||
if (pTaskEntry->stage != p->stage && pTaskEntry->stage != -1) {
|
||||
updateStageInfo(pTaskEntry, p->stage);
|
||||
if (pTaskEntry->nodeId == SNODE_HANDLE) snodeChanged = true;
|
||||
if (pTaskEntry->nodeId == SNODE_HANDLE) {
|
||||
snodeChanged = true;
|
||||
}
|
||||
} else {
|
||||
// task is idle for more than 50 sec.
|
||||
if (fabs(pTaskEntry->inputQUsed - p->inputQUsed) <= DBL_EPSILON) {
|
||||
|
@ -2996,6 +3075,8 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
|
||||
if (p->checkpointFailed) {
|
||||
checkpointFailed = p->checkpointFailed;
|
||||
streamId = p->id.streamId;
|
||||
transId = p->chkpointTransId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3010,18 +3091,18 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
if (p->status != TASK_STATUS__READY) {
|
||||
mDebug("received s-task:0x%" PRIx64 " not in ready status:%s", p->id.taskId, streamTaskGetStatusStr(p->status));
|
||||
|
||||
if (p->status == TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
bool drop = needDropRelatedFillhistoryTask(pTaskEntry, &execInfo);
|
||||
if (drop) {
|
||||
SStreamObj *pStreamObj = mndGetStreamObj(pMnode, pTaskEntry->id.streamId);
|
||||
if (pStreamObj == NULL) {
|
||||
mError("failed to acquire the streamObj:0x%" PRIx64 " it may have been dropped", pStreamObj->uid);
|
||||
} else {
|
||||
mndDropRelatedFillhistoryTask(pMnode, pTaskEntry, pStreamObj);
|
||||
mndReleaseStream(pMnode, pStreamObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (p->status == TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
// bool drop = needDropRelatedFillhistoryTask(pTaskEntry, &execInfo);
|
||||
// if (drop) {
|
||||
// SStreamObj *pStreamObj = mndGetStreamObj(pMnode, pTaskEntry->id.streamId);
|
||||
// if (pStreamObj == NULL) {
|
||||
// mError("failed to acquire the streamObj:0x%" PRIx64 " it may have been dropped", pStreamObj->uid);
|
||||
// } else {
|
||||
// mndDropRelatedFillhistoryTask(pMnode, pTaskEntry, pStreamObj);
|
||||
// mndReleaseStream(pMnode, pStreamObj);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3034,9 +3115,8 @@ int32_t mndProcessStreamHb(SRpcMsg *pReq) {
|
|||
|
||||
if (allReady || snodeChanged) {
|
||||
// if the execInfo.activeCheckpoint == 0, the checkpoint is restoring from wal
|
||||
mInfo("checkpointId:%" PRId64 " failed, issue task-reset trans to reset all tasks status",
|
||||
execInfo.activeCheckpoint);
|
||||
mndResetStatusFromCheckpoint(pMnode, activeCheckpointId);
|
||||
mInfo("checkpointId:%" PRId64 " failed, issue task-reset trans to reset all tasks status", activeCheckpointId);
|
||||
mndResetStatusFromCheckpoint(pMnode, streamId, transId);
|
||||
} else {
|
||||
mInfo("not all vgroups are ready, wait for next HB from stream tasks");
|
||||
}
|
||||
|
|
|
@ -90,16 +90,20 @@ bool streamTransConflictOtherTrans(SMnode* pMnode, int64_t streamUid, const char
|
|||
|
||||
if (strcmp(tInfo.name, MND_STREAM_CHECKPOINT_NAME) == 0) {
|
||||
if (strcmp(pTransName, MND_STREAM_DROP_NAME) != 0) {
|
||||
mWarn("conflict with other transId:%d streamUid:%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
mWarn("conflict with other transId:%d streamUid:0x%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
tInfo.name);
|
||||
return true;
|
||||
} else {
|
||||
mDebug("not conflict with checkpoint trans, name:%s, continue create trans", pTransName);
|
||||
}
|
||||
} else if ((strcmp(tInfo.name, MND_STREAM_CREATE_NAME) == 0) ||
|
||||
(strcmp(tInfo.name, MND_STREAM_DROP_NAME) == 0)) {
|
||||
mWarn("conflict with other transId:%d streamUid:%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
} else if ((strcmp(tInfo.name, MND_STREAM_CREATE_NAME) == 0) || (strcmp(tInfo.name, MND_STREAM_DROP_NAME) == 0) ||
|
||||
(strcmp(tInfo.name, MND_STREAM_TASK_RESET_NAME) == 0)) {
|
||||
mWarn("conflict with other transId:%d streamUid:0x%" PRIx64 ", trans:%s", tInfo.transId, tInfo.streamUid,
|
||||
tInfo.name);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
mDebug("stream:0x%"PRIx64" no conflict trans existed, continue create trans", streamUid);
|
||||
}
|
||||
|
||||
if (lock) {
|
||||
|
|
|
@ -27,7 +27,10 @@
|
|||
#define MND_SUBSCRIBE_VER_NUMBER 2
|
||||
#define MND_SUBSCRIBE_RESERVE_SIZE 64
|
||||
|
||||
#define MND_SUBSCRIBE_REBALANCE_CNT 3
|
||||
#define MND_CONSUMER_LOST_HB_CNT 6
|
||||
#define MND_CONSUMER_LOST_CLEAR_THRESHOLD 43200
|
||||
|
||||
static int32_t mqRebInExecCnt = 0;
|
||||
|
||||
static SSdbRaw *mndSubActionEncode(SMqSubscribeObj *);
|
||||
static SSdbRow *mndSubActionDecode(SSdbRaw *pRaw);
|
||||
|
@ -38,14 +41,7 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg);
|
|||
static int32_t mndProcessDropCgroupReq(SRpcMsg *pMsg);
|
||||
static int32_t mndRetrieveSubscribe(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows);
|
||||
static void mndCancelGetNextSubscribe(SMnode *pMnode, void *pIter);
|
||||
|
||||
static int32_t mndSetSubRedoLogs(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub) {
|
||||
SSdbRaw *pRedoRaw = mndSubActionEncode(pSub);
|
||||
if (pRedoRaw == NULL) return -1;
|
||||
if (mndTransAppendRedolog(pTrans, pRedoRaw) != 0) return -1;
|
||||
if (sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY) != 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
static int32_t mndCheckConsumer(SRpcMsg *pMsg, SHashObj* hash);
|
||||
|
||||
static int32_t mndSetSubCommitLogs(SMnode *pMnode, STrans *pTrans, SMqSubscribeObj *pSub) {
|
||||
SSdbRaw *pCommitRaw = mndSubActionEncode(pSub);
|
||||
|
@ -68,7 +64,7 @@ int32_t mndInitSubscribe(SMnode *pMnode) {
|
|||
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_TMQ_SUBSCRIBE_RSP, mndTransProcessRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_TMQ_DELETE_SUB_RSP, mndTransProcessRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_DO_REBALANCE, mndProcessRebalanceReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_TIMER, mndProcessRebalanceReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_DROP_CGROUP, mndProcessDropCgroupReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_TMQ_DROP_CGROUP_RSP, mndTransProcessRsp);
|
||||
|
||||
|
@ -213,16 +209,18 @@ static int32_t mndSplitSubscribeKey(const char *key, char *topic, char *cgroup,
|
|||
}
|
||||
|
||||
static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebInfo *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebSub == NULL) {
|
||||
pRebSub = tNewSMqRebSubscribe(key);
|
||||
if (pRebSub == NULL) {
|
||||
SMqRebInfo *pRebInfo = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebInfo == NULL) {
|
||||
pRebInfo = tNewSMqRebSubscribe(key);
|
||||
if (pRebInfo == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebSub, sizeof(SMqRebInfo));
|
||||
taosHashPut(pHash, key, strlen(key) + 1, pRebInfo, sizeof(SMqRebInfo));
|
||||
taosMemoryFree(pRebInfo);
|
||||
pRebInfo = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
}
|
||||
return pRebSub;
|
||||
return pRebInfo;
|
||||
}
|
||||
|
||||
static void doRemoveLostConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, const SMqRebInputObj *pInput) {
|
||||
|
@ -727,17 +725,156 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
SMqDoRebalanceMsg *pReq = pMsg->pCont;
|
||||
void *pIter = NULL;
|
||||
// bool rebalanceOnce = false; // to ensure only once.
|
||||
static void freeRebalanceItem(void *param) {
|
||||
SMqRebInfo *pInfo = param;
|
||||
taosArrayDestroy(pInfo->newConsumers);
|
||||
taosArrayDestroy(pInfo->removedConsumers);
|
||||
}
|
||||
|
||||
mInfo("mq re-balance start, total required re-balanced trans:%d", taosHashGetSize(pReq->rebSubHash));
|
||||
static int32_t mndCheckConsumer(SRpcMsg *pMsg, SHashObj* rebSubHash) {
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SMqConsumerObj *pConsumer;
|
||||
void *pIter = NULL;
|
||||
|
||||
mInfo("start to process mq timer");
|
||||
|
||||
// iterate all consumers, find all modification
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_CONSUMER, pIter, (void **)&pConsumer);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t hbStatus = atomic_add_fetch_32(&pConsumer->hbStatus, 1);
|
||||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
mInfo("check for consumer:0x%" PRIx64 " status:%d(%s), sub-time:%" PRId64 ", createTime:%" PRId64 ", hbstatus:%d",
|
||||
pConsumer->consumerId, status, mndConsumerStatusName(status), pConsumer->subscribeTime, pConsumer->createTime,
|
||||
hbStatus);
|
||||
|
||||
if (status == MQ_CONSUMER_STATUS_READY) {
|
||||
if (taosArrayGetSize(pConsumer->assignedTopics) == 0) { // unsubscribe or close
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
} else if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
int32_t topicNum = taosArrayGetSize(pConsumer->currentTopics);
|
||||
for (int32_t i = 0; i < topicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
}else{
|
||||
int32_t newTopicNum = taosArrayGetSize(pConsumer->currentTopics);
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char * topic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||
SMqSubscribeObj *pSub = mndAcquireSubscribe(pMnode, pConsumer->cgroup, topic);
|
||||
if (pSub == NULL) {
|
||||
continue;
|
||||
}
|
||||
taosRLockLatch(&pSub->lock);
|
||||
|
||||
// 2.2 iterate all vg assigned to the consumer of that topic
|
||||
SMqConsumerEp *pConsumerEp = taosHashGet(pSub->consumerHash, &pConsumer->consumerId, sizeof(int64_t));
|
||||
int32_t vgNum = taosArrayGetSize(pConsumerEp->vgs);
|
||||
|
||||
for (int32_t j = 0; j < vgNum; j++) {
|
||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
|
||||
SVgObj * pVgroup = mndAcquireVgroup(pMnode, pVgEp->vgId);
|
||||
if (!pVgroup) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, topic);
|
||||
mndGetOrCreateRebSub(rebSubHash, key);
|
||||
mInfo("vnode splitted, vgId:%d rebalance will be triggered", pVgEp->vgId);
|
||||
}
|
||||
mndReleaseVgroup(pMnode, pVgroup);
|
||||
}
|
||||
taosRUnLockLatch(&pSub->lock);
|
||||
mndReleaseSubscribe(pMnode, pSub);
|
||||
}
|
||||
}
|
||||
} else if (status == MQ_CONSUMER_STATUS_LOST) {
|
||||
if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) { // clear consumer if lost a day
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
}
|
||||
} else {
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
|
||||
int32_t newTopicNum = taosArrayGetSize(pConsumer->rebNewTopics);
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *newTopic = taosArrayGetP(pConsumer->rebNewTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, newTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(rebSubHash, key);
|
||||
taosArrayPush(pRebSub->newConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
|
||||
int32_t removedTopicNum = taosArrayGetSize(pConsumer->rebRemovedTopics);
|
||||
for (int32_t i = 0; i < removedTopicNum; i++) {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
char *removedTopic = taosArrayGetP(pConsumer->rebRemovedTopics, i);
|
||||
mndMakeSubscribeKey(key, pConsumer->cgroup, removedTopic);
|
||||
SMqRebInfo *pRebSub = mndGetOrCreateRebSub(rebSubHash, key);
|
||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||
}
|
||||
|
||||
if (newTopicNum == 0 && removedTopicNum == 0 && taosArrayGetSize(pConsumer->assignedTopics) == 0) { // unsubscribe or close
|
||||
mndDropConsumerFromSdb(pMnode, pConsumer->consumerId, &pMsg->info);
|
||||
}
|
||||
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
}
|
||||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mndRebTryStart() {
|
||||
int32_t old = atomic_val_compare_exchange_32(&mqRebInExecCnt, 0, 1);
|
||||
mInfo("rebalance counter old val:%d", old);
|
||||
return old == 0;
|
||||
}
|
||||
|
||||
void mndRebCntInc() {
|
||||
int32_t val = atomic_add_fetch_32(&mqRebInExecCnt, 1);
|
||||
mInfo("rebalance cnt inc, value:%d", val);
|
||||
}
|
||||
|
||||
void mndRebCntDec() {
|
||||
int32_t val = atomic_sub_fetch_32(&mqRebInExecCnt, 1);
|
||||
mInfo("rebalance cnt sub, value:%d", val);
|
||||
}
|
||||
|
||||
static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||
int code = 0;
|
||||
if (!mndRebTryStart()) {
|
||||
mInfo("mq rebalance already in progress, do nothing");
|
||||
return code;
|
||||
}
|
||||
|
||||
SHashObj *rebSubHash = taosHashInit(64, MurmurHash3_32, true, HASH_NO_LOCK);
|
||||
if (rebSubHash == NULL) {
|
||||
mError("failed to create rebalance hashmap");
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
code = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
taosHashSetFreeFp(rebSubHash, freeRebalanceItem);
|
||||
|
||||
mndCheckConsumer(pMsg, rebSubHash);
|
||||
mInfo("mq re-balance start, total required re-balanced trans:%d", taosHashGetSize(rebSubHash));
|
||||
|
||||
// here we only handle one topic rebalance requirement to ensure the atomic execution of this transaction.
|
||||
void *pIter = NULL;
|
||||
SMnode *pMnode = pMsg->info.node;
|
||||
while (1) {
|
||||
pIter = taosHashIterate(pReq->rebSubHash, pIter);
|
||||
pIter = taosHashIterate(rebSubHash, pIter);
|
||||
if (pIter == NULL) {
|
||||
break;
|
||||
}
|
||||
|
@ -756,12 +893,11 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
|||
taosArrayDestroy(rebOutput.modifyConsumers);
|
||||
taosArrayDestroy(rebOutput.rebVgs);
|
||||
|
||||
taosHashCancelIterate(pReq->rebSubHash, pIter);
|
||||
taosHashCancelIterate(rebSubHash, pIter);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mInfo("mq re-balance failed, due to out of memory");
|
||||
taosHashCleanup(pReq->rebSubHash);
|
||||
mndRebEnd();
|
||||
return -1;
|
||||
mError("mq re-balance failed, due to out of memory");
|
||||
code = -1;
|
||||
goto END;
|
||||
}
|
||||
|
||||
SMqRebInfo *pRebInfo = (SMqRebInfo *)pIter;
|
||||
|
@ -829,10 +965,12 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
|||
|
||||
// reset flag
|
||||
mInfo("mq re-balance completed successfully");
|
||||
taosHashCleanup(pReq->rebSubHash);
|
||||
mndRebEnd();
|
||||
|
||||
return 0;
|
||||
END:
|
||||
taosHashCleanup(rebSubHash);
|
||||
mndRebCntDec();
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t sendDeleteSubToVnode(SMqSubscribeObj *pSub, STrans *pTrans){
|
||||
|
@ -1215,7 +1353,7 @@ int32_t mndDropSubByTopic(SMnode *pMnode, STrans *pTrans, const char *topicName)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (mndSetDropSubRedoLogs(pMnode, pTrans, pSub) < 0) {
|
||||
if (mndSetDropSubCommitLogs(pMnode, pTrans, pSub) < 0) {
|
||||
sdbRelease(pSdb, pSub);
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
return -1;
|
||||
|
|
|
@ -180,7 +180,7 @@ int32_t mndProcessWriteMsg(SMnode *pMnode, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
|||
goto _OUT;
|
||||
}
|
||||
|
||||
mInfo("trans:%d, is proposed, saved:%d code:0x%x, apply index:%" PRId64 " term:%" PRIu64 " config:%" PRId64
|
||||
mInfo("trans:%d, process sync proposal, saved:%d code:0x%x, apply index:%" PRId64 " term:%" PRIu64 " config:%" PRId64
|
||||
" role:%s raw:%p sec:%d seq:%" PRId64,
|
||||
transId, pMgmt->transId, pMeta->code, pMeta->index, pMeta->term, pMeta->lastConfigIndex, syncStr(pMeta->state),
|
||||
pRaw, pMgmt->transSec, pMgmt->transSeq);
|
||||
|
@ -208,15 +208,11 @@ int32_t mndProcessWriteMsg(SMnode *pMnode, SRpcMsg *pMsg, SFsmCbMeta *pMeta) {
|
|||
}
|
||||
|
||||
if (pTrans->stage == TRN_STAGE_PREPARE) {
|
||||
bool continueExec = mndTransPerformPrepareStage(pMnode, pTrans);
|
||||
bool continueExec = mndTransPerformPrepareStage(pMnode, pTrans, false);
|
||||
if (!continueExec) goto _OUT;
|
||||
}
|
||||
|
||||
if (pTrans->id != pMgmt->transId) {
|
||||
mInfo("trans:%d, execute in mnode which not leader or sync timeout, createTime:%" PRId64 " saved trans:%d",
|
||||
pTrans->id, pTrans->createdTime, pMgmt->transId);
|
||||
mndTransRefresh(pMnode, pTrans);
|
||||
}
|
||||
mndTransRefresh(pMnode, pTrans);
|
||||
|
||||
sdbSetApplyInfo(pMnode->pSdb, pMeta->index, pMeta->term, pMeta->lastConfigIndex);
|
||||
sdbWriteFile(pMnode->pSdb, tsMndSdbWriteDelta);
|
||||
|
@ -234,6 +230,7 @@ static int32_t mndPostMgmtCode(SMnode *pMnode, int32_t code) {
|
|||
goto _OUT;
|
||||
}
|
||||
|
||||
int32_t transId = pMgmt->transId;
|
||||
pMgmt->transId = 0;
|
||||
pMgmt->transSec = 0;
|
||||
pMgmt->transSeq = 0;
|
||||
|
@ -241,9 +238,9 @@ static int32_t mndPostMgmtCode(SMnode *pMnode, int32_t code) {
|
|||
tsem_post(&pMgmt->syncSem);
|
||||
|
||||
if (pMgmt->errCode != 0) {
|
||||
mError("trans:%d, failed to propose since %s, post sem", pMgmt->transId, tstrerror(pMgmt->errCode));
|
||||
mError("trans:%d, failed to propose since %s, post sem", transId, tstrerror(pMgmt->errCode));
|
||||
} else {
|
||||
mInfo("trans:%d, is proposed and post sem, seq:%" PRId64, pMgmt->transId, pMgmt->transSeq);
|
||||
mInfo("trans:%d, is proposed and post sem, seq:%" PRId64, transId, pMgmt->transSeq);
|
||||
}
|
||||
|
||||
_OUT:
|
||||
|
@ -542,7 +539,7 @@ int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, int32_t transId) {
|
|||
taosThreadMutexLock(&pMgmt->lock);
|
||||
pMgmt->errCode = 0;
|
||||
|
||||
if (pMgmt->transId != 0 /* && pMgmt->transId != transId*/) {
|
||||
if (pMgmt->transId != 0) {
|
||||
mError("trans:%d, can't be proposed since trans:%d already waiting for confirm", transId, pMgmt->transId);
|
||||
taosThreadMutexUnlock(&pMgmt->lock);
|
||||
rpcFreeCont(req.pCont);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndTrans.h"
|
||||
#include "mndConsumer.h"
|
||||
#include "mndSubscribe.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
|
@ -36,21 +36,25 @@ static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw);
|
|||
static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction);
|
||||
static void mndTransDropLogs(SArray *pArray);
|
||||
static void mndTransDropActions(SArray *pArray);
|
||||
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray);
|
||||
static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans);
|
||||
static bool mndCannotExecuteTransAction(SMnode *pMnode) { return !pMnode->deploy && !mndIsLeader(pMnode); }
|
||||
|
||||
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray, bool topHalf);
|
||||
static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformRedoLogStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformUndoLogStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans, bool topHalf);
|
||||
|
||||
static bool mndCannotExecuteTransAction(SMnode *pMnode, bool topHalf) {
|
||||
return (!pMnode->deploy && !mndIsLeader(pMnode)) || !topHalf;
|
||||
}
|
||||
|
||||
static void mndTransSendRpcRsp(SMnode *pMnode, STrans *pTrans);
|
||||
static int32_t mndProcessTransTimer(SRpcMsg *pReq);
|
||||
|
@ -1090,8 +1094,9 @@ static void mndTransResetActions(SMnode *pMnode, STrans *pTrans, SArray *pArray)
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
|
||||
static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||
if (pAction->rawWritten) return 0;
|
||||
if (topHalf) return TSDB_CODE_MND_TRANS_CTX_SWITCH;
|
||||
|
||||
int32_t code = sdbWriteWithoutFree(pMnode->pSdb, pAction->pRaw);
|
||||
if (code == 0 || terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||
|
@ -1112,9 +1117,9 @@ static int32_t mndTransWriteSingleLog(SMnode *pMnode, STrans *pTrans, STransActi
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
|
||||
if (pAction->msgSent) return 0;
|
||||
if (mndCannotExecuteTransAction(pMnode)) return -1;
|
||||
static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||
if (pAction->msgSent) return 0;
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return TSDB_CODE_MND_TRANS_CTX_SWITCH;
|
||||
|
||||
int64_t signature = pTrans->id;
|
||||
signature = (signature << 32);
|
||||
|
@ -1159,7 +1164,8 @@ static int32_t mndTransSendSingleMsg(SMnode *pMnode, STrans *pTrans, STransActio
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecNullMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
|
||||
static int32_t mndTransExecNullMsg(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||
if (!topHalf) return TSDB_CODE_MND_TRANS_CTX_SWITCH;
|
||||
pAction->rawWritten = 0;
|
||||
pAction->errCode = 0;
|
||||
mInfo("trans:%d, %s:%d confirm action executed", pTrans->id, mndTransStr(pAction->stage), pAction->id);
|
||||
|
@ -1168,34 +1174,39 @@ static int32_t mndTransExecNullMsg(SMnode *pMnode, STrans *pTrans, STransAction
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecSingleAction(SMnode *pMnode, STrans *pTrans, STransAction *pAction) {
|
||||
static int32_t mndTransExecSingleAction(SMnode *pMnode, STrans *pTrans, STransAction *pAction, bool topHalf) {
|
||||
if (pAction->actionType == TRANS_ACTION_RAW) {
|
||||
return mndTransWriteSingleLog(pMnode, pTrans, pAction);
|
||||
return mndTransWriteSingleLog(pMnode, pTrans, pAction, topHalf);
|
||||
} else if (pAction->actionType == TRANS_ACTION_MSG) {
|
||||
return mndTransSendSingleMsg(pMnode, pTrans, pAction);
|
||||
return mndTransSendSingleMsg(pMnode, pTrans, pAction, topHalf);
|
||||
} else {
|
||||
return mndTransExecNullMsg(pMnode, pTrans, pAction);
|
||||
return mndTransExecNullMsg(pMnode, pTrans, pAction, topHalf);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransExecSingleActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
|
||||
static int32_t mndTransExecSingleActions(SMnode *pMnode, STrans *pTrans, SArray *pArray, bool topHalf) {
|
||||
int32_t numOfActions = taosArrayGetSize(pArray);
|
||||
int32_t code = 0;
|
||||
|
||||
for (int32_t action = 0; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pArray, action);
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction);
|
||||
if (code != 0) break;
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction, topHalf);
|
||||
if (code != 0) {
|
||||
mInfo("trans:%d, action:%d not executed since %s. numOfActions:%d", pTrans->id, action, tstrerror(code),
|
||||
numOfActions);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray) {
|
||||
static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pArray, bool topHalf) {
|
||||
int32_t numOfActions = taosArrayGetSize(pArray);
|
||||
int32_t code = 0;
|
||||
if (numOfActions == 0) return 0;
|
||||
|
||||
if (mndTransExecSingleActions(pMnode, pTrans, pArray) != 0) {
|
||||
if ((code = mndTransExecSingleActions(pMnode, pTrans, pArray, topHalf)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1248,31 +1259,31 @@ static int32_t mndTransExecuteActions(SMnode *pMnode, STrans *pTrans, SArray *pA
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->redoActions);
|
||||
static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->redoActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("failed to execute redoActions since:%s, code:0x%x", terrstr(), terrno);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->undoActions);
|
||||
static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->undoActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("failed to execute undoActions since %s", terrstr());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->commitActions);
|
||||
static int32_t mndTransExecuteCommitActions(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = mndTransExecuteActions(pMnode, pTrans, pTrans->commitActions, topHalf);
|
||||
if (code != 0 && code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
mError("failed to execute commitActions since %s", terrstr());
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans) {
|
||||
static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
int32_t code = 0;
|
||||
int32_t numOfActions = taosArrayGetSize(pTrans->redoActions);
|
||||
if (numOfActions == 0) return code;
|
||||
|
@ -1289,7 +1300,7 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
|||
for (int32_t action = pTrans->redoActionPos; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pTrans->redoActions, pTrans->redoActionPos);
|
||||
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction);
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction, topHalf);
|
||||
if (code == 0) {
|
||||
if (pAction->msgSent) {
|
||||
if (pAction->msgReceived) {
|
||||
|
@ -1317,14 +1328,16 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
|||
}
|
||||
mndSetTransLastAction(pTrans, pAction);
|
||||
|
||||
if (mndCannotExecuteTransAction(pMnode)) break;
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) break;
|
||||
|
||||
if (code == 0) {
|
||||
pTrans->code = 0;
|
||||
pTrans->redoActionPos++;
|
||||
mInfo("trans:%d, %s:%d is executed and need sync to other mnodes", pTrans->id, mndTransStr(pAction->stage),
|
||||
pAction->id);
|
||||
taosThreadMutexUnlock(&pTrans->mutex);
|
||||
code = mndTransSync(pMnode, pTrans);
|
||||
taosThreadMutexLock(&pTrans->mutex);
|
||||
if (code != 0) {
|
||||
pTrans->redoActionPos--;
|
||||
pTrans->code = terrno;
|
||||
|
@ -1357,7 +1370,7 @@ static int32_t mndTransExecuteRedoActionsSerial(SMnode *pMnode, STrans *pTrans)
|
|||
return code;
|
||||
}
|
||||
|
||||
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
|
||||
bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
bool continueExec = true;
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -1368,7 +1381,7 @@ bool mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) {
|
|||
|
||||
for (int32_t action = 0; action < numOfActions; ++action) {
|
||||
STransAction *pAction = taosArrayGet(pTrans->prepareActions, action);
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction);
|
||||
code = mndTransExecSingleAction(pMnode, pTrans, pAction, topHalf);
|
||||
if (code != 0) {
|
||||
mError("trans:%d, failed to execute prepare action:%d, numOfActions:%d", pTrans->id, action, numOfActions);
|
||||
return false;
|
||||
|
@ -1381,17 +1394,17 @@ _OVER:
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||
static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
bool continueExec = true;
|
||||
int32_t code = 0;
|
||||
|
||||
if (pTrans->exec == TRN_EXEC_SERIAL) {
|
||||
code = mndTransExecuteRedoActionsSerial(pMnode, pTrans);
|
||||
code = mndTransExecuteRedoActionsSerial(pMnode, pTrans, topHalf);
|
||||
} else {
|
||||
code = mndTransExecuteRedoActions(pMnode, pTrans);
|
||||
code = mndTransExecuteRedoActions(pMnode, pTrans, topHalf);
|
||||
}
|
||||
|
||||
if (mndCannotExecuteTransAction(pMnode)) return false;
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
terrno = code;
|
||||
|
||||
if (code == 0) {
|
||||
|
@ -1431,8 +1444,8 @@ static bool mndTransPerformRedoActionStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans) {
|
||||
if (mndCannotExecuteTransAction(pMnode)) return false;
|
||||
static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransCommit(pMnode, pTrans);
|
||||
|
@ -1452,9 +1465,9 @@ static bool mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||
static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransExecuteCommitActions(pMnode, pTrans);
|
||||
int32_t code = mndTransExecuteCommitActions(pMnode, pTrans, topHalf);
|
||||
|
||||
if (code == 0) {
|
||||
pTrans->code = 0;
|
||||
|
@ -1471,9 +1484,9 @@ static bool mndTransPerformCommitActionStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans) {
|
||||
static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransExecuteUndoActions(pMnode, pTrans);
|
||||
int32_t code = mndTransExecuteUndoActions(pMnode, pTrans, topHalf);
|
||||
|
||||
if (code == 0) {
|
||||
pTrans->stage = TRN_STAGE_PRE_FINISH;
|
||||
|
@ -1491,8 +1504,8 @@ static bool mndTransPerformUndoActionStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans) {
|
||||
if (mndCannotExecuteTransAction(pMnode)) return false;
|
||||
static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransRollback(pMnode, pTrans);
|
||||
|
@ -1510,8 +1523,8 @@ static bool mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformPreFinishStage(SMnode *pMnode, STrans *pTrans) {
|
||||
if (mndCannotExecuteTransAction(pMnode)) return false;
|
||||
static bool mndTransPerformPreFinishStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
if (mndCannotExecuteTransAction(pMnode, topHalf)) return false;
|
||||
|
||||
bool continueExec = true;
|
||||
int32_t code = mndTransPreFinish(pMnode, pTrans);
|
||||
|
@ -1529,8 +1542,9 @@ static bool mndTransPerformPreFinishStage(SMnode *pMnode, STrans *pTrans) {
|
|||
return continueExec;
|
||||
}
|
||||
|
||||
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans) {
|
||||
static bool mndTransPerformFinishStage(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
||||
bool continueExec = false;
|
||||
if (topHalf) return continueExec;
|
||||
|
||||
SSdbRaw *pRaw = mndTransEncode(pTrans);
|
||||
if (pRaw == NULL) {
|
||||
|
@ -1558,43 +1572,28 @@ void mndTransExecuteImp(SMnode *pMnode, STrans *pTrans, bool topHalf) {
|
|||
pTrans->lastExecTime = taosGetTimestampMs();
|
||||
switch (pTrans->stage) {
|
||||
case TRN_STAGE_PREPARE:
|
||||
continueExec = mndTransPerformPrepareStage(pMnode, pTrans);
|
||||
continueExec = mndTransPerformPrepareStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_REDO_ACTION:
|
||||
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans);
|
||||
continueExec = mndTransPerformRedoActionStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_COMMIT:
|
||||
if (topHalf) {
|
||||
continueExec = mndTransPerformCommitStage(pMnode, pTrans);
|
||||
} else {
|
||||
mInfo("trans:%d, can not commit since not leader", pTrans->id);
|
||||
continueExec = false;
|
||||
}
|
||||
continueExec = mndTransPerformCommitStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_COMMIT_ACTION:
|
||||
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans);
|
||||
continueExec = mndTransPerformCommitActionStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_ROLLBACK:
|
||||
if (topHalf) {
|
||||
continueExec = mndTransPerformRollbackStage(pMnode, pTrans);
|
||||
} else {
|
||||
mInfo("trans:%d, can not rollback since not leader", pTrans->id);
|
||||
continueExec = false;
|
||||
}
|
||||
continueExec = mndTransPerformRollbackStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_UNDO_ACTION:
|
||||
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans);
|
||||
continueExec = mndTransPerformUndoActionStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_PRE_FINISH:
|
||||
if (topHalf) {
|
||||
continueExec = mndTransPerformPreFinishStage(pMnode, pTrans);
|
||||
} else {
|
||||
mInfo("trans:%d, can not pre-finish since not leader", pTrans->id);
|
||||
continueExec = false;
|
||||
}
|
||||
continueExec = mndTransPerformPreFinishStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
case TRN_STAGE_FINISH:
|
||||
continueExec = mndTransPerformFinishStage(pMnode, pTrans);
|
||||
continueExec = mndTransPerformFinishStage(pMnode, pTrans, topHalf);
|
||||
break;
|
||||
default:
|
||||
continueExec = false;
|
||||
|
|
|
@ -125,7 +125,7 @@ SSnode *sndOpen(const char *path, const SSnodeOpt *pOption) {
|
|||
}
|
||||
|
||||
pSnode->msgCb = pOption->msgCb;
|
||||
pSnode->pMeta = streamMetaOpen(path, pSnode, (FTaskExpand *)sndExpandTask, SNODE_HANDLE, taosGetTimestampMs());
|
||||
pSnode->pMeta = streamMetaOpen(path, pSnode, (FTaskExpand *)sndExpandTask, SNODE_HANDLE, taosGetTimestampMs(), tqStartTaskCompleteCallback);
|
||||
if (pSnode->pMeta == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
|
@ -147,8 +147,8 @@ FAIL:
|
|||
}
|
||||
|
||||
int32_t sndInit(SSnode *pSnode) {
|
||||
resetStreamTaskStatus(pSnode->pMeta);
|
||||
startStreamTasks(pSnode->pMeta);
|
||||
tqStreamTaskResetStatus(pSnode->pMeta);
|
||||
streamMetaStartAllTasks(pSnode->pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -202,6 +202,8 @@ int32_t sndProcessWriteMsg(SSnode *pSnode, SRpcMsg *pMsg, SRpcMsg *pRsp) {
|
|||
return tqStreamTaskProcessDropReq(pSnode->pMeta, pMsg->pCont, pMsg->contLen);
|
||||
case TDMT_VND_STREAM_TASK_UPDATE:
|
||||
return tqStreamTaskProcessUpdateReq(pSnode->pMeta, &pSnode->msgCb, pMsg, true);
|
||||
case TDMT_VND_STREAM_TASK_RESET:
|
||||
return tqStreamTaskProcessTaskResetReq(pSnode->pMeta, pMsg);
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -152,9 +152,6 @@ void tqSinkDataIntoDstTable(SStreamTask* pTask, void* vnode, void* data);
|
|||
char* tqOffsetBuildFName(const char* path, int32_t fVer);
|
||||
int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname);
|
||||
|
||||
// tqStream
|
||||
int32_t tqStopStreamTasks(STQ* pTq);
|
||||
|
||||
// tq util
|
||||
int32_t extractDelDataBlock(const void* pData, int32_t len, int64_t ver, void** pRefBlock, int32_t type);
|
||||
int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg);
|
||||
|
|
|
@ -256,18 +256,7 @@ void tsdbDelFileName(STsdb *pTsdb, SDelFile *pFile, char fname[]);
|
|||
// tsdbFS.c ==============================================================================================
|
||||
int32_t tsdbFSOpen(STsdb *pTsdb, int8_t rollback);
|
||||
int32_t tsdbFSClose(STsdb *pTsdb);
|
||||
int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS);
|
||||
void tsdbFSDestroy(STsdbFS *pFS);
|
||||
int32_t tDFileSetCmprFn(const void *p1, const void *p2);
|
||||
int32_t tsdbFSCommit(STsdb *pTsdb);
|
||||
int32_t tsdbFSRollback(STsdb *pTsdb);
|
||||
int32_t tsdbFSPrepareCommit(STsdb *pTsdb, STsdbFS *pFS);
|
||||
int32_t tsdbFSRef(STsdb *pTsdb, STsdbFS *pFS);
|
||||
void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS);
|
||||
void tsdbGetCurrentFName(STsdb *pTsdb, char *current, char *current_t);
|
||||
|
||||
int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet);
|
||||
int32_t tsdbFSUpsertDelFile(STsdbFS *pFS, SDelFile *pDelFile);
|
||||
// tsdbReaderWriter.c ==============================================================================================
|
||||
// SDataFWriter
|
||||
int32_t tsdbDataFWriterOpen(SDataFWriter **ppWriter, STsdb *pTsdb, SDFileSet *pSet);
|
||||
|
@ -737,7 +726,6 @@ struct STsdbReadSnap {
|
|||
SMemTable *pIMem;
|
||||
SQueryNode *pINode;
|
||||
TFileSetArray *pfSetArray;
|
||||
STsdbFS fs;
|
||||
};
|
||||
|
||||
struct SDataFWriter {
|
||||
|
@ -796,16 +784,16 @@ typedef struct {
|
|||
} SSttTableRowsInfo;
|
||||
|
||||
typedef struct SSttBlockLoadInfo {
|
||||
SBlockDataInfo blockData[2]; // buffered block data
|
||||
SArray *aSttBlk;
|
||||
int32_t currentLoadBlockIndex;
|
||||
STSchema *pSchema;
|
||||
int16_t *colIds;
|
||||
int32_t numOfCols;
|
||||
bool checkRemainingRow; // todo: no assign value?
|
||||
bool isLast;
|
||||
bool sttBlockLoaded;
|
||||
SSttTableRowsInfo info;
|
||||
SBlockDataInfo blockData[2]; // buffered block data
|
||||
SArray *aSttBlk;
|
||||
int32_t currentLoadBlockIndex;
|
||||
STSchema *pSchema;
|
||||
int16_t *colIds;
|
||||
int32_t numOfCols;
|
||||
bool checkRemainingRow; // todo: no assign value?
|
||||
bool isLast;
|
||||
bool sttBlockLoaded;
|
||||
SSttTableRowsInfo info;
|
||||
SSttBlockLoadCostInfo cost;
|
||||
} SSttBlockLoadInfo;
|
||||
|
||||
|
@ -894,15 +882,15 @@ typedef struct {
|
|||
_load_tomb_fn loadTombFn;
|
||||
void *pReader;
|
||||
void *idstr;
|
||||
bool rspRows; // response the rows in stt-file, if possible
|
||||
bool rspRows; // response the rows in stt-file, if possible
|
||||
} SMergeTreeConf;
|
||||
|
||||
typedef struct SSttDataInfoForTable {
|
||||
SArray* pTimeWindowList;
|
||||
SArray *pTimeWindowList;
|
||||
int64_t numOfRows;
|
||||
} SSttDataInfoForTable;
|
||||
|
||||
int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoForTable* pTableInfo);
|
||||
int32_t tMergeTreeOpen2(SMergeTree *pMTree, SMergeTreeConf *pConf, SSttDataInfoForTable *pTableInfo);
|
||||
void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter);
|
||||
bool tMergeTreeNext(SMergeTree *pMTree);
|
||||
void tMergeTreePinSttBlock(SMergeTree *pMTree);
|
||||
|
|
|
@ -95,7 +95,7 @@ typedef struct SQueryNode SQueryNode;
|
|||
#define VNODE_RSMA2_DIR "rsma2"
|
||||
#define VNODE_TQ_STREAM "stream"
|
||||
|
||||
#if SUSPEND_RESUME_TEST // only for test purpose
|
||||
#if SUSPEND_RESUME_TEST // only for test purpose
|
||||
#define VNODE_BUFPOOL_SEGMENTS 1
|
||||
#else
|
||||
#define VNODE_BUFPOOL_SEGMENTS 3
|
||||
|
@ -216,8 +216,6 @@ int32_t tsdbBegin(STsdb* pTsdb);
|
|||
int32_t tsdbCacheCommit(STsdb* pTsdb);
|
||||
int32_t tsdbCompact(STsdb* pTsdb, SCompactInfo* pInfo);
|
||||
int32_t tsdbRetention(STsdb* tsdb, int64_t now, int32_t sync);
|
||||
// int32_t tsdbFinishCommit(STsdb* pTsdb);
|
||||
// int32_t tsdbRollbackCommit(STsdb* pTsdb);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, SSubmitReq2* pMsg);
|
||||
int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq2* pMsg, SSubmitRsp2* pRsp);
|
||||
int32_t tsdbInsertTableData(STsdb* pTsdb, int64_t version, SSubmitTbData* pSubmitTbData, int32_t* affectedRows);
|
||||
|
@ -232,6 +230,7 @@ int tqPushMsg(STQ*, tmsg_t msgType);
|
|||
int tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg);
|
||||
int tqUnregisterPushHandle(STQ* pTq, void* pHandle);
|
||||
int tqScanWalAsync(STQ* pTq, bool ckPause);
|
||||
int32_t tqStopStreamTasksAsync(STQ* pTq);
|
||||
int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp);
|
||||
int32_t tqProcessTaskCheckpointReadyMsg(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
|
|
|
@ -36,7 +36,6 @@ static int metaDeleteBtimeIdx(SMeta *pMeta, const SMetaEntry *pME);
|
|||
static int metaUpdateNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
|
||||
static int metaDeleteNcolIdx(SMeta *pMeta, const SMetaEntry *pME);
|
||||
|
||||
|
||||
static void metaGetEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
|
||||
pInfo->uid = pEntry->uid;
|
||||
pInfo->version = pEntry->version;
|
||||
|
@ -562,6 +561,7 @@ int metaAddIndexToSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
|
||||
metaULock(pMeta);
|
||||
metaDestroyTagIdxKey(pTagIdxKey);
|
||||
pTagIdxKey = NULL;
|
||||
}
|
||||
|
||||
nStbEntry.version = version;
|
||||
|
@ -692,6 +692,7 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq)
|
|||
tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
|
||||
metaULock(pMeta);
|
||||
metaDestroyTagIdxKey(pTagIdxKey);
|
||||
pTagIdxKey = NULL;
|
||||
}
|
||||
|
||||
// clear idx flag
|
||||
|
@ -1076,7 +1077,7 @@ static int metaDeleteTtl(SMeta *pMeta, const SMetaEntry *pME) {
|
|||
return ttlMgrDeleteTtl(pMeta->pTtlMgr, &ctx);
|
||||
}
|
||||
|
||||
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t* pSysTbl) {
|
||||
static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *pSuid, int8_t *pSysTbl) {
|
||||
void *pData = NULL;
|
||||
int nData = 0;
|
||||
int rc = 0;
|
||||
|
@ -1146,6 +1147,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *p
|
|||
tdbTbDelete(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, pMeta->txn);
|
||||
}
|
||||
metaDestroyTagIdxKey(pTagIdxKey);
|
||||
pTagIdxKey = NULL;
|
||||
}
|
||||
}
|
||||
tDecoderClear(&tdc);
|
||||
|
@ -1865,6 +1867,7 @@ static int metaAddTagIndex(SMeta *pMeta, int64_t version, SVAlterTbReq *pAlterTb
|
|||
}
|
||||
tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
|
||||
metaDestroyTagIdxKey(pTagIdxKey);
|
||||
pTagIdxKey = NULL;
|
||||
}
|
||||
tdbTbcClose(pCtbIdxc);
|
||||
return 0;
|
||||
|
@ -2122,7 +2125,7 @@ int metaUpdateChangeTimeWithLock(SMeta *pMeta, tb_uid_t uid, int64_t changeTimeM
|
|||
if (!tsTtlChangeOnWrite) return 0;
|
||||
|
||||
metaWLock(pMeta);
|
||||
int ret = metaUpdateChangeTime(pMeta, uid, changeTimeMs);
|
||||
int ret = metaUpdateChangeTime(pMeta, uid, changeTimeMs);
|
||||
metaULock(pMeta);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2228,15 +2231,14 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
|
|||
nTagData = tDataTypes[pTagColumn->type].bytes;
|
||||
}
|
||||
|
||||
if (pTagData != NULL) {
|
||||
if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
|
||||
pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
|
||||
if (metaCreateTagIdxKey(pCtbEntry->ctbEntry.suid, pTagColumn->colId, pTagData, nTagData, pTagColumn->type,
|
||||
pCtbEntry->uid, &pTagIdxKey, &nTagIdxKey) < 0) {
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
tdbTbUpsert(pMeta->pTagIdx, pTagIdxKey, nTagIdxKey, NULL, 0, pMeta->txn);
|
||||
metaDestroyTagIdxKey(pTagIdxKey);
|
||||
pTagIdxKey = NULL;
|
||||
}
|
||||
}
|
||||
end:
|
||||
|
|
|
@ -240,23 +240,23 @@ int32_t tdFetchTbUidList(SSma *pSma, STbUidStore **ppStore, tb_uid_t suid, tb_ui
|
|||
|
||||
static void tdRSmaTaskInit(SStreamMeta *pMeta, SRSmaInfoItem *pItem, SStreamTaskId *pId) {
|
||||
STaskId id = {.streamId = pId->streamId, .taskId = pId->taskId};
|
||||
taosRLockLatch(&pMeta->lock);
|
||||
streamMetaRLock(pMeta);
|
||||
SStreamTask **ppTask = (SStreamTask **)taosHashGet(pMeta->pTasksMap, &id, sizeof(id));
|
||||
if (ppTask && *ppTask) {
|
||||
pItem->submitReqVer = (*ppTask)->chkInfo.checkpointVer;
|
||||
pItem->fetchResultVer = (*ppTask)->info.triggerParam;
|
||||
}
|
||||
taosRUnLockLatch(&pMeta->lock);
|
||||
streamMetaRUnLock(pMeta);
|
||||
}
|
||||
|
||||
static void tdRSmaTaskRemove(SStreamMeta *pMeta, int64_t streamId, int32_t taskId) {
|
||||
streamMetaUnregisterTask(pMeta, streamId, taskId);
|
||||
taosWLockLatch(&pMeta->lock);
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
|
||||
if (streamMetaCommit(pMeta) < 0) {
|
||||
// persist to disk
|
||||
}
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
streamMetaWUnLock(pMeta);
|
||||
smaDebug("vgId:%d, rsma task:%" PRIi64 ",%d dropped, remain tasks:%d", pMeta->vgId, streamId, taskId, numOfTasks);
|
||||
}
|
||||
|
||||
|
@ -1301,14 +1301,14 @@ _checkpoint:
|
|||
checkpointBuilt = true;
|
||||
}
|
||||
|
||||
taosWLockLatch(&pMeta->lock);
|
||||
streamMetaWLock(pMeta);
|
||||
if (streamMetaSaveTask(pMeta, pTask)) {
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
streamMetaWUnLock(pMeta);
|
||||
code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
|
||||
taosHashCancelIterate(pInfoHash, infoHash);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
streamMetaWUnLock(pMeta);
|
||||
smaDebug("vgId:%d, rsma commit, succeed to commit task:%p, submitReqVer:%" PRIi64 ", fetchResultVer:%" PRIi64
|
||||
", table:%" PRIi64 ", level:%d",
|
||||
TD_VID(pVnode), pTask, pItem->submitReqVer, pItem->fetchResultVer, pRSmaInfo->suid, i + 1);
|
||||
|
@ -1316,13 +1316,13 @@ _checkpoint:
|
|||
}
|
||||
}
|
||||
if (pMeta) {
|
||||
taosWLockLatch(&pMeta->lock);
|
||||
streamMetaWLock(pMeta);
|
||||
if (streamMetaCommit(pMeta)) {
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
streamMetaWUnLock(pMeta);
|
||||
code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
streamMetaWUnLock(pMeta);
|
||||
}
|
||||
if (checkpointBuilt) {
|
||||
smaInfo("vgId:%d, rsma commit, succeed to commit checkpoint:%" PRIi64, TD_VID(pVnode), checkpointId);
|
||||
|
|
|
@ -96,7 +96,8 @@ int32_t tqInitialize(STQ* pTq) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
pTq->pStreamMeta = streamMetaOpen(pTq->path, pTq, (FTaskExpand*)tqExpandTask, pTq->pVnode->config.vgId, -1);
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
pTq->pStreamMeta = streamMetaOpen(pTq->path, pTq, (FTaskExpand*)tqExpandTask, vgId, -1, tqStartTaskCompleteCallback);
|
||||
if (pTq->pStreamMeta == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1036,15 +1037,16 @@ int32_t tqProcessTaskScanHistory(STQ* pTq, SRpcMsg* pMsg) {
|
|||
|
||||
streamMetaReleaseTask(pMeta, pStreamTask);
|
||||
} else {
|
||||
STimeWindow* pWindow = &pTask->dataRange.window;
|
||||
ASSERT(HAS_RELATED_FILLHISTORY_TASK(pTask) || streamTaskShouldStop(pTask));
|
||||
|
||||
// Not update the fill-history time window until the state transfer is completed.
|
||||
tqDebug("s-task:%s scan-history in stream time window completed, start to handle data from WAL, startVer:%" PRId64
|
||||
", window:%" PRId64 " - %" PRId64,
|
||||
id, pTask->chkInfo.nextProcessVer, pWindow->skey, pWindow->ekey);
|
||||
|
||||
code = streamTaskScanHistoryDataComplete(pTask);
|
||||
ASSERT(0);
|
||||
// STimeWindow* pWindow = &pTask->dataRange.window;
|
||||
// ASSERT(HAS_RELATED_FILLHISTORY_TASK(pTask) || streamTaskShouldStop(pTask));
|
||||
//
|
||||
// // Not update the fill-history time window until the state transfer is completed.
|
||||
// tqDebug("s-task:%s scan-history in stream time window completed, start to handle data from WAL, startVer:%" PRId64
|
||||
// ", window:%" PRId64 " - %" PRId64,
|
||||
// id, pTask->chkInfo.nextProcessVer, pWindow->skey, pWindow->ekey);
|
||||
//
|
||||
// code = streamTaskScanHistoryDataComplete(pTask);
|
||||
}
|
||||
|
||||
atomic_store_32(&pTask->status.inScanHistorySentinel, 0);
|
||||
|
@ -1070,10 +1072,12 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
tqScanWal(pTq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t code = tqStreamTaskProcessRunReq(pTq->pStreamMeta, pMsg, vnodeIsRoleLeader(pTq->pVnode));
|
||||
if(code == 0 && taskId > 0){
|
||||
tqScanWalAsync(pTq, false);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1167,7 +1171,7 @@ int32_t tqProcessTaskResumeImpl(STQ* pTq, SStreamTask* pTask, int64_t sversion,
|
|||
} else if (status == TASK_STATUS__UNINIT) {
|
||||
// todo: fill-history task init ?
|
||||
if (pTask->info.fillHistory == 0) {
|
||||
EStreamTaskEvent event = HAS_RELATED_FILLHISTORY_TASK(pTask) ? TASK_EVENT_INIT_STREAM_SCANHIST : TASK_EVENT_INIT;
|
||||
EStreamTaskEvent event = /*HAS_RELATED_FILLHISTORY_TASK(pTask) ? TASK_EVENT_INIT_STREAM_SCANHIST : */TASK_EVENT_INIT;
|
||||
streamTaskHandleEvent(pTask->status.pSM, event);
|
||||
}
|
||||
}
|
||||
|
@ -1256,10 +1260,11 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
if (pTask->status.downstreamReady != 1) {
|
||||
pTask->chkInfo.failedId = req.checkpointId; // record the latest failed checkpoint id
|
||||
pTask->chkInfo.checkpointingId = req.checkpointId;
|
||||
pTask->chkInfo.transId = req.transId;
|
||||
|
||||
tqError("s-task:%s not ready for checkpoint, since downstream not ready, ignore this checkpoint:%" PRId64
|
||||
", set it failure",
|
||||
pTask->id.idStr, req.checkpointId);
|
||||
", transId:%d set it failed",
|
||||
pTask->id.idStr, req.checkpointId, req.transId);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
||||
SRpcMsg rsp = {0};
|
||||
|
@ -1288,10 +1293,9 @@ int32_t tqProcessTaskCheckPointSourceReq(STQ* pTq, SRpcMsg* pMsg, SRpcMsg* pRsp)
|
|||
|
||||
// check if the checkpoint msg already sent or not.
|
||||
if (status == TASK_STATUS__CK) {
|
||||
ASSERT(pTask->chkInfo.checkpointingId == req.checkpointId);
|
||||
tqWarn("s-task:%s recv checkpoint-source msg again checkpointId:%" PRId64
|
||||
" already received, ignore this msg and continue process checkpoint",
|
||||
pTask->id.idStr, pTask->chkInfo.checkpointingId);
|
||||
" transId:%d already received, ignore this msg and continue process checkpoint",
|
||||
pTask->id.idStr, pTask->chkInfo.checkpointingId, req.transId);
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
|
@ -1335,28 +1339,10 @@ int32_t tqProcessTaskUpdateReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
}
|
||||
|
||||
int32_t tqProcessTaskResetReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)pMsg->pCont;
|
||||
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d process task-reset req, failed to acquire task:0x%x, it may have been dropped already",
|
||||
pMeta->vgId, pReq->taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s receive task-reset msg from mnode, reset status and ready for data processing", pTask->id.idStr);
|
||||
|
||||
// clear flag set during do checkpoint, and open inputQ for all upstream tasks
|
||||
if (streamTaskGetStatus(pTask, NULL) == TASK_STATUS__CK) {
|
||||
streamTaskClearCheckInfo(pTask, true);
|
||||
streamTaskSetStatusReady(pTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return tqStreamTaskProcessTaskResetReq(pTq->pStreamMeta, pMsg);
|
||||
}
|
||||
|
||||
// NOTE: here we may receive this message more than once, so need to handle this case
|
||||
int32_t tqProcessTaskDropHTask(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SVDropHTaskReq* pReq = (SVDropHTaskReq*)pMsg->pCont;
|
||||
|
||||
|
@ -1375,14 +1361,17 @@ int32_t tqProcessTaskDropHTask(STQ* pTq, SRpcMsg* pMsg) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
ASSERT(status == TASK_STATUS__STREAM_SCAN_HISTORY);
|
||||
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE);
|
||||
// if (status == TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
// streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_SCANHIST_DONE);
|
||||
// }
|
||||
|
||||
SStreamTaskId id = {.streamId = pTask->hTaskInfo.id.streamId, .taskId = pTask->hTaskInfo.id.taskId};
|
||||
streamBuildAndSendDropTaskMsg(pTask->pMsgCb, pMeta->vgId, &id);
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
// clear the scheduler status
|
||||
streamTaskSetSchedStatusInactive(pTask);
|
||||
tqDebug("s-task:%s set scheduler status:%d after drop fill-history task", pTask->id.idStr, pTask->status.schedStatus);
|
||||
|
|
|
@ -195,7 +195,8 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t
|
|||
int64_t committedVer = walGetCommittedVer(pHandle->pWalReader->pWal);
|
||||
int64_t appliedVer = walGetAppliedVer(pHandle->pWalReader->pWal);
|
||||
|
||||
wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64 ", applied index:%" PRId64", 0x%"PRIx64,
|
||||
wDebug("vgId:%d, start to fetch wal, index:%" PRId64 ", last:%" PRId64 " commit:%" PRId64 ", applied:%" PRId64
|
||||
", 0x%" PRIx64,
|
||||
vgId, offset, lastVer, committedVer, appliedVer, id);
|
||||
|
||||
while (offset <= appliedVer) {
|
||||
|
|
|
@ -39,7 +39,7 @@ int32_t tqScanWal(STQ* pTq) {
|
|||
bool shouldIdle = true;
|
||||
doScanWalForAllTasks(pTq->pStreamMeta, &shouldIdle);
|
||||
|
||||
if (shouldIdle) {
|
||||
// if (shouldIdle) {
|
||||
streamMetaWLock(pMeta);
|
||||
int32_t times = (--pMeta->walScanCounter);
|
||||
ASSERT(pMeta->walScanCounter >= 0);
|
||||
|
@ -50,7 +50,7 @@ int32_t tqScanWal(STQ* pTq) {
|
|||
} 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);
|
||||
}
|
||||
|
@ -109,8 +109,8 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d, restored:%d", vgId, numOfTasks,
|
||||
alreadyRestored);
|
||||
tqDebug("vgId:%d create msg to start wal scan to launch stream tasks, numOfTasks:%d, vnd restored:%d", vgId,
|
||||
numOfTasks, alreadyRestored);
|
||||
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
|
@ -123,33 +123,25 @@ int32_t tqScanWalAsync(STQ* pTq, bool ckPause) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqStopStreamTasks(STQ* pTq) {
|
||||
int32_t tqStopStreamTasksAsync(STQ* pTq) {
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
tqDebug("vgId:%d stop all %d stream task(s)", vgId, numOfTasks);
|
||||
if (numOfTasks == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
SStreamTaskRunReq* pRunReq = rpcMallocCont(sizeof(SStreamTaskRunReq));
|
||||
if (pRunReq == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tqError("vgId:%d failed to create msg to stop tasks, code:%s", vgId, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SArray* pTaskList = NULL;
|
||||
streamMetaWLock(pMeta);
|
||||
pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqDebug("vgId:%d create msg to stop tasks", vgId);
|
||||
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
pRunReq->head.vgId = vgId;
|
||||
pRunReq->streamId = 0;
|
||||
pRunReq->taskId = STREAM_EXEC_STOP_ALL_TASKS_ID;
|
||||
|
||||
streamTaskStop(pTask);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTaskList);
|
||||
SRpcMsg msg = {.msgType = TDMT_STREAM_TASK_RUN, .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq)};
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, STREAM_QUEUE, &msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -196,7 +196,7 @@ int32_t streamTaskSnapWriterClose(SStreamTaskWriter* pWriter, int8_t rollback) {
|
|||
int32_t code = 0;
|
||||
STQ* pTq = pWriter->pTq;
|
||||
|
||||
taosWLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWLock(pTq->pStreamMeta);
|
||||
tqDebug("vgId:%d, vnode stream-task snapshot writer closed", TD_VID(pTq->pVnode));
|
||||
if (rollback) {
|
||||
tdbAbort(pTq->pStreamMeta->db, pTq->pStreamMeta->txn);
|
||||
|
@ -212,14 +212,14 @@ int32_t streamTaskSnapWriterClose(SStreamTaskWriter* pWriter, int8_t rollback) {
|
|||
taosMemoryFree(pWriter);
|
||||
goto _err;
|
||||
}
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWUnLock(pTq->pStreamMeta);
|
||||
taosMemoryFree(pWriter);
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tqError("vgId:%d, vnode stream-task snapshot writer failed to close since %s", TD_VID(pWriter->pTq->pVnode),
|
||||
tstrerror(code));
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWUnLock(pTq->pStreamMeta);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -240,13 +240,13 @@ int32_t streamTaskSnapWrite(SStreamTaskWriter* pWriter, uint8_t* pData, uint32_t
|
|||
tDecoderClear(&decoder);
|
||||
|
||||
int64_t key[2] = {taskId.streamId, taskId.taskId};
|
||||
taosWLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWLock(pTq->pStreamMeta);
|
||||
if (tdbTbUpsert(pTq->pStreamMeta->pTaskDb, key, sizeof(int64_t) << 1, (uint8_t*)pData + sizeof(SSnapDataHdr),
|
||||
nData - sizeof(SSnapDataHdr), pTq->pStreamMeta->txn) < 0) {
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWUnLock(pTq->pStreamMeta);
|
||||
return -1;
|
||||
}
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
streamMetaWUnLock(pTq->pStreamMeta);
|
||||
} else if (pHdr->type == SNAP_DATA_STREAM_TASK_CHECKPOINT) {
|
||||
// do nothing
|
||||
}
|
||||
|
|
|
@ -35,20 +35,8 @@ int32_t tqInitDataRsp(SMqDataRsp* pRsp, STqOffsetVal pOffset) {
|
|||
}
|
||||
|
||||
void tqUpdateNodeStage(STQ* pTq, bool isLeader) {
|
||||
SSyncState state = syncGetState(pTq->pVnode->sync);
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
int64_t stage = pMeta->stage;
|
||||
|
||||
pMeta->stage = state.term;
|
||||
pMeta->role = (isLeader)? NODE_ROLE_LEADER:NODE_ROLE_FOLLOWER;
|
||||
if (isLeader) {
|
||||
tqInfo("vgId:%d update meta stage:%" PRId64 ", prev:%" PRId64 " leader:%d, start to send Hb", pMeta->vgId,
|
||||
state.term, stage, isLeader);
|
||||
streamMetaStartHb(pMeta);
|
||||
} else {
|
||||
tqInfo("vgId:%d update meta stage:%" PRId64 " prev:%" PRId64 " leader:%d", pMeta->vgId, state.term, stage,
|
||||
isLeader);
|
||||
}
|
||||
SSyncState state = syncGetState(pTq->pVnode->sync);
|
||||
streamMetaUpdateStageRole(pTq->pStreamMeta, state.term, isLeader);
|
||||
}
|
||||
|
||||
static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, STqOffsetVal pOffset) {
|
||||
|
|
|
@ -106,14 +106,15 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
return rsp.code;
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
// streamMetaWUnLock(pMeta);
|
||||
|
||||
// todo for test purpose
|
||||
// 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
|
||||
streamMetaWLock(pMeta);
|
||||
// streamMetaWLock(pMeta);
|
||||
|
||||
SStreamTask** ppHTask = NULL;
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
|
@ -166,65 +167,17 @@ int32_t tqStreamTaskProcessUpdateReq(SStreamMeta* pMeta, SMsgCb* cb, SRpcMsg* pM
|
|||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
if (!restored) {
|
||||
tqDebug("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 start the tasks, clear the start after nodeUpdate flag", vgId);
|
||||
pMeta->startInfo.tasksWillRestart = 0;
|
||||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
tqDebug("vgId:%d all %d task(s) nodeEp updated and closed", vgId, numOfTasks);
|
||||
#if 1
|
||||
#if 0
|
||||
// for test purpose, to trigger the leader election
|
||||
taosMSleep(5000);
|
||||
#endif
|
||||
tqStreamTaskStartAsync(pMeta, cb, true);
|
||||
streamMetaWUnLock(pMeta);
|
||||
#else
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// For debug purpose.
|
||||
// the following procedure consume many CPU resource, result in the re-election of leader
|
||||
// with high probability. So we employ it as a test case for the stream processing framework, with
|
||||
// checkpoint/restart/nodeUpdate etc.
|
||||
while (1) {
|
||||
int32_t startVal = atomic_val_compare_exchange_32(&pMeta->startInfo.taskStarting, 0, 1);
|
||||
if (startVal == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d in start stream tasks procedure, wait for 500ms and recheck", vgId);
|
||||
taosMsleep(500);
|
||||
}
|
||||
|
||||
while (streamMetaTaskInTimer(pMeta)) {
|
||||
tqDebug("vgId:%d some tasks in timer, wait for 100ms and recheck", pMeta->vgId);
|
||||
taosMsleep(100);
|
||||
}
|
||||
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
int32_t code = streamMetaReopen(pMeta);
|
||||
if (code != 0) {
|
||||
tqError("vgId:%d failed to reopen stream meta", vgId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
taosArrayDestroy(req.pNodeList);
|
||||
return -1;
|
||||
}
|
||||
|
||||
streamMetaInitBackend(pMeta);
|
||||
|
||||
if (streamMetaLoadAllTasks(pTq->pStreamMeta) < 0) {
|
||||
tqError("vgId:%d failed to load stream tasks", vgId);
|
||||
streamMetaWUnLock(pMeta);
|
||||
taosArrayDestroy(req.pNodeList);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vnodeIsRoleLeader(pTq->pVnode) && !tsDisableStream) {
|
||||
tqInfo("vgId:%d start all stream tasks after all being updated", vgId);
|
||||
resetStreamTaskStatus(pTq->pStreamMeta);
|
||||
tqStartStreamTaskAsync(pTq, false);
|
||||
} else {
|
||||
tqInfo("vgId:%d, follower node not start stream tasks", vgId);
|
||||
}
|
||||
streamMetaWUnLock(pMeta);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -592,7 +545,7 @@ int32_t tqStreamTaskProcessDeployReq(SStreamMeta* pMeta, int64_t sversion, char*
|
|||
SStreamTask* p = streamMetaAcquireTask(pMeta, streamId, taskId);
|
||||
|
||||
if (p != NULL && restored && p->info.fillHistory == 0) {
|
||||
EStreamTaskEvent event = (HAS_RELATED_FILLHISTORY_TASK(p)) ? TASK_EVENT_INIT_STREAM_SCANHIST : TASK_EVENT_INIT;
|
||||
EStreamTaskEvent event = TASK_EVENT_INIT;
|
||||
streamTaskHandleEvent(p->status.pSM, event);
|
||||
} else if (!restored) {
|
||||
tqWarn("s-task:%s not launched since vnode(vgId:%d) not ready", p->id.idStr, vgId);
|
||||
|
@ -645,65 +598,7 @@ int32_t tqStreamTaskProcessDropReq(SStreamMeta* pMeta, char* msg, int32_t msgLen
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t startStreamTasks(SStreamMeta* pMeta) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
tqDebug("vgId:%d start to check all %d stream task(s) downstream status", vgId, numOfTasks);
|
||||
if (numOfTasks == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SArray* pTaskList = NULL;
|
||||
streamMetaWLock(pMeta);
|
||||
pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
taosHashClear(pMeta->startInfo.pReadyTaskSet);
|
||||
taosHashClear(pMeta->startInfo.pFailedTaskSet);
|
||||
pMeta->startInfo.startTs = taosGetTimestampMs();
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// broadcast the check downstream tasks msg
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// fill-history task can only be launched by related stream tasks.
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pTask->status.downstreamReady == 1) {
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
tqDebug("s-task:%s downstream ready, no need to check downstream, check only related fill-history task",
|
||||
pTask->id.idStr);
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
}
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, pTask->execInfo.init,
|
||||
pTask->execInfo.start, true);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
EStreamTaskEvent event = (HAS_RELATED_FILLHISTORY_TASK(pTask)) ? TASK_EVENT_INIT_STREAM_SCANHIST : TASK_EVENT_INIT;
|
||||
int32_t ret = streamTaskHandleEvent(pTask->status.pSM, event);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
code = ret;
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTaskList);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t resetStreamTaskStatus(SStreamMeta* pMeta) {
|
||||
int32_t tqStreamTaskResetStatus(SStreamMeta* pMeta) {
|
||||
int32_t vgId = pMeta->vgId;
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
|
||||
|
@ -728,16 +623,18 @@ static int32_t restartStreamTasks(SStreamMeta* pMeta, bool isLeader) {
|
|||
int32_t code = 0;
|
||||
int64_t st = taosGetTimestampMs();
|
||||
|
||||
while (1) {
|
||||
int32_t startVal = atomic_val_compare_exchange_32(&pMeta->startInfo.taskStarting, 0, 1);
|
||||
if (startVal == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
tqDebug("vgId:%d in start stream tasks procedure, wait for 500ms and recheck", vgId);
|
||||
taosMsleep(500);
|
||||
streamMetaWLock(pMeta);
|
||||
if (pMeta->startInfo.taskStarting == 1) {
|
||||
pMeta->startInfo.restartCount += 1;
|
||||
tqDebug("vgId:%d in start tasks procedure, inc restartCounter by 1, remaining restart:%d", vgId,
|
||||
pMeta->startInfo.restartCount);
|
||||
streamMetaWUnLock(pMeta);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pMeta->startInfo.taskStarting = 1;
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
terrno = 0;
|
||||
tqInfo("vgId:%d tasks are all updated and stopped, restart all tasks, triggered by transId:%d", vgId,
|
||||
pMeta->updateInfo.transId);
|
||||
|
@ -762,11 +659,9 @@ static int32_t restartStreamTasks(SStreamMeta* pMeta, bool isLeader) {
|
|||
}
|
||||
|
||||
if (isLeader && !tsDisableStream) {
|
||||
resetStreamTaskStatus(pMeta);
|
||||
tqStreamTaskResetStatus(pMeta);
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqInfo("vgId:%d restart all stream tasks after all tasks being updated", vgId);
|
||||
|
||||
startStreamTasks(pMeta);
|
||||
streamMetaStartAllTasks(pMeta);
|
||||
} else {
|
||||
streamMetaResetStartInfo(&pMeta->startInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
@ -784,11 +679,14 @@ int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLead
|
|||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
if (taskId == STREAM_EXEC_START_ALL_TASKS_ID) {
|
||||
startStreamTasks(pMeta);
|
||||
streamMetaStartAllTasks(pMeta);
|
||||
return 0;
|
||||
} else if (taskId == STREAM_EXEC_RESTART_ALL_TASKS_ID) {
|
||||
restartStreamTasks(pMeta, isLeader);
|
||||
return 0;
|
||||
} else if (taskId == STREAM_EXEC_STOP_ALL_TASKS_ID) {
|
||||
streamMetaStopAllTasks(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, taskId);
|
||||
|
@ -812,3 +710,46 @@ int32_t tqStreamTaskProcessRunReq(SStreamMeta* pMeta, SRpcMsg* pMsg, bool isLead
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tqStartTaskCompleteCallback(SStreamMeta* pMeta) {
|
||||
STaskStartInfo* pStartInfo = &pMeta->startInfo;
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
if (pStartInfo->restartCount > 0) {
|
||||
pStartInfo->restartCount -= 1;
|
||||
|
||||
ASSERT(pStartInfo->taskStarting == 0);
|
||||
tqDebug("vgId:%d role:%d need to restart all tasks again, restartCounter:%d", pMeta->vgId, pMeta->role,
|
||||
pStartInfo->restartCount);
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
restartStreamTasks(pMeta, (pMeta->role == NODE_ROLE_LEADER));
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqDebug("vgId:%d start all tasks completed", pMeta->vgId);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tqStreamTaskProcessTaskResetReq(SStreamMeta* pMeta, SRpcMsg* pMsg) {
|
||||
SVPauseStreamTaskReq* pReq = (SVPauseStreamTaskReq*)pMsg->pCont;
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pReq->streamId, pReq->taskId);
|
||||
if (pTask == NULL) {
|
||||
tqError("vgId:%d process task-reset req, failed to acquire task:0x%x, it may have been dropped already",
|
||||
pMeta->vgId, pReq->taskId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tqDebug("s-task:%s receive task-reset msg from mnode, reset status and ready for data processing", pTask->id.idStr);
|
||||
|
||||
// clear flag set during do checkpoint, and open inputQ for all upstream tasks
|
||||
if (streamTaskGetStatus(pTask, NULL) == TASK_STATUS__CK) {
|
||||
streamTaskClearCheckInfo(pTask, true);
|
||||
streamTaskSetStatusReady(pTask);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
|
@ -1183,8 +1183,10 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
LRUHandle *h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[i], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
if (pLastCol->dirty && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) {
|
||||
if (pLastCol->dirty) {
|
||||
pLastCol->dirty = 0;
|
||||
}
|
||||
if (pLastCol->ts <= eKey && pLastCol->ts >= sKey) {
|
||||
erase = true;
|
||||
}
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
|
@ -1197,8 +1199,10 @@ int32_t tsdbCacheDel(STsdb *pTsdb, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKE
|
|||
h = taosLRUCacheLookup(pTsdb->lruCache, keys_list[num_keys + i], klen);
|
||||
if (h) {
|
||||
SLastCol *pLastCol = (SLastCol *)taosLRUCacheValue(pTsdb->lruCache, h);
|
||||
if (pLastCol->dirty && (pLastCol->ts <= eKey && pLastCol->ts >= sKey)) {
|
||||
if (pLastCol->dirty) {
|
||||
pLastCol->dirty = 0;
|
||||
}
|
||||
if (pLastCol->ts <= eKey && pLastCol->ts >= sKey) {
|
||||
erase = true;
|
||||
}
|
||||
taosLRUCacheRelease(pTsdb->lruCache, h, erase);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -702,7 +702,7 @@ _exit:
|
|||
}
|
||||
|
||||
// EXPOSED APIS ====================================================================================
|
||||
int32_t tsdbFSCommit(STsdb *pTsdb) {
|
||||
static int32_t tsdbFSCommit(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
STsdbFS fs = {0};
|
||||
|
@ -738,7 +738,7 @@ _exit:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSRollback(STsdb *pTsdb) {
|
||||
static int32_t tsdbFSRollback(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
|
@ -833,312 +833,3 @@ int32_t tsdbFSClose(STsdb *pTsdb) {
|
|||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSCopy(STsdb *pTsdb, STsdbFS *pFS) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
|
||||
pFS->pDelFile = NULL;
|
||||
if (pFS->aDFileSet) {
|
||||
taosArrayClear(pFS->aDFileSet);
|
||||
} else {
|
||||
pFS->aDFileSet = taosArrayInit(taosArrayGetSize(pTsdb->fs.aDFileSet), sizeof(SDFileSet));
|
||||
if (pFS->aDFileSet == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
||||
if (pTsdb->fs.pDelFile) {
|
||||
pFS->pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
|
||||
if (pFS->pDelFile == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
|
||||
*pFS->pDelFile = *pTsdb->fs.pDelFile;
|
||||
}
|
||||
|
||||
for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
|
||||
SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
|
||||
SDFileSet fSet = {.diskId = pSet->diskId, .fid = pSet->fid};
|
||||
|
||||
// head
|
||||
fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
|
||||
if (fSet.pHeadF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
*fSet.pHeadF = *pSet->pHeadF;
|
||||
|
||||
// data
|
||||
fSet.pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
|
||||
if (fSet.pDataF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
*fSet.pDataF = *pSet->pDataF;
|
||||
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
*fSet.pSmaF = *pSet->pSmaF;
|
||||
|
||||
// stt
|
||||
for (fSet.nSttF = 0; fSet.nSttF < pSet->nSttF; fSet.nSttF++) {
|
||||
fSet.aSttF[fSet.nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (fSet.aSttF[fSet.nSttF] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
*fSet.aSttF[fSet.nSttF] = *pSet->aSttF[fSet.nSttF];
|
||||
}
|
||||
|
||||
if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSUpsertDelFile(STsdbFS *pFS, SDelFile *pDelFile) {
|
||||
int32_t code = 0;
|
||||
|
||||
if (pDelFile) {
|
||||
if (pFS->pDelFile == NULL) {
|
||||
pFS->pDelFile = (SDelFile *)taosMemoryMalloc(sizeof(SDelFile));
|
||||
if (pFS->pDelFile == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
*pFS->pDelFile = *pDelFile;
|
||||
} else {
|
||||
if (pFS->pDelFile) {
|
||||
taosMemoryFree(pFS->pDelFile);
|
||||
pFS->pDelFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSUpsertFSet(STsdbFS *pFS, SDFileSet *pSet) {
|
||||
int32_t code = 0;
|
||||
int32_t idx = taosArraySearchIdx(pFS->aDFileSet, pSet, tDFileSetCmprFn, TD_GE);
|
||||
|
||||
if (idx < 0) {
|
||||
idx = taosArrayGetSize(pFS->aDFileSet);
|
||||
} else {
|
||||
SDFileSet *pDFileSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, idx);
|
||||
int32_t c = tDFileSetCmprFn(pSet, pDFileSet);
|
||||
if (c == 0) {
|
||||
*pDFileSet->pHeadF = *pSet->pHeadF;
|
||||
*pDFileSet->pDataF = *pSet->pDataF;
|
||||
*pDFileSet->pSmaF = *pSet->pSmaF;
|
||||
// stt
|
||||
if (pSet->nSttF > pDFileSet->nSttF) {
|
||||
ASSERT(pSet->nSttF == pDFileSet->nSttF + 1);
|
||||
|
||||
pDFileSet->aSttF[pDFileSet->nSttF] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (pDFileSet->aSttF[pDFileSet->nSttF] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*pDFileSet->aSttF[pDFileSet->nSttF] = *pSet->aSttF[pSet->nSttF - 1];
|
||||
pDFileSet->nSttF++;
|
||||
} else if (pSet->nSttF < pDFileSet->nSttF) {
|
||||
ASSERT(pSet->nSttF == 1);
|
||||
for (int32_t iStt = 1; iStt < pDFileSet->nSttF; iStt++) {
|
||||
taosMemoryFree(pDFileSet->aSttF[iStt]);
|
||||
}
|
||||
|
||||
*pDFileSet->aSttF[0] = *pSet->aSttF[0];
|
||||
pDFileSet->nSttF = 1;
|
||||
} else {
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
*pDFileSet->aSttF[iStt] = *pSet->aSttF[iStt];
|
||||
}
|
||||
}
|
||||
|
||||
pDFileSet->diskId = pSet->diskId;
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(pSet->nSttF == 1);
|
||||
SDFileSet fSet = {.diskId = pSet->diskId, .fid = pSet->fid, .nSttF = 1};
|
||||
|
||||
// head
|
||||
fSet.pHeadF = (SHeadFile *)taosMemoryMalloc(sizeof(SHeadFile));
|
||||
if (fSet.pHeadF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.pHeadF = *pSet->pHeadF;
|
||||
|
||||
// data
|
||||
fSet.pDataF = (SDataFile *)taosMemoryMalloc(sizeof(SDataFile));
|
||||
if (fSet.pDataF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.pDataF = *pSet->pDataF;
|
||||
|
||||
// sma
|
||||
fSet.pSmaF = (SSmaFile *)taosMemoryMalloc(sizeof(SSmaFile));
|
||||
if (fSet.pSmaF == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.pSmaF = *pSet->pSmaF;
|
||||
|
||||
// stt
|
||||
fSet.aSttF[0] = (SSttFile *)taosMemoryMalloc(sizeof(SSttFile));
|
||||
if (fSet.aSttF[0] == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
*fSet.aSttF[0] = *pSet->aSttF[0];
|
||||
|
||||
if (taosArrayInsert(pFS->aDFileSet, idx, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSPrepareCommit(STsdb *pTsdb, STsdbFS *pFSNew) {
|
||||
int32_t code = 0;
|
||||
int32_t lino = 0;
|
||||
char tfname[TSDB_FILENAME_LEN];
|
||||
|
||||
tsdbGetCurrentFName(pTsdb, NULL, tfname);
|
||||
|
||||
// gnrt CURRENT.t
|
||||
code = tsdbSaveFSToFile(pFSNew, tfname);
|
||||
TSDB_CHECK_CODE(code, lino, _exit);
|
||||
|
||||
_exit:
|
||||
if (code) {
|
||||
tsdbError("vgId:%d, %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbFSRef(STsdb *pTsdb, STsdbFS *pFS) {
|
||||
int32_t code = 0;
|
||||
int32_t nRef;
|
||||
|
||||
pFS->aDFileSet = taosArrayInit(taosArrayGetSize(pTsdb->fs.aDFileSet), sizeof(SDFileSet));
|
||||
if (pFS->aDFileSet == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
pFS->pDelFile = pTsdb->fs.pDelFile;
|
||||
if (pFS->pDelFile) {
|
||||
nRef = atomic_fetch_add_32(&pFS->pDelFile->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
}
|
||||
|
||||
SDFileSet fSet;
|
||||
for (int32_t iSet = 0; iSet < taosArrayGetSize(pTsdb->fs.aDFileSet); iSet++) {
|
||||
SDFileSet *pSet = (SDFileSet *)taosArrayGet(pTsdb->fs.aDFileSet, iSet);
|
||||
fSet = *pSet;
|
||||
|
||||
nRef = atomic_fetch_add_32(&pSet->pHeadF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
nRef = atomic_fetch_add_32(&pSet->pDataF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
nRef = atomic_fetch_add_32(&pSet->pSmaF->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
nRef = atomic_fetch_add_32(&pSet->aSttF[iStt]->nRef, 1);
|
||||
ASSERT(nRef > 0);
|
||||
}
|
||||
|
||||
if (taosArrayPush(pFS->aDFileSet, &fSet) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
void tsdbFSUnref(STsdb *pTsdb, STsdbFS *pFS) {
|
||||
int32_t nRef;
|
||||
char fname[TSDB_FILENAME_LEN];
|
||||
|
||||
if (pFS->pDelFile) {
|
||||
nRef = atomic_sub_fetch_32(&pFS->pDelFile->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbDelFileName(pTsdb, pFS->pDelFile, fname);
|
||||
(void)taosRemoveFile(fname);
|
||||
taosMemoryFree(pFS->pDelFile);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t iSet = 0; iSet < taosArrayGetSize(pFS->aDFileSet); iSet++) {
|
||||
SDFileSet *pSet = (SDFileSet *)taosArrayGet(pFS->aDFileSet, iSet);
|
||||
|
||||
// head
|
||||
nRef = atomic_sub_fetch_32(&pSet->pHeadF->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbHeadFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pHeadF, fname);
|
||||
(void)taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->pHeadF);
|
||||
}
|
||||
|
||||
// data
|
||||
nRef = atomic_sub_fetch_32(&pSet->pDataF->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbDataFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pDataF, fname);
|
||||
(void)taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->pDataF);
|
||||
}
|
||||
|
||||
// sma
|
||||
nRef = atomic_sub_fetch_32(&pSet->pSmaF->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbSmaFileName(pTsdb, pSet->diskId, pSet->fid, pSet->pSmaF, fname);
|
||||
(void)taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->pSmaF);
|
||||
}
|
||||
|
||||
// stt
|
||||
for (int32_t iStt = 0; iStt < pSet->nSttF; iStt++) {
|
||||
nRef = atomic_sub_fetch_32(&pSet->aSttF[iStt]->nRef, 1);
|
||||
ASSERT(nRef >= 0);
|
||||
if (nRef == 0) {
|
||||
tsdbSttFileName(pTsdb, pSet->diskId, pSet->fid, pSet->aSttF[iStt], fname);
|
||||
(void)taosRemoveFile(fname);
|
||||
taosMemoryFree(pSet->aSttF[iStt]);
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayDestroy(pFS->aDFileSet);
|
||||
}
|
||||
|
|
|
@ -805,6 +805,12 @@ int64_t tsdbFSAllocEid(STFileSystem *fs) {
|
|||
return cid;
|
||||
}
|
||||
|
||||
void tsdbFSUpdateEid(STFileSystem *fs, int64_t cid) {
|
||||
taosThreadMutexLock(&fs->tsdb->mutex);
|
||||
fs->neid = TMAX(fs->neid, cid);
|
||||
taosThreadMutexUnlock(&fs->tsdb->mutex);
|
||||
}
|
||||
|
||||
int32_t tsdbFSEditBegin(STFileSystem *fs, const TFileOpArray *opArray, EFEditT etype) {
|
||||
int32_t code = 0;
|
||||
int32_t lino;
|
||||
|
|
|
@ -52,6 +52,7 @@ int32_t tsdbFSCreateRefRangedSnapshot(STFileSystem *fs, int64_t sver, int64_t ev
|
|||
int32_t tsdbFSDestroyRefRangedSnapshot(TFileSetRangeArray **fsrArr);
|
||||
// txn
|
||||
int64_t tsdbFSAllocEid(STFileSystem *fs);
|
||||
void tsdbFSUpdateEid(STFileSystem *fs, int64_t cid);
|
||||
int32_t tsdbFSEditBegin(STFileSystem *fs, const TFileOpArray *opArray, EFEditT etype);
|
||||
int32_t tsdbFSEditCommit(STFileSystem *fs);
|
||||
int32_t tsdbFSEditAbort(STFileSystem *fs);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "tsdbFSetRAW.h"
|
||||
#include "tsdbFS2.h"
|
||||
|
||||
// SFSetRAWWriter ==================================================
|
||||
typedef struct SFSetRAWWriter {
|
||||
|
@ -76,7 +77,7 @@ static int32_t tsdbFSetRAWWriteFileDataBegin(SFSetRAWWriter *writer, STsdbDataRA
|
|||
.szPage = writer->config->szPage,
|
||||
.fid = bHdr->file.fid,
|
||||
.did = writer->config->did,
|
||||
.cid = writer->config->cid,
|
||||
.cid = bHdr->file.cid,
|
||||
.level = writer->config->level,
|
||||
|
||||
.file =
|
||||
|
@ -84,7 +85,7 @@ static int32_t tsdbFSetRAWWriteFileDataBegin(SFSetRAWWriter *writer, STsdbDataRA
|
|||
.type = bHdr->file.type,
|
||||
.fid = bHdr->file.fid,
|
||||
.did = writer->config->did,
|
||||
.cid = writer->config->cid,
|
||||
.cid = bHdr->file.cid,
|
||||
.size = bHdr->file.size,
|
||||
.minVer = bHdr->file.minVer,
|
||||
.maxVer = bHdr->file.maxVer,
|
||||
|
@ -94,6 +95,7 @@ static int32_t tsdbFSetRAWWriteFileDataBegin(SFSetRAWWriter *writer, STsdbDataRA
|
|||
},
|
||||
};
|
||||
|
||||
tsdbFSUpdateEid(config.tsdb->pFS, config.cid);
|
||||
writer->ctx->offset = 0;
|
||||
writer->ctx->file = config.file;
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include "tsdbUtil2.h"
|
||||
#include "tsimplehash.h"
|
||||
|
||||
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
|
||||
#define getCurrentKeyInSttBlock(_r) ((_r)->currentKey)
|
||||
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
|
||||
#define getCurrentKeyInSttBlock(_r) ((_r)->currentKey)
|
||||
|
||||
typedef struct {
|
||||
bool overlapWithNeighborBlock;
|
||||
|
@ -41,7 +41,7 @@ static int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, i
|
|||
static TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* pReader);
|
||||
static int32_t doMergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
|
||||
static int32_t doMergeRowsInSttBlock(SSttBlockReader* pSttBlockReader, STableBlockScanInfo* pScanInfo, int64_t ts,
|
||||
SRowMerger* pMerger, SVersionRange* pVerRange, const char* id);
|
||||
SRowMerger* pMerger, SVersionRange* pVerRange, const char* id);
|
||||
static int32_t doMergeRowsInBuf(SIterInfo* pIter, uint64_t uid, int64_t ts, SArray* pDelList, STsdbReader* pReader);
|
||||
static int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, SRow* pTSRow,
|
||||
STableBlockScanInfo* pScanInfo);
|
||||
|
@ -67,7 +67,7 @@ static SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond
|
|||
static int32_t doBuildDataBlock(STsdbReader* pReader);
|
||||
static TSDBKEY getCurrentKeyInBuf(STableBlockScanInfo* pScanInfo, STsdbReader* pReader);
|
||||
static bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo* pDumpInfo);
|
||||
static bool hasDataInSttBlock(STableBlockScanInfo *pInfo);
|
||||
static bool hasDataInSttBlock(STableBlockScanInfo* pInfo);
|
||||
static void initBlockDumpInfo(STsdbReader* pReader, SDataBlockIter* pBlockIter);
|
||||
static int32_t getInitialDelIndex(const SArray* pDelSkyline, int32_t order);
|
||||
static void resetTableListIndex(SReaderStatus* pStatus);
|
||||
|
@ -120,7 +120,7 @@ static int32_t updateBlockSMAInfo(STSchema* pSchema, SBlockLoadSuppInfo* pSupInf
|
|||
} else if (pTCol->colId < pSupInfo->colId[j]) { // do nothing
|
||||
i += 1;
|
||||
} else {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
return TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1138,7 +1138,7 @@ static bool getNeighborBlockOfSameTable(SDataBlockIter* pBlockIter, SFileDataBlo
|
|||
return false;
|
||||
}
|
||||
|
||||
int32_t step = asc ? 1 : -1;
|
||||
int32_t step = asc ? 1 : -1;
|
||||
STableDataBlockIdx* pTableDataBlockIdx =
|
||||
taosArrayGet(pTableBlockScanInfo->pBlockIdxList, pBlockInfo->tbBlockIdx + step);
|
||||
SFileDataBlockInfo* p = taosArrayGet(pBlockIter->blockList, pTableDataBlockIdx->globalIndex);
|
||||
|
@ -1316,17 +1316,17 @@ static int32_t buildDataBlockFromBuf(STsdbReader* pReader, STableBlockScanInfo*
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
int64_t st = taosGetTimestampUs();
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
int32_t code = buildDataBlockFromBufImpl(pBlockScanInfo, endKey, pReader->resBlockInfo.capacity, pReader);
|
||||
int32_t code = buildDataBlockFromBufImpl(pBlockScanInfo, endKey, pReader->resBlockInfo.capacity, pReader);
|
||||
|
||||
double el = (taosGetTimestampUs() - st) / 1000.0;
|
||||
updateComposedBlockInfo(pReader, el, pBlockScanInfo);
|
||||
|
||||
tsdbDebug("%p build data block from cache completed, elapsed time:%.2f ms, numOfRows:%" PRId64 ", brange:%" PRId64
|
||||
" - %" PRId64 ", uid:%" PRIu64 ", %s",
|
||||
pReader, el, pBlock->info.rows, pBlock->info.window.skey, pBlock->info.window.ekey,
|
||||
pBlockScanInfo->uid, pReader->idStr);
|
||||
pReader, el, pBlock->info.rows, pBlock->info.window.skey, pBlock->info.window.ekey, pBlockScanInfo->uid,
|
||||
pReader->idStr);
|
||||
|
||||
pReader->cost.buildmemBlock += el;
|
||||
return code;
|
||||
|
@ -1360,7 +1360,8 @@ static bool tryCopyDistinctRowFromFileBlock(STsdbReader* pReader, SBlockData* pB
|
|||
|
||||
static bool nextRowFromSttBlocks(SSttBlockReader* pSttBlockReader, STableBlockScanInfo* pScanInfo,
|
||||
SVersionRange* pVerRange) {
|
||||
int32_t step = ASCENDING_TRAVERSE(pSttBlockReader->order) ? 1 : -1;
|
||||
int32_t order = pSttBlockReader->order;
|
||||
int32_t step = ASCENDING_TRAVERSE(order) ? 1 : -1;
|
||||
|
||||
while (1) {
|
||||
bool hasVal = tMergeTreeNext(&pSttBlockReader->mergeTree);
|
||||
|
@ -1377,21 +1378,21 @@ static bool nextRowFromSttBlocks(SSttBlockReader* pSttBlockReader, STableBlockSc
|
|||
pSttBlockReader->currentKey = key;
|
||||
pScanInfo->sttKeyInfo.nextProcKey = key;
|
||||
|
||||
if (!hasBeenDropped(pScanInfo->delSkyline, &pScanInfo->sttBlockDelIndex, key, ver, pSttBlockReader->order,
|
||||
pVerRange)) {
|
||||
if (pScanInfo->delSkyline != NULL && TARRAY_SIZE(pScanInfo->delSkyline) > 0) {
|
||||
if (!hasBeenDropped(pScanInfo->delSkyline, &pScanInfo->sttBlockDelIndex, key, ver, order, pVerRange)) {
|
||||
pScanInfo->sttKeyInfo.status = STT_FILE_HAS_DATA;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
pScanInfo->sttKeyInfo.status = STT_FILE_HAS_DATA;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void doPinSttBlock(SSttBlockReader* pSttBlockReader) {
|
||||
tMergeTreePinSttBlock(&pSttBlockReader->mergeTree);
|
||||
}
|
||||
static void doPinSttBlock(SSttBlockReader* pSttBlockReader) { tMergeTreePinSttBlock(&pSttBlockReader->mergeTree); }
|
||||
|
||||
static void doUnpinSttBlock(SSttBlockReader* pSttBlockReader) {
|
||||
tMergeTreeUnpinSttBlock(&pSttBlockReader->mergeTree);
|
||||
}
|
||||
static void doUnpinSttBlock(SSttBlockReader* pSttBlockReader) { tMergeTreeUnpinSttBlock(&pSttBlockReader->mergeTree); }
|
||||
|
||||
static bool tryCopyDistinctRowFromSttBlock(TSDBROW* fRow, SSttBlockReader* pSttBlockReader,
|
||||
STableBlockScanInfo* pScanInfo, int64_t ts, STsdbReader* pReader,
|
||||
|
@ -1530,8 +1531,7 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange, pReader->idStr);
|
||||
}
|
||||
|
||||
if (minKey == k.ts) {
|
||||
|
@ -1580,8 +1580,7 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange, pReader->idStr);
|
||||
}
|
||||
|
||||
if (minKey == key) {
|
||||
|
@ -1643,7 +1642,7 @@ static int32_t doMergeFileBlockAndLastBlock(SSttBlockReader* pSttBlockReader, ST
|
|||
TSDBROW* pRow1 = tMergeTreeGetRow(&pSttBlockReader->mergeTree);
|
||||
tsdbRowMergerAdd(pMerger, pRow1, NULL);
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLastBlock, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
pReader->idStr);
|
||||
|
||||
code = tsdbRowMergerGetRow(pMerger, &pTSRow);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1666,7 +1665,7 @@ static int32_t doMergeFileBlockAndLastBlock(SSttBlockReader* pSttBlockReader, ST
|
|||
}
|
||||
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLastBlock, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
pReader->idStr);
|
||||
|
||||
// merge with block data if ts == key
|
||||
if (tsLastBlock == pBlockData->aTSKEY[pDumpInfo->rowIndex]) {
|
||||
|
@ -1714,6 +1713,9 @@ static int32_t mergeFileBlockAndSttBlock(STsdbReader* pReader, SSttBlockReader*
|
|||
} else if ((!dataInDataFile) && dataInSttFile) {
|
||||
// no data ile block exists
|
||||
return mergeRowsInSttBlocks(pSttBlockReader, pBlockScanInfo, pReader);
|
||||
} else if (pBlockScanInfo->cleanSttBlocks && pReader->info.execMode == READER_EXEC_ROWS) {
|
||||
// opt model for count data in stt file, which is not overlap with data blocks in files.
|
||||
return mergeRowsInFileBlocks(pBlockData, pBlockScanInfo, key, pReader);
|
||||
} else {
|
||||
// row in both stt file blocks and data file blocks
|
||||
TSDBROW fRow = tsdbRowFromBlockData(pBlockData, pDumpInfo->rowIndex);
|
||||
|
@ -1735,7 +1737,7 @@ static int32_t mergeFileBlockAndSttBlock(STsdbReader* pReader, SSttBlockReader*
|
|||
// the following for key == tsLast
|
||||
// ASC: file block ------> stt block
|
||||
// DESC: stt block ------> file block
|
||||
SRow* pTSRow = NULL;
|
||||
SRow* pTSRow = NULL;
|
||||
if (ASCENDING_TRAVERSE(pReader->info.order)) {
|
||||
code = tsdbRowMergerAdd(pMerger, &fRow, NULL);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1884,8 +1886,7 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
return code;
|
||||
}
|
||||
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange, pReader->idStr);
|
||||
}
|
||||
|
||||
if (minKey == ik.ts) {
|
||||
|
@ -1943,8 +1944,7 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
return code;
|
||||
}
|
||||
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange,
|
||||
pReader->idStr);
|
||||
doMergeRowsInSttBlock(pSttBlockReader, pBlockScanInfo, tsLast, pMerger, &pReader->info.verRange, pReader->idStr);
|
||||
}
|
||||
|
||||
if (minKey == key) {
|
||||
|
@ -2054,9 +2054,12 @@ static bool isValidFileBlockRow(SBlockData* pBlockData, SFileBlockDumpInfo* pDum
|
|||
return false;
|
||||
}
|
||||
|
||||
if (hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->fileDelIndex, ts, ver, pReader->info.order,
|
||||
&pReader->info.verRange)) {
|
||||
return false;
|
||||
if (pBlockScanInfo->delSkyline != NULL && TARRAY_SIZE(pBlockScanInfo->delSkyline) > 0) {
|
||||
bool dropped = hasBeenDropped(pBlockScanInfo->delSkyline, &pBlockScanInfo->fileDelIndex, ts, ver,
|
||||
pReader->info.order, &pReader->info.verRange);
|
||||
if (dropped) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2112,7 +2115,7 @@ static bool initSttBlockReader(SSttBlockReader* pSttBlockReader, STableBlockScan
|
|||
};
|
||||
|
||||
SSttDataInfoForTable info = {.pTimeWindowList = taosArrayInit(4, sizeof(STimeWindow))};
|
||||
int32_t code = tMergeTreeOpen2(&pSttBlockReader->mergeTree, &conf, &info);
|
||||
int32_t code = tMergeTreeOpen2(&pSttBlockReader->mergeTree, &conf, &info);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2130,7 +2133,7 @@ static bool initSttBlockReader(SSttBlockReader* pSttBlockReader, STableBlockScan
|
|||
pScanInfo->sttWindow.ekey = INT64_MIN;
|
||||
|
||||
// calculate the time window for data in stt files
|
||||
for(int32_t i = 0; i < taosArrayGetSize(info.pTimeWindowList); ++i) {
|
||||
for (int32_t i = 0; i < taosArrayGetSize(info.pTimeWindowList); ++i) {
|
||||
STimeWindow* pWindow = taosArrayGet(info.pTimeWindowList, i);
|
||||
if (pScanInfo->sttWindow.skey > pWindow->skey) {
|
||||
pScanInfo->sttWindow.skey = pWindow->skey;
|
||||
|
@ -2141,8 +2144,9 @@ static bool initSttBlockReader(SSttBlockReader* pSttBlockReader, STableBlockScan
|
|||
}
|
||||
}
|
||||
|
||||
pScanInfo->sttKeyInfo.status = taosArrayGetSize(info.pTimeWindowList)? STT_FILE_HAS_DATA:STT_FILE_NO_DATA;
|
||||
pScanInfo->sttKeyInfo.nextProcKey = ASCENDING_TRAVERSE(pReader->info.order)? pScanInfo->sttWindow.skey:pScanInfo->sttWindow.ekey;
|
||||
pScanInfo->sttKeyInfo.status = taosArrayGetSize(info.pTimeWindowList) ? STT_FILE_HAS_DATA : STT_FILE_NO_DATA;
|
||||
pScanInfo->sttKeyInfo.nextProcKey =
|
||||
ASCENDING_TRAVERSE(pReader->info.order) ? pScanInfo->sttWindow.skey : pScanInfo->sttWindow.ekey;
|
||||
hasData = true;
|
||||
} else {
|
||||
hasData = nextRowFromSttBlocks(pSttBlockReader, pScanInfo, &pReader->info.verRange);
|
||||
|
@ -2160,9 +2164,7 @@ static bool initSttBlockReader(SSttBlockReader* pSttBlockReader, STableBlockScan
|
|||
return hasData;
|
||||
}
|
||||
|
||||
static bool hasDataInSttBlock(STableBlockScanInfo *pInfo) {
|
||||
return pInfo->sttKeyInfo.status == STT_FILE_HAS_DATA;
|
||||
}
|
||||
static bool hasDataInSttBlock(STableBlockScanInfo* pInfo) { return pInfo->sttKeyInfo.status == STT_FILE_HAS_DATA; }
|
||||
|
||||
bool hasDataInFileBlock(const SBlockData* pBlockData, const SFileBlockDumpInfo* pDumpInfo) {
|
||||
if ((pBlockData->nRow > 0) && (pBlockData->nRow != pDumpInfo->totalRows)) {
|
||||
|
@ -2217,10 +2219,11 @@ int32_t mergeRowsInFileBlocks(SBlockData* pBlockData, STableBlockScanInfo* pBloc
|
|||
}
|
||||
}
|
||||
|
||||
int32_t mergeRowsInSttBlocks(SSttBlockReader* pSttBlockReader, STableBlockScanInfo* pBlockScanInfo, STsdbReader* pReader) {
|
||||
bool copied = false;
|
||||
SRow* pTSRow = NULL;
|
||||
int64_t tsLastBlock = getCurrentKeyInSttBlock(pSttBlockReader);
|
||||
int32_t mergeRowsInSttBlocks(SSttBlockReader* pSttBlockReader, STableBlockScanInfo* pBlockScanInfo,
|
||||
STsdbReader* pReader) {
|
||||
bool copied = false;
|
||||
SRow* pTSRow = NULL;
|
||||
int64_t tsLastBlock = getCurrentKeyInSttBlock(pSttBlockReader);
|
||||
|
||||
SRowMerger* pMerger = &pReader->status.merger;
|
||||
TSDBROW* pRow = tMergeTreeGetRow(&pSttBlockReader->mergeTree);
|
||||
|
@ -2551,16 +2554,16 @@ static void prepareDurationForNextFileSet(STsdbReader* pReader) {
|
|||
pReader->status.bProcMemFirstFileset = false;
|
||||
}
|
||||
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
STimeWindow winFid = {0};
|
||||
tsdbFidKeyRange(fid, pReader->pTsdb->keepCfg.days, pReader->pTsdb->keepCfg.precision, &winFid.skey, &winFid.ekey);
|
||||
|
||||
if (ASCENDING_TRAVERSE(pReader->info.order)) {
|
||||
pReader->status.bProcMemPreFileset = !(pReader->status.memTableMaxKey < pReader->status.prevFilesetStartKey ||
|
||||
(winFid.skey-1) < pReader->status.memTableMinKey);
|
||||
(winFid.skey - 1) < pReader->status.memTableMinKey);
|
||||
} else {
|
||||
pReader->status.bProcMemPreFileset = !( pReader->status.memTableMaxKey < (winFid.ekey+1) ||
|
||||
pReader->status.prevFilesetEndKey < pReader->status.memTableMinKey);
|
||||
pReader->status.bProcMemPreFileset = !(pReader->status.memTableMaxKey < (winFid.ekey + 1) ||
|
||||
pReader->status.prevFilesetEndKey < pReader->status.memTableMinKey);
|
||||
}
|
||||
|
||||
if (pReader->status.bProcMemPreFileset) {
|
||||
|
@ -2794,7 +2797,7 @@ static int32_t doLoadSttBlockSequentially(STsdbReader* pReader) {
|
|||
static bool notOverlapWithSttFiles(SFileDataBlockInfo* pBlockInfo, STableBlockScanInfo* pScanInfo, bool asc) {
|
||||
ASSERT(pScanInfo->sttKeyInfo.status != STT_FILE_READER_UNINIT);
|
||||
|
||||
if(pScanInfo->sttKeyInfo.status == STT_FILE_NO_DATA) {
|
||||
if (pScanInfo->sttKeyInfo.status == STT_FILE_NO_DATA) {
|
||||
return true;
|
||||
} else {
|
||||
int64_t keyInStt = pScanInfo->sttKeyInfo.nextProcKey;
|
||||
|
@ -2915,7 +2918,8 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
static int32_t buildBlockFromBufferSeqForPreFileset(STsdbReader* pReader, int64_t endKey) {
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
|
||||
tsdbDebug("seq load data blocks from cache that preceeds fileset %d, %s", pReader->status.pCurrentFileset->fid, pReader->idStr);
|
||||
tsdbDebug("seq load data blocks from cache that preceeds fileset %d, %s", pReader->status.pCurrentFileset->fid,
|
||||
pReader->idStr);
|
||||
|
||||
while (1) {
|
||||
if (pReader->code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -3219,7 +3223,7 @@ SVersionRange getQueryVerRange(SVnode* pVnode, SQueryTableDataCond* pCond, int8_
|
|||
|
||||
bool hasBeenDropped(const SArray* pDelList, int32_t* index, int64_t key, int64_t ver, int32_t order,
|
||||
SVersionRange* pVerRange) {
|
||||
if (pDelList == NULL || (taosArrayGetSize(pDelList) == 0)) {
|
||||
if (pDelList == NULL || (TARRAY_SIZE(pDelList) == 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3327,16 +3331,22 @@ TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* p
|
|||
|
||||
TSDBROW* pRow = tsdbTbDataIterGet(pIter->iter);
|
||||
TSDBKEY key = TSDBROW_KEY(pRow);
|
||||
|
||||
int32_t order = pReader->info.order;
|
||||
if (outOfTimeWindow(key.ts, &pReader->info.window)) {
|
||||
pIter->hasVal = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// it is a valid data version
|
||||
if ((key.version <= pReader->info.verRange.maxVer && key.version >= pReader->info.verRange.minVer) &&
|
||||
(!hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, pReader->info.order, &pReader->info.verRange))) {
|
||||
return pRow;
|
||||
if (key.version <= pReader->info.verRange.maxVer && key.version >= pReader->info.verRange.minVer) {
|
||||
if (pDelList == NULL || TARRAY_SIZE(pDelList) == 0) {
|
||||
return pRow;
|
||||
} else {
|
||||
bool dropped = hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, order, &pReader->info.verRange);
|
||||
if (!dropped) {
|
||||
return pRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
@ -3353,9 +3363,15 @@ TSDBROW* getValidMemRow(SIterInfo* pIter, const SArray* pDelList, STsdbReader* p
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (key.version <= pReader->info.verRange.maxVer && key.version >= pReader->info.verRange.minVer &&
|
||||
(!hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, pReader->info.order, &pReader->info.verRange))) {
|
||||
return pRow;
|
||||
if (key.version <= pReader->info.verRange.maxVer && key.version >= pReader->info.verRange.minVer) {
|
||||
if (pDelList == NULL || TARRAY_SIZE(pDelList) == 0) {
|
||||
return pRow;
|
||||
} else {
|
||||
bool dropped = hasBeenDropped(pDelList, &pIter->index, key.ts, key.version, order, &pReader->info.verRange);
|
||||
if (!dropped) {
|
||||
return pRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3827,7 +3843,6 @@ int32_t buildDataBlockFromBufImpl(STableBlockScanInfo* pBlockScanInfo, int64_t e
|
|||
pBlockScanInfo->lastProcKey = row.pBlockData->aTSKEY[row.iRow];
|
||||
}
|
||||
|
||||
|
||||
// no data in buffer, return immediately
|
||||
if (!(pBlockScanInfo->iter.hasVal || pBlockScanInfo->iiter.hasVal)) {
|
||||
break;
|
||||
|
@ -3925,7 +3940,7 @@ static int32_t doOpenReaderImpl(STsdbReader* pReader) {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pStatus->fileIter.numOfFiles == 0) {
|
||||
pStatus->loadFromFile = false;
|
||||
// } else if (READER_EXEC_DATA == pReader->info.readMode) {
|
||||
// } else if (READER_EXEC_DATA == pReader->info.readMode) {
|
||||
// DO NOTHING
|
||||
} else {
|
||||
code = initForFirstBlockInFile(pReader, pBlockIter);
|
||||
|
@ -4072,7 +4087,7 @@ int32_t tsdbReaderOpen2(void* pVnode, SQueryTableDataCond* pCond, void* pTableLi
|
|||
}
|
||||
|
||||
pReader->flag = READER_STATUS_SUSPEND;
|
||||
pReader->info.execMode = pCond->notLoadData? READER_EXEC_ROWS : READER_EXEC_DATA;
|
||||
pReader->info.execMode = pCond->notLoadData ? READER_EXEC_ROWS : READER_EXEC_DATA;
|
||||
|
||||
pReader->pIgnoreTables = pIgnoreTables;
|
||||
tsdbDebug("%p total numOfTable:%d, window:%" PRId64 " - %" PRId64 ", verRange:%" PRId64 " - %" PRId64
|
||||
|
@ -4137,7 +4152,7 @@ void tsdbReaderClose2(STsdbReader* pReader) {
|
|||
}
|
||||
|
||||
SReadCostSummary* pCost = &pReader->cost;
|
||||
SFilesetIter* pFilesetIter = &pReader->status.fileIter;
|
||||
SFilesetIter* pFilesetIter = &pReader->status.fileIter;
|
||||
if (pFilesetIter->pSttBlockReader != NULL) {
|
||||
SSttBlockReader* pLReader = pFilesetIter->pSttBlockReader;
|
||||
tMergeTreeClose(&pLReader->mergeTree);
|
||||
|
@ -4184,7 +4199,7 @@ int32_t tsdbReaderSuspend2(STsdbReader* pReader) {
|
|||
SReaderStatus* pStatus = &pReader->status;
|
||||
STableBlockScanInfo* pBlockScanInfo = NULL;
|
||||
|
||||
pReader->status.suspendInvoked = true; // record the suspend status
|
||||
pReader->status.suspendInvoked = true; // record the suspend status
|
||||
|
||||
if (pStatus->loadFromFile) {
|
||||
SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(&pReader->status.blockIter);
|
||||
|
@ -4207,7 +4222,7 @@ int32_t tsdbReaderSuspend2(STsdbReader* pReader) {
|
|||
// resetDataBlockScanInfo excluding lastKey
|
||||
STableBlockScanInfo** p = NULL;
|
||||
|
||||
int32_t step = ASCENDING_TRAVERSE(pReader->info.order)? 1:-1;
|
||||
int32_t step = ASCENDING_TRAVERSE(pReader->info.order) ? 1 : -1;
|
||||
|
||||
int32_t iter = 0;
|
||||
while ((p = tSimpleHashIterate(pStatus->pTableMap, p, &iter)) != NULL) {
|
||||
|
@ -4228,7 +4243,7 @@ int32_t tsdbReaderSuspend2(STsdbReader* pReader) {
|
|||
pReader->flag = READER_STATUS_SUSPEND;
|
||||
|
||||
#if SUSPEND_RESUME_TEST
|
||||
tsem_post(&pReader->resumeAfterSuspend);
|
||||
tsem_post(&pReader->resumeAfterSuspend);
|
||||
#endif
|
||||
|
||||
tsdbDebug("reader: %p suspended uid %" PRIu64 " in this query %s", pReader, pBlockScanInfo ? pBlockScanInfo->uid : 0,
|
||||
|
@ -4311,13 +4326,13 @@ _err:
|
|||
}
|
||||
|
||||
static int32_t buildFromPreFilesetBuffer(STsdbReader* pReader) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
STimeWindow win = {0};
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
STimeWindow win = {0};
|
||||
tsdbFidKeyRange(fid, pReader->pTsdb->keepCfg.days, pReader->pTsdb->keepCfg.precision, &win.skey, &win.ekey);
|
||||
|
||||
int64_t endKey = (ASCENDING_TRAVERSE(pReader->info.order)) ? win.skey : win.ekey;
|
||||
|
@ -4339,8 +4354,8 @@ static int32_t buildFromPreFilesetBuffer(STsdbReader* pReader) {
|
|||
|
||||
static int32_t doTsdbNextDataBlockFilesetDelimited(STsdbReader* pReader) {
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
|
||||
if (pStatus->loadFromFile) {
|
||||
if (pStatus->bProcMemPreFileset) {
|
||||
|
@ -4355,12 +4370,12 @@ static int32_t doTsdbNextDataBlockFilesetDelimited(STsdbReader* pReader) {
|
|||
return code;
|
||||
}
|
||||
|
||||
tsdbTrace("block from file rows: %"PRId64", will process pre-file set buffer: %d. %s",
|
||||
pBlock->info.rows, pStatus->bProcMemFirstFileset, pReader->idStr);
|
||||
tsdbTrace("block from file rows: %" PRId64 ", will process pre-file set buffer: %d. %s", pBlock->info.rows,
|
||||
pStatus->bProcMemFirstFileset, pReader->idStr);
|
||||
if (pStatus->bProcMemPreFileset) {
|
||||
if (pBlock->info.rows > 0) {
|
||||
if (pReader->notifyFn) {
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
int32_t fid = pReader->status.pCurrentFileset->fid;
|
||||
STsdReaderNotifyInfo info = {0};
|
||||
info.duration.filesetId = fid;
|
||||
pReader->notifyFn(TSD_READER_NOTIFY_NEXT_DURATION_BLOCK, &info, pReader->notifyParam);
|
||||
|
@ -4384,8 +4399,8 @@ static int32_t doTsdbNextDataBlockFilesetDelimited(STsdbReader* pReader) {
|
|||
|
||||
static int32_t doTsdbNextDataBlockFilesFirst(STsdbReader* pReader) {
|
||||
SReaderStatus* pStatus = &pReader->status;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SSDataBlock* pBlock = pReader->resBlockInfo.pResBlock;
|
||||
|
||||
if (pStatus->loadFromFile) {
|
||||
code = buildBlockFromFiles(pReader);
|
||||
|
@ -4920,7 +4935,7 @@ static void getMemTableTimeRange(STsdbReader* pReader, int64_t* pMaxKey, int64_t
|
|||
int64_t minKey = INT64_MAX;
|
||||
|
||||
void* pHashIter = tSimpleHashIterate(pStatus->pTableMap, NULL, &iter);
|
||||
while (pHashIter!= NULL) {
|
||||
while (pHashIter != NULL) {
|
||||
STableBlockScanInfo* pBlockScanInfo = *(STableBlockScanInfo**)pHashIter;
|
||||
|
||||
STbData* d = NULL;
|
||||
|
@ -5124,7 +5139,6 @@ void tsdbUntakeReadSnap2(STsdbReader* pReader, STsdbReadSnap* pSnap, bool proact
|
|||
tsdbUnrefMemTable(pSnap->pIMem, pSnap->pINode, proactive);
|
||||
}
|
||||
|
||||
tsdbFSUnref(pTsdb, &pSnap->fs);
|
||||
if (pSnap->pNode) taosMemoryFree(pSnap->pNode);
|
||||
if (pSnap->pINode) taosMemoryFree(pSnap->pINode);
|
||||
|
||||
|
@ -5145,9 +5159,7 @@ void tsdbReaderSetId2(STsdbReader* pReader, const char* idstr) {
|
|||
void tsdbReaderSetCloseFlag(STsdbReader* pReader) { /*pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED;*/
|
||||
}
|
||||
|
||||
void tsdbSetFilesetDelimited(STsdbReader* pReader) {
|
||||
pReader->bFilesetDelimited = true;
|
||||
}
|
||||
void tsdbSetFilesetDelimited(STsdbReader* pReader) { pReader->bFilesetDelimited = true; }
|
||||
|
||||
void tsdbReaderSetNotifyCb(STsdbReader* pReader, TsdReaderNotifyCbFn notifyFn, void* param) {
|
||||
pReader->notifyFn = notifyFn;
|
||||
|
|
|
@ -567,17 +567,29 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx)
|
|||
if (vnodeIsRoleLeader(pVnode)) {
|
||||
// start to restore all stream tasks
|
||||
if (tsDisableStream) {
|
||||
streamMetaWUnLock(pMeta);
|
||||
vInfo("vgId:%d, sync restore finished, not launch stream tasks, since stream tasks are disabled", vgId);
|
||||
} else {
|
||||
vInfo("vgId:%d sync restore finished, start to launch stream tasks", pVnode->config.vgId);
|
||||
resetStreamTaskStatus(pVnode->pTq->pStreamMeta);
|
||||
tqStreamTaskStartAsync(pMeta, &pVnode->msgCb, false);
|
||||
tqStreamTaskResetStatus(pVnode->pTq->pStreamMeta);
|
||||
|
||||
{
|
||||
if (pMeta->startInfo.taskStarting == 1) {
|
||||
pMeta->startInfo.restartCount += 1;
|
||||
tqDebug("vgId:%d in start tasks procedure, inc restartCounter by 1, remaining restart:%d", vgId,
|
||||
pMeta->startInfo.restartCount);
|
||||
streamMetaWUnLock(pMeta);
|
||||
} else {
|
||||
pMeta->startInfo.taskStarting = 1;
|
||||
streamMetaWUnLock(pMeta);
|
||||
tqStreamTaskStartAsync(pMeta, &pVnode->msgCb, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
streamMetaWUnLock(pMeta);
|
||||
vInfo("vgId:%d, sync restore finished, not launch stream tasks since not leader", vgId);
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
}
|
||||
|
||||
static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
|
||||
|
@ -594,7 +606,7 @@ static void vnodeBecomeFollower(const SSyncFSM *pFsm) {
|
|||
|
||||
if (pVnode->pTq) {
|
||||
tqUpdateNodeStage(pVnode->pTq, false);
|
||||
tqStopStreamTasks(pVnode->pTq);
|
||||
tqStopStreamTasksAsync(pVnode->pTq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -846,6 +846,8 @@ void resetWinRange(STimeWindow* winRange);
|
|||
bool checkExpiredData(SStateStore* pAPI, SUpdateInfo* pUpdateInfo, STimeWindowAggSupp* pTwSup, uint64_t tableId, TSKEY ts);
|
||||
int64_t getDeleteMark(SWindowPhysiNode* pWinPhyNode, int64_t interval);
|
||||
void resetUnCloseSessionWinInfo(SSHashObj* winMap);
|
||||
void setStreamOperatorCompleted(struct SOperatorInfo* pOperator);
|
||||
void reloadAggSupFromDownStream(struct SOperatorInfo* downstream, SStreamAggSupporter* pAggSup);
|
||||
|
||||
int32_t encodeSSessionKey(void** buf, SSessionKey* key);
|
||||
void* decodeSSessionKey(void* buf, SSessionKey* key);
|
||||
|
|
|
@ -2244,8 +2244,11 @@ void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr
|
|||
}
|
||||
|
||||
void printSpecDataBlock(SSDataBlock* pBlock, const char* flag, const char* opStr, const char* taskIdStr) {
|
||||
if (!pBlock || pBlock->info.rows == 0) {
|
||||
qDebug("%s===stream===%s: Block is Null or Empty", taskIdStr, flag);
|
||||
if (!pBlock) {
|
||||
qDebug("%s===stream===%s: Block is Null", taskIdStr, flag);
|
||||
return;
|
||||
} else if (pBlock->info.rows == 0) {
|
||||
qDebug("%s===stream===%s: Block is Empty. type:%d", taskIdStr, flag, pBlock->info.type);
|
||||
return;
|
||||
}
|
||||
if (qDebugFlag & DEBUG_DEBUG) {
|
||||
|
|
|
@ -1961,8 +1961,10 @@ static void setBlockGroupIdByUid(SStreamScanInfo* pInfo, SSDataBlock* pBlock) {
|
|||
}
|
||||
|
||||
static void doCheckUpdate(SStreamScanInfo* pInfo, TSKEY endKey, SSDataBlock* pBlock) {
|
||||
if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) {
|
||||
if (pInfo->pUpdateInfo) {
|
||||
pInfo->pUpdateInfo->maxDataVersion = TMAX(pInfo->pUpdateInfo->maxDataVersion, pBlock->info.version);
|
||||
}
|
||||
if (!pInfo->igCheckUpdate && pInfo->pUpdateInfo) {
|
||||
checkUpdateData(pInfo, true, pBlock, true);
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, endKey);
|
||||
if (pInfo->pUpdateDataRes->info.rows > 0) {
|
||||
|
@ -1997,7 +1999,6 @@ void streamScanOperatorSaveCheckpoint(SStreamScanInfo* pInfo) {
|
|||
int32_t len = streamScanOperatorEncode(pInfo, &pBuf);
|
||||
pInfo->stateStore.streamStateSaveInfo(pInfo->pState, STREAM_SCAN_OP_CHECKPOINT_NAME, strlen(STREAM_SCAN_OP_CHECKPOINT_NAME), pBuf, len);
|
||||
taosMemoryFree(pBuf);
|
||||
pInfo->stateStore.streamStateCommit(pInfo->pState);
|
||||
}
|
||||
|
||||
// other properties are recovered from the execution plan
|
||||
|
@ -2316,6 +2317,7 @@ FETCH_NEXT_BLOCK:
|
|||
|
||||
doCheckUpdate(pInfo, pBlockInfo->window.ekey, pInfo->pRes);
|
||||
doFilter(pInfo->pRes, pOperator->exprSupp.pFilterInfo, NULL);
|
||||
blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
|
||||
|
||||
int64_t numOfUpdateRes = pInfo->pUpdateDataRes->info.rows;
|
||||
qDebug("%s %" PRId64 " rows in datablock, update res:%" PRId64, id, pBlockInfo->rows, numOfUpdateRes);
|
||||
|
|
|
@ -480,18 +480,18 @@ static SSDataBlock* doStreamEventAgg(SOperatorInfo* pOperator) {
|
|||
return resBlock;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -561,7 +561,7 @@ static SSDataBlock* doStreamEventAgg(SOperatorInfo* pOperator) {
|
|||
if (resBlock != NULL) {
|
||||
return resBlock;
|
||||
}
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -622,6 +622,7 @@ void streamEventReloadState(SOperatorInfo* pOperator) {
|
|||
}
|
||||
setEventWindowFlag(pAggSup, &curInfo);
|
||||
if (!curInfo.pWinFlag->startFlag || curInfo.pWinFlag->endFlag) {
|
||||
saveSessionOutputBuf(pAggSup, &curInfo.winInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -653,6 +654,7 @@ void streamEventReloadState(SOperatorInfo* pOperator) {
|
|||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
reloadAggSupFromDownStream(downstream, &pInfo->streamAggSup);
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamEventAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
|
|
|
@ -801,10 +801,24 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
SRowBuffPos* pResPos = NULL;
|
||||
SResultRow* pResult = NULL;
|
||||
int32_t forwardRows = 0;
|
||||
int32_t endRowId = pSDataBlock->info.rows - 1;
|
||||
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
|
||||
if (pSDataBlock->info.window.skey != tsCols[0] || pSDataBlock->info.window.ekey != tsCols[endRowId]) {
|
||||
qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64
|
||||
",maxKey %" PRId64,
|
||||
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||
blockDataUpdateTsWindow(pSDataBlock, pInfo->primaryTsIndex);
|
||||
|
||||
// timestamp of the data is incorrect
|
||||
if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) {
|
||||
qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64,
|
||||
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t startPos = 0;
|
||||
TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols);
|
||||
STimeWindow nextWin = {0};
|
||||
|
@ -902,19 +916,6 @@ static void doStreamIntervalAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDat
|
|||
pInfo->delKey = key;
|
||||
}
|
||||
int32_t prevEndPos = (forwardRows - 1) * step + startPos;
|
||||
if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) {
|
||||
qError("table uid %" PRIu64 " data block timestamp range may not be calculated! minKey %" PRId64
|
||||
",maxKey %" PRId64,
|
||||
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||
blockDataUpdateTsWindow(pSDataBlock, 0);
|
||||
|
||||
// timestamp of the data is incorrect
|
||||
if (pSDataBlock->info.window.skey <= 0 || pSDataBlock->info.window.ekey <= 0) {
|
||||
qError("table uid %" PRIu64 " data block timestamp is out of range! minKey %" PRId64 ",maxKey %" PRId64,
|
||||
pSDataBlock->info.id.uid, pSDataBlock->info.window.skey, pSDataBlock->info.window.ekey);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_FINAL_INTERVAL_OP(pOperator)) {
|
||||
startPos = getNextQualifiedFinalWindow(&pInfo->interval, &nextWin, &pSDataBlock->info, tsCols, prevEndPos);
|
||||
} else {
|
||||
|
@ -1223,7 +1224,7 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
if (!IS_FINAL_INTERVAL_OP(pOperator)) {
|
||||
clearFunctionContext(&pOperator->exprSupp);
|
||||
// semi interval operator clear disk buffer
|
||||
|
@ -1623,6 +1624,7 @@ void initDummyFunction(SqlFunctionCtx* pDummy, SqlFunctionCtx* pCtx, int32_t num
|
|||
pDummy[i].functionId = pCtx[i].functionId;
|
||||
pDummy[i].isNotNullFunc = pCtx[i].isNotNullFunc;
|
||||
pDummy[i].isPseudoFunc = pCtx[i].isPseudoFunc;
|
||||
pDummy[i].fpSet.init = pCtx[i].fpSet.init;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2342,10 +2344,6 @@ int32_t buildSessionResultDataBlock(SOperatorInfo* pOperator, void* pState, SSDa
|
|||
}
|
||||
|
||||
int32_t code = pAPI->stateStore.streamStateGetByPos(pState, pPos, (void**)&pRow);
|
||||
if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
|
||||
ASSERT(pBlock->info.rows > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (code == -1) {
|
||||
// for history
|
||||
|
@ -2362,6 +2360,11 @@ int32_t buildSessionResultDataBlock(SOperatorInfo* pOperator, void* pState, SSDa
|
|||
continue;
|
||||
}
|
||||
|
||||
if (pBlock->info.rows + pRow->numOfRows > pBlock->info.capacity) {
|
||||
ASSERT(pBlock->info.rows > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
pGroupResInfo->index += 1;
|
||||
|
||||
for (int32_t j = 0; j < numOfExprs; ++j) {
|
||||
|
@ -2608,18 +2611,18 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
return opRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2717,7 +2720,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
return opRes;
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2758,6 +2761,18 @@ void getSessionWindowInfoByKey(SStreamAggSupporter* pAggSup, SSessionKey* pKey,
|
|||
}
|
||||
}
|
||||
|
||||
void reloadAggSupFromDownStream(SOperatorInfo* downstream, SStreamAggSupporter* pAggSup) {
|
||||
SStateStore* pAPI = &downstream->pTaskInfo->storageAPI.stateStore;
|
||||
|
||||
if (downstream->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
reloadAggSupFromDownStream(downstream->pDownstream[0], pAggSup);
|
||||
return;
|
||||
}
|
||||
|
||||
SStreamScanInfo* pScanInfo = downstream->info;
|
||||
pAggSup->pUpdateInfo = pScanInfo->pUpdateInfo;
|
||||
}
|
||||
|
||||
void streamSessionSemiReloadState(SOperatorInfo* pOperator) {
|
||||
SStreamSessionAggOperatorInfo* pInfo = pOperator->info;
|
||||
SStreamAggSupporter* pAggSup = &pInfo->streamAggSup;
|
||||
|
@ -2774,6 +2789,9 @@ void streamSessionSemiReloadState(SOperatorInfo* pOperator) {
|
|||
for (int32_t i = 0; i < num; i++) {
|
||||
SResultWindowInfo winInfo = {0};
|
||||
getSessionWindowInfoByKey(pAggSup, pSeKeyBuf + i, &winInfo);
|
||||
if (!IS_VALID_SESSION_WIN(winInfo)) {
|
||||
continue;
|
||||
}
|
||||
compactSessionSemiWindow(pOperator, &winInfo);
|
||||
saveSessionOutputBuf(pAggSup, &winInfo);
|
||||
}
|
||||
|
@ -2786,6 +2804,7 @@ void streamSessionSemiReloadState(SOperatorInfo* pOperator) {
|
|||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
reloadAggSupFromDownStream(downstream, &pInfo->streamAggSup);
|
||||
}
|
||||
|
||||
void streamSessionReloadState(SOperatorInfo* pOperator) {
|
||||
|
@ -2838,6 +2857,7 @@ void streamSessionReloadState(SOperatorInfo* pOperator) {
|
|||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
reloadAggSupFromDownStream(downstream, &pInfo->streamAggSup);
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
|
@ -2997,7 +3017,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
clearFunctionContext(&pOperator->exprSupp);
|
||||
// semi session operator clear disk buffer
|
||||
clearStreamSessionOperator(pInfo);
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
pInfo->clearState = false;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3070,7 +3090,7 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
clearFunctionContext(&pOperator->exprSupp);
|
||||
// semi session operator clear disk buffer
|
||||
clearStreamSessionOperator(pInfo);
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3547,18 +3567,18 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
return resBlock;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
if (pInfo->recvGetAll) {
|
||||
pInfo->recvGetAll = false;
|
||||
resetUnCloseSessionWinInfo(pInfo->streamAggSup.pResultRows);
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3624,7 +3644,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
if (resBlock != NULL) {
|
||||
return resBlock;
|
||||
}
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3720,6 +3740,7 @@ void streamStateReloadState(SOperatorInfo* pOperator) {
|
|||
if (downstream->fpSet.reloadStreamStateFn) {
|
||||
downstream->fpSet.reloadStreamStateFn(downstream);
|
||||
}
|
||||
reloadAggSupFromDownStream(downstream, &pInfo->streamAggSup);
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
|
@ -3860,11 +3881,11 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
if (pInfo->reCkBlock) {
|
||||
pInfo->reCkBlock = false;
|
||||
// printDataBlock(pInfo->pCheckpointRes, "single interval ck");
|
||||
printDataBlock(pInfo->pCheckpointRes, getStreamOpName(pOperator->operatorType), GET_TASKID(pTaskInfo));
|
||||
return pInfo->pCheckpointRes;
|
||||
}
|
||||
|
||||
setOperatorCompleted(pOperator);
|
||||
setStreamOperatorCompleted(pOperator);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3896,7 +3917,6 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
doDeleteWindows(pOperator, &pInfo->interval, pBlock, pInfo->pDelWins, pInfo->pUpdatedMap);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL) {
|
||||
qDebug("===stream===%s recv|block type STREAM_GET_ALL", getStreamOpName(pOperator->operatorType));
|
||||
pInfo->recvGetAll = true;
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pInfo->pUpdatedMap);
|
||||
continue;
|
||||
|
@ -4079,3 +4099,8 @@ _error:
|
|||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void setStreamOperatorCompleted(SOperatorInfo* pOperator) {
|
||||
setOperatorCompleted(pOperator);
|
||||
qDebug("stask:%s %s status: %d. set completed", GET_TASKID(pOperator->pTaskInfo), getStreamOpName(pOperator->operatorType), pOperator->status);
|
||||
}
|
||||
|
|
|
@ -169,13 +169,14 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock*
|
|||
setNotFillColumn(pFillInfo, pDstCol, index, i);
|
||||
}
|
||||
} else {
|
||||
SGroupKeys* pKey = taosArrayGet(pFillInfo->prev.pRowVal, i);
|
||||
SRowVal* pRVal = FILL_IS_ASC_FILL(pFillInfo) ? &pFillInfo->prev : &pFillInfo->next;
|
||||
SGroupKeys* pKey = taosArrayGet(pRVal->pRowVal, i);
|
||||
if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || pKey->isNull) {
|
||||
colDataSetNULL(pDstCol, index);
|
||||
continue;
|
||||
}
|
||||
|
||||
SGroupKeys* pKey1 = taosArrayGet(pFillInfo->prev.pRowVal, pFillInfo->tsSlotId);
|
||||
SGroupKeys* pKey1 = taosArrayGet(pRVal->pRowVal, pFillInfo->tsSlotId);
|
||||
|
||||
int64_t prevTs = *(int64_t*)pKey1->pData;
|
||||
int32_t srcSlotId = GET_DEST_SLOT_ID(pCol);
|
||||
|
@ -346,9 +347,10 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t
|
|||
char* src = colDataGetData(pSrc, pFillInfo->index);
|
||||
if (!colDataIsNull_s(pSrc, pFillInfo->index)) {
|
||||
colDataSetVal(pDst, index, src, false);
|
||||
saveColData(pFillInfo->prev.pRowVal, i, src, false);
|
||||
SRowVal* pRVal = FILL_IS_ASC_FILL(pFillInfo) ? &pFillInfo->prev : &pFillInfo->next;
|
||||
saveColData(pRVal->pRowVal, i, src, false);
|
||||
if (pFillInfo->srcTsSlotId == dstSlotId) {
|
||||
pFillInfo->prev.key = *(int64_t*)src;
|
||||
pRVal->key = *(int64_t*)src;
|
||||
}
|
||||
} else { // the value is null
|
||||
if (pDst->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
|
@ -361,7 +363,8 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t
|
|||
} else if (pFillInfo->type == TSDB_FILL_LINEAR) {
|
||||
bool isNull = colDataIsNull_s(pSrc, pFillInfo->index);
|
||||
colDataSetVal(pDst, index, src, isNull);
|
||||
saveColData(pFillInfo->prev.pRowVal, i, src, isNull); // todo:
|
||||
SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev.pRowVal : pFillInfo->next.pRowVal;
|
||||
saveColData(p, i, src, isNull); // todo:
|
||||
} else if (pFillInfo->type == TSDB_FILL_NULL || pFillInfo->type == TSDB_FILL_NULL_F) {
|
||||
colDataSetNULL(pDst, index);
|
||||
} else if (pFillInfo->type == TSDB_FILL_NEXT) {
|
||||
|
|
|
@ -26,12 +26,12 @@ extern "C" {
|
|||
typedef struct MinMaxEntry {
|
||||
union {
|
||||
double dMinVal;
|
||||
int64_t i64MinVal;
|
||||
//double i64MinVal;
|
||||
uint64_t u64MinVal;
|
||||
};
|
||||
union {
|
||||
double dMaxVal;
|
||||
int64_t i64MaxVal;
|
||||
//double i64MaxVal;
|
||||
int64_t u64MaxVal;
|
||||
};
|
||||
} MinMaxEntry;
|
||||
|
|
|
@ -63,8 +63,8 @@ static SFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx)
|
|||
|
||||
static void resetBoundingBox(MinMaxEntry *range, int32_t type) {
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
range->i64MaxVal = INT64_MIN;
|
||||
range->i64MinVal = INT64_MAX;
|
||||
range->dMaxVal = INT64_MIN;
|
||||
range->dMinVal = INT64_MAX;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
range->u64MaxVal = 0;
|
||||
range->u64MinVal = UINT64_MAX;
|
||||
|
@ -80,8 +80,8 @@ static int32_t setBoundingBox(MinMaxEntry *range, int16_t type, double minval, d
|
|||
}
|
||||
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type)) {
|
||||
range->i64MinVal = (int64_t)minval;
|
||||
range->i64MaxVal = (int64_t)maxval;
|
||||
range->dMinVal = (int64_t)minval;
|
||||
range->dMaxVal = (int64_t)maxval;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
range->u64MinVal = (uint64_t)minval;
|
||||
range->u64MaxVal = (uint64_t)maxval;
|
||||
|
@ -137,21 +137,21 @@ int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) {
|
|||
|
||||
int32_t index = -1;
|
||||
|
||||
if (v > pBucket->range.i64MaxVal || v < pBucket->range.i64MinVal) {
|
||||
if (v > pBucket->range.dMaxVal || v < pBucket->range.dMinVal) {
|
||||
return index;
|
||||
}
|
||||
|
||||
// divide the value range into 1024 buckets
|
||||
uint64_t span = (uint64_t)(pBucket->range.i64MaxVal - pBucket->range.i64MinVal);
|
||||
uint64_t span = pBucket->range.dMaxVal - pBucket->range.dMinVal;
|
||||
if (span < pBucket->numOfSlots) {
|
||||
int64_t delta = v - pBucket->range.i64MinVal;
|
||||
int64_t delta = v - pBucket->range.dMinVal;
|
||||
index = (delta % pBucket->numOfSlots);
|
||||
} else {
|
||||
double slotSpan = ((double)span) / pBucket->numOfSlots;
|
||||
uint64_t delta = (uint64_t)(v - pBucket->range.i64MinVal);
|
||||
uint64_t delta = (uint64_t)(v - pBucket->range.dMinVal);
|
||||
|
||||
index = (int32_t)(delta / slotSpan);
|
||||
if (v == pBucket->range.i64MaxVal || index == pBucket->numOfSlots) {
|
||||
index = delta / slotSpan;
|
||||
if (v == pBucket->range.dMaxVal || index == pBucket->numOfSlots) {
|
||||
index -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -318,23 +318,23 @@ void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataT
|
|||
int64_t v = 0;
|
||||
GET_TYPED_DATA(v, int64_t, dataType, data);
|
||||
|
||||
if (r->i64MinVal > v) {
|
||||
r->i64MinVal = v;
|
||||
if (r->dMinVal > v) {
|
||||
r->dMinVal = v;
|
||||
}
|
||||
|
||||
if (r->i64MaxVal < v) {
|
||||
r->i64MaxVal = v;
|
||||
if (r->dMaxVal < v) {
|
||||
r->dMaxVal = v;
|
||||
}
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) {
|
||||
uint64_t v = 0;
|
||||
GET_TYPED_DATA(v, uint64_t, dataType, data);
|
||||
|
||||
if (r->i64MinVal > v) {
|
||||
r->i64MinVal = v;
|
||||
if (r->u64MinVal > v) {
|
||||
r->u64MinVal = v;
|
||||
}
|
||||
|
||||
if (r->i64MaxVal < v) {
|
||||
r->i64MaxVal = v;
|
||||
if (r->u64MaxVal < v) {
|
||||
r->u64MaxVal = v;
|
||||
}
|
||||
} else if (IS_FLOAT_TYPE(dataType)) {
|
||||
double v = 0;
|
||||
|
@ -438,7 +438,7 @@ static double getIdenticalDataVal(tMemBucket *pMemBucket, int32_t slotIndex) {
|
|||
|
||||
double finalResult = 0.0;
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
finalResult = (double)pSlot->range.i64MinVal;
|
||||
finalResult = (double)pSlot->range.dMinVal;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
finalResult = (double)pSlot->range.u64MinVal;
|
||||
} else {
|
||||
|
@ -469,8 +469,8 @@ int32_t getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction
|
|||
double maxOfThisSlot = 0;
|
||||
double minOfNextSlot = 0;
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
maxOfThisSlot = (double)pSlot->range.i64MaxVal;
|
||||
minOfNextSlot = (double)next.i64MinVal;
|
||||
maxOfThisSlot = (double)pSlot->range.dMaxVal;
|
||||
minOfNextSlot = (double)next.dMinVal;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
maxOfThisSlot = (double)pSlot->range.u64MaxVal;
|
||||
minOfNextSlot = (double)next.u64MinVal;
|
||||
|
@ -577,7 +577,7 @@ int32_t getPercentile(tMemBucket *pMemBucket, double percent, double *result) {
|
|||
MinMaxEntry *pRange = &pMemBucket->range;
|
||||
|
||||
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
*result = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal);
|
||||
*result = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->dMaxVal : pRange->dMinVal);
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) {
|
||||
*result = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->u64MaxVal : pRange->u64MinVal);
|
||||
} else {
|
||||
|
@ -603,6 +603,6 @@ bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) {
|
|||
if (IS_FLOAT_TYPE(pMemBucket->type)) {
|
||||
return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON;
|
||||
} else {
|
||||
return pSeg->range.i64MinVal == pSeg->range.i64MaxVal;
|
||||
return pSeg->range.dMinVal == pSeg->range.dMaxVal;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,6 @@ IF (TD_ENTERPRISE)
|
|||
LIST(APPEND PARSER_SRC ${TD_ENTERPRISE_DIR}/src/plugins/view/src/parserView.c)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_BI_SUPPORT)
|
||||
LIST(APPEND PARSER_SRC ${TD_ENTERPRISE_DIR}/src/plugins/bi/src/biRewriteQuery.c)
|
||||
ENDIF ()
|
||||
add_library(parser STATIC ${PARSER_SRC})
|
||||
target_include_directories(
|
||||
parser
|
||||
|
|
|
@ -334,6 +334,13 @@ static int32_t calcConstSelectWithoutFrom(SCalcConstContext* pCxt, SSelectStmt*
|
|||
|
||||
static int32_t calcConstSelectFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
|
||||
int32_t code = calcConstFromTable(pCxt, pSelect->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == code && QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) &&
|
||||
((STempTableNode*)pSelect->pFromTable)->pSubquery != NULL &&
|
||||
QUERY_NODE_SELECT_STMT == nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery) &&
|
||||
((SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery)->isEmptyResult){
|
||||
pSelect->isEmptyResult = true;
|
||||
return code;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = calcConstProjections(pCxt, pSelect, subquery);
|
||||
}
|
||||
|
|
|
@ -1104,11 +1104,192 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
#ifndef TD_ENTERPRISE
|
||||
static void biMakeAliasNameInMD5(char* pExprStr, int32_t len, char* pAlias) {
|
||||
T_MD5_CTX ctx;
|
||||
tMD5Init(&ctx);
|
||||
tMD5Update(&ctx, pExprStr, len);
|
||||
tMD5Final(&ctx);
|
||||
char* p = pAlias;
|
||||
for (uint8_t i = 0; i < tListLen(ctx.digest); ++i) {
|
||||
sprintf(p, "%02x", ctx.digest[i]);
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static SNode* biMakeTbnameProjectAstNode(char* funcName, char* tableAlias) {
|
||||
SValueNode* valNode = NULL;
|
||||
if (tableAlias != NULL) {
|
||||
SValueNode* n = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
n->literal = tstrdup(tableAlias);
|
||||
n->node.resType.type = TSDB_DATA_TYPE_BINARY;
|
||||
n->node.resType.bytes = strlen(n->literal);
|
||||
n->isDuration = false;
|
||||
n->translate = false;
|
||||
valNode = n;
|
||||
}
|
||||
|
||||
SFunctionNode* tbNameFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
tstrncpy(tbNameFunc->functionName, "tbname", TSDB_FUNC_NAME_LEN);
|
||||
if (valNode != NULL) {
|
||||
nodesListMakeAppend(&tbNameFunc->pParameterList, (SNode*)valNode);
|
||||
}
|
||||
snprintf(tbNameFunc->node.userAlias, sizeof(tbNameFunc->node.userAlias),
|
||||
(tableAlias)? "%s.tbname" : "%stbname",
|
||||
(tableAlias)? tableAlias : "");
|
||||
strncpy(tbNameFunc->node.aliasName, tbNameFunc->functionName, TSDB_COL_NAME_LEN);
|
||||
|
||||
if (funcName == NULL) {
|
||||
return (SNode*)tbNameFunc;
|
||||
} else {
|
||||
SFunctionNode* multiResFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
tstrncpy(multiResFunc->functionName, funcName, TSDB_FUNC_NAME_LEN);
|
||||
nodesListMakeAppend(&multiResFunc->pParameterList, (SNode*)tbNameFunc);
|
||||
|
||||
if (tsKeepColumnName) {
|
||||
snprintf(multiResFunc->node.userAlias, sizeof(tbNameFunc->node.userAlias),
|
||||
(tableAlias)? "%s.tbname" : "%stbname",
|
||||
(tableAlias)? tableAlias : "");
|
||||
strcpy(multiResFunc->node.aliasName, tbNameFunc->functionName);
|
||||
} else {
|
||||
snprintf(multiResFunc->node.userAlias, sizeof(multiResFunc->node.userAlias),
|
||||
tableAlias? "%s(%s.tbname)" : "%s(%stbname)", funcName,
|
||||
tableAlias? tableAlias: "");
|
||||
biMakeAliasNameInMD5(multiResFunc->node.userAlias, strlen(multiResFunc->node.userAlias), multiResFunc->node.aliasName);
|
||||
}
|
||||
|
||||
return (SNode*)multiResFunc;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t biRewriteSelectFuncParamStar(STranslateContext* pCxt, SSelectStmt* pSelect, SNode* pNode, SListCell* pSelectListCell) {
|
||||
SNodeList* pTbnameNodeList = nodesMakeList();
|
||||
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (strcasecmp(pFunc->functionName, "last") == 0 ||
|
||||
strcasecmp(pFunc->functionName, "last_row") == 0 ||
|
||||
strcasecmp(pFunc->functionName, "first") == 0) {
|
||||
SNodeList* pParams = pFunc->pParameterList;
|
||||
SNode* pPara = NULL;
|
||||
FOREACH(pPara, pParams) {
|
||||
if (nodesIsStar(pPara)) {
|
||||
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
||||
size_t n = taosArrayGetSize(pTables);
|
||||
for (int32_t i = 0; i < n; ++i) {
|
||||
STableNode* pTable = taosArrayGetP(pTables, i);
|
||||
if (nodeType(pTable) == QUERY_NODE_REAL_TABLE && ((SRealTableNode*)pTable)->pMeta != NULL &&
|
||||
((SRealTableNode*)pTable)->pMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
SNode* pTbnameNode = biMakeTbnameProjectAstNode(pFunc->functionName, NULL);
|
||||
nodesListAppend(pTbnameNodeList, pTbnameNode);
|
||||
}
|
||||
}
|
||||
if (LIST_LENGTH(pTbnameNodeList) > 0) {
|
||||
nodesListInsertListAfterPos(pSelect->pProjectionList, pSelectListCell, pTbnameNodeList);
|
||||
}
|
||||
} else if (nodesIsTableStar(pPara)) {
|
||||
char* pTableAlias = ((SColumnNode*)pPara)->tableAlias;
|
||||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, pTableAlias, &pTable);
|
||||
if (TSDB_CODE_SUCCESS == code && nodeType(pTable) == QUERY_NODE_REAL_TABLE &&
|
||||
((SRealTableNode*)pTable)->pMeta != NULL &&
|
||||
((SRealTableNode*)pTable)->pMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
SNode* pTbnameNode = biMakeTbnameProjectAstNode(pFunc->functionName, pTableAlias);
|
||||
nodesListAppend(pTbnameNodeList, pTbnameNode);
|
||||
}
|
||||
if (LIST_LENGTH(pTbnameNodeList) > 0) {
|
||||
nodesListInsertListAfterPos(pSelect->pProjectionList, pSelectListCell, pTbnameNodeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// after translate from
|
||||
// before translate select list
|
||||
int32_t biRewriteSelectStar(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
SNode* pNode = NULL;
|
||||
SNodeList* pTbnameNodeList = nodesMakeList();
|
||||
WHERE_EACH(pNode, pSelect->pProjectionList) {
|
||||
if (nodesIsStar(pNode)) {
|
||||
SArray* pTables = taosArrayGetP(pCxt->pNsLevel, pCxt->currLevel);
|
||||
size_t n = taosArrayGetSize(pTables);
|
||||
for (int32_t i = 0; i < n; ++i) {
|
||||
STableNode* pTable = taosArrayGetP(pTables, i);
|
||||
if (nodeType(pTable) == QUERY_NODE_REAL_TABLE &&
|
||||
((SRealTableNode*)pTable)->pMeta != NULL &&
|
||||
((SRealTableNode*)pTable)->pMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
SNode* pTbnameNode = biMakeTbnameProjectAstNode(NULL, NULL);
|
||||
nodesListAppend(pTbnameNodeList, pTbnameNode);
|
||||
}
|
||||
}
|
||||
if (LIST_LENGTH(pTbnameNodeList) > 0) {
|
||||
nodesListInsertListAfterPos(pSelect->pProjectionList, cell, pTbnameNodeList);
|
||||
}
|
||||
} else if (nodesIsTableStar(pNode)) {
|
||||
char* pTableAlias = ((SColumnNode*)pNode)->tableAlias;
|
||||
STableNode* pTable = NULL;
|
||||
int32_t code = findTable(pCxt, pTableAlias, &pTable);
|
||||
if (TSDB_CODE_SUCCESS == code &&
|
||||
nodeType(pTable) == QUERY_NODE_REAL_TABLE &&
|
||||
((SRealTableNode*)pTable)->pMeta != NULL &&
|
||||
((SRealTableNode*)pTable)->pMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
SNode* pTbnameNode = biMakeTbnameProjectAstNode(NULL, pTableAlias);
|
||||
nodesListAppend(pTbnameNodeList, pTbnameNode);
|
||||
}
|
||||
if (LIST_LENGTH(pTbnameNodeList) > 0) {
|
||||
nodesListInsertListAfterPos(pSelect->pProjectionList, cell, pTbnameNodeList);
|
||||
}
|
||||
} else if (nodeType(pNode) == QUERY_NODE_FUNCTION) {
|
||||
biRewriteSelectFuncParamStar(pCxt, pSelect, pNode, cell);
|
||||
}
|
||||
WHERE_NEXT;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool biRewriteToTbnameFunc(STranslateContext* pCxt, SNode** ppNode) {
|
||||
SColumnNode* pCol = (SColumnNode*)(*ppNode);
|
||||
if ((strcasecmp(pCol->colName, "tbname") == 0) &&
|
||||
((SSelectStmt*)pCxt->pCurrStmt)->pFromTable &&
|
||||
QUERY_NODE_REAL_TABLE == nodeType(((SSelectStmt*)pCxt->pCurrStmt)->pFromTable)) {
|
||||
SFunctionNode* tbnameFuncNode = NULL;
|
||||
tbnameFuncNode = (SFunctionNode*)biMakeTbnameProjectAstNode(NULL, (pCol->tableAlias[0]!='\0') ? pCol->tableAlias : NULL);
|
||||
tbnameFuncNode->node.resType = pCol->node.resType;
|
||||
strcpy(tbnameFuncNode->node.aliasName, pCol->node.aliasName);
|
||||
strcpy(tbnameFuncNode->node.userAlias, pCol->node.userAlias);
|
||||
|
||||
nodesDestroyNode(*ppNode);
|
||||
*ppNode = (SNode*)tbnameFuncNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t biCheckCreateTableTbnameCol(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
||||
if (pStmt->pTags) {
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pStmt->pTags) {
|
||||
SColumnDefNode* pTag = (SColumnDefNode*)pNode;
|
||||
if (strcasecmp(pTag->colName, "tbname") == 0) {
|
||||
int32_t code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_TAG_NAME, "tbname can not used for tags in BI mode");
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pStmt->pCols) {
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pStmt->pCols) {
|
||||
SColumnDefNode* pCol = (SColumnDefNode*)pNode;
|
||||
if (strcasecmp(pCol->colName, "tbname") == 0) {
|
||||
int32_t code = generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, "tbname can not used for columns in BI mode");
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode** pCol) {
|
||||
if (NULL == pCxt->pCurrStmt ||
|
||||
|
@ -3232,10 +3413,6 @@ static int32_t createTags(STranslateContext* pCxt, SNodeList** pOutput) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef TD_ENTERPRISE
|
||||
int32_t biRewriteSelectStar(STranslateContext* pCxt, SSelectStmt* pSelect) { return TSDB_CODE_SUCCESS; }
|
||||
#endif
|
||||
|
||||
static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
SNode* pNode = NULL;
|
||||
WHERE_EACH(pNode, pSelect->pProjectionList) {
|
||||
|
@ -5797,11 +5974,6 @@ static int32_t checkTableDeleteMarkOption(STranslateContext* pCxt, STableOptions
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifndef TD_ENTERPRISE
|
||||
int32_t biCheckCreateTableTbnameCol(STranslateContext* pCxt, SCreateTableStmt* pStmt) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32_t checkCreateTable(STranslateContext* pCxt, SCreateTableStmt* pStmt, bool createStable) {
|
||||
if (NULL != strchr(pStmt->tableName, '.')) {
|
||||
|
@ -7328,7 +7500,7 @@ static int32_t addTagsToCreateStreamQuery(STranslateContext* pCxt, SCreateStream
|
|||
}
|
||||
}
|
||||
if (!found) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, ((SColumnDefNode*)pTag)->colName);
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, getTagNameForCreateStreamTag(pTag));
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -8043,9 +8215,9 @@ int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void
|
|||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (interval.interval > 0) {
|
||||
pStmt->pReq->lastTs = taosTimeTruncate(lastTs, &interval);
|
||||
pStmt->pReq->lastTs = taosTimeAdd(taosTimeTruncate(lastTs, &interval), interval.interval, interval.intervalUnit, interval.precision);
|
||||
} else {
|
||||
pStmt->pReq->lastTs = lastTs;
|
||||
pStmt->pReq->lastTs = lastTs + 1; // start key of the next time window
|
||||
}
|
||||
code = buildCmdMsg(&cxt, TDMT_MND_CREATE_STREAM, (FSerializeFunc)tSerializeSCMCreateStreamReq, pStmt->pReq);
|
||||
}
|
||||
|
@ -8845,7 +9017,7 @@ static int32_t extractCompactDbResultSchema(int32_t* numOfCols, SSchema** pSchem
|
|||
|
||||
(*pSchema)[0].type = TSDB_DATA_TYPE_BINARY;
|
||||
(*pSchema)[0].bytes = COMPACT_DB_RESULT_FIELD1_LEN;
|
||||
strcpy((*pSchema)[0].name, "name");
|
||||
strcpy((*pSchema)[0].name, "result");
|
||||
|
||||
(*pSchema)[1].type = TSDB_DATA_TYPE_INT;
|
||||
(*pSchema)[1].bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;
|
||||
|
|
|
@ -109,13 +109,12 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
||||
|
||||
int32_t streamSaveTaskCheckpointInfo(SStreamTask* p, int64_t checkpointId);
|
||||
int32_t streamTaskBuildCheckpoint(SStreamTask* pTask);
|
||||
int32_t streamSaveAllTaskStatus(SStreamMeta* pMeta, int64_t checkpointId);
|
||||
int32_t streamSendCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
|
||||
|
||||
int32_t streamAddCheckpointReadyMsg(SStreamTask* pTask, int32_t srcTaskId, int32_t index, int64_t checkpointId);
|
||||
int32_t streamTaskSendCheckpointReadyMsg(SStreamTask* pTask);
|
||||
int32_t streamTaskSendCheckpointSourceRsp(SStreamTask* pTask);
|
||||
void streamTaskSetCheckpointFailedId(SStreamTask* pTask);
|
||||
int32_t streamTaskGetNumOfDownstream(const SStreamTask* pTask);
|
||||
int32_t streamTaskInitTokenBucket(STokenBucket* pBucket, int32_t numCap, int32_t numRate, float quotaRate, const char*);
|
||||
STaskId streamTaskExtractKey(const SStreamTask* pTask);
|
||||
|
@ -137,17 +136,6 @@ int32_t streamAddEndScanHistoryMsg(SStreamTask* pTask, SRpcHandleInfo* pRpcInfo,
|
|||
int32_t streamNotifyUpstreamContinue(SStreamTask* pTask);
|
||||
int32_t streamTransferStateToStreamTask(SStreamTask* pTask);
|
||||
|
||||
// <<<<<<< HEAD
|
||||
// void streamClearChkptReadyMsg(SStreamTask* pTask);
|
||||
|
||||
// int32_t streamTaskInitTokenBucket(STokenBucket* pBucket, int32_t numCap, int32_t numRate, float quotaRate, const
|
||||
// char*); STaskId streamTaskExtractKey(const SStreamTask* pTask); void streamTaskInitForLaunchHTask(SHistoryTaskInfo*
|
||||
// pInfo); void streamTaskSetRetryInfoForLaunch(SHistoryTaskInfo* pInfo);
|
||||
|
||||
// void streamMetaResetStartInfo(STaskStartInfo* pMeta);
|
||||
|
||||
// =======
|
||||
// >>>>>>> 3.0
|
||||
SStreamQueue* streamQueueOpen(int64_t cap);
|
||||
void streamQueueClose(SStreamQueue* pQueue, int32_t taskId);
|
||||
void streamQueueProcessSuccess(SStreamQueue* queue);
|
||||
|
|
|
@ -34,6 +34,8 @@ typedef int32_t (*__state_trans_succ_fn)(SStreamTask*);
|
|||
typedef struct SAttachedEventInfo {
|
||||
ETaskStatus status; // required status that this event can be handled
|
||||
EStreamTaskEvent event; // the delayed handled event
|
||||
void* pParam;
|
||||
void* pFn;
|
||||
} SAttachedEventInfo;
|
||||
|
||||
typedef struct STaskStateTrans {
|
||||
|
|
|
@ -665,6 +665,7 @@ void streamBackendHandleCleanup(void* arg) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t getLatestCheckpoint(void* arg, int64_t* checkpoint) {
|
||||
SStreamMeta* pMeta = arg;
|
||||
taosWLockLatch(&pMeta->chkpDirLock);
|
||||
|
@ -738,6 +739,7 @@ int32_t delObsoleteCheckpoint(void* arg, const char* path) {
|
|||
taosArrayDestroy(chkpDel);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* checkpointSave |--cp1--|--cp2--|--cp3--|--cp4--|--cp5--|
|
||||
* chkpInUse: |--cp2--|--cp4--|
|
||||
|
@ -855,6 +857,7 @@ int32_t streamBackendLoadCheckpointInfo(void* arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t chkpGetAllDbCfHandle(SStreamMeta* pMeta, rocksdb_column_family_handle_t*** ppHandle, SArray* refs) {
|
||||
return 0;
|
||||
// SArray* pHandle = taosArrayInit(16, POINTER_BYTES);
|
||||
|
@ -891,6 +894,7 @@ int32_t chkpGetAllDbCfHandle(SStreamMeta* pMeta, rocksdb_column_family_handle_t*
|
|||
// *ppHandle = ppCf;
|
||||
// return nCf;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t chkpGetAllDbCfHandle2(STaskDbWrapper* pBackend, rocksdb_column_family_handle_t*** ppHandle) {
|
||||
SArray* pHandle = taosArrayInit(8, POINTER_BYTES);
|
||||
|
@ -1006,6 +1010,7 @@ int32_t taskDbBuildSnap(void* arg, SArray* pSnap) {
|
|||
|
||||
return code;
|
||||
}
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t streamBackendAddInUseChkp(void* arg, int64_t chkpId) {
|
||||
// if (arg == NULL) return 0;
|
||||
|
||||
|
@ -1029,6 +1034,7 @@ int32_t streamBackendDelInUseChkp(void* arg, int64_t chkpId) {
|
|||
// }
|
||||
// taosWUnLockLatch(&pMeta->chkpDirLock);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
0
|
||||
|
@ -1099,7 +1105,9 @@ void streamBackendDelCompare(void* backend, void* arg) {
|
|||
taosMemoryFree(node);
|
||||
}
|
||||
}
|
||||
#ifdef BUILD_NO_CALL
|
||||
void streamStateDestroy_rocksdb(SStreamState* pState, bool remove) { streamStateCloseBackend(pState, remove); }
|
||||
#endif
|
||||
void destroyRocksdbCfInst(RocksdbCfInst* inst) {
|
||||
int cfLen = sizeof(ginitDict) / sizeof(ginitDict[0]);
|
||||
if (inst->pHandle) {
|
||||
|
@ -2170,6 +2178,7 @@ int32_t streamStateOpenBackendCf(void* backend, char* name, char** cfs, int32_t
|
|||
taosMemoryFree(cfOpts);
|
||||
return 0;
|
||||
}
|
||||
#ifdef BUILD_NO_CALL
|
||||
int streamStateOpenBackend(void* backend, SStreamState* pState) {
|
||||
taosAcquireRef(streamBackendId, pState->streamBackendRid);
|
||||
SBackendWrapper* handle = backend;
|
||||
|
@ -2279,6 +2288,7 @@ void streamStateCloseBackend(SStreamState* pState, bool remove) {
|
|||
wrapper->remove |= remove; // update by other pState
|
||||
taosReleaseRef(streamBackendCfWrapperId, pState->pTdbState->backendCfWrapperId);
|
||||
}
|
||||
#endif
|
||||
void streamStateDestroyCompar(void* arg) {
|
||||
SCfComparator* comp = (SCfComparator*)arg;
|
||||
for (int i = 0; i < comp->numOfComp; i++) {
|
||||
|
@ -2669,7 +2679,7 @@ SStreamStateCur* streamStateSeekToLast_rocksdb(SStreamState* pState) {
|
|||
STREAM_STATE_DEL_ROCKSDB(pState, "state", &maxStateKey);
|
||||
return pCur;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
SStreamStateCur* streamStateGetCur_rocksdb(SStreamState* pState, const SWinKey* key) {
|
||||
qDebug("streamStateGetCur_rocksdb");
|
||||
STaskDbWrapper* wrapper = pState->pTdbState->pOwner->pBackend;
|
||||
|
@ -2719,6 +2729,7 @@ int32_t streamStateFuncDel_rocksdb(SStreamState* pState, const STupleKey* key) {
|
|||
STREAM_STATE_DEL_ROCKSDB(pState, "func", key);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// session cf
|
||||
int32_t streamStateSessionPut_rocksdb(SStreamState* pState, const SSessionKey* key, const void* value, int32_t vLen) {
|
||||
|
@ -3128,6 +3139,7 @@ SStreamStateCur* streamStateFillSeekKeyPrev_rocksdb(SStreamState* pState, const
|
|||
streamStateFreeCur(pCur);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t streamStateSessionGetKeyByRange_rocksdb(SStreamState* pState, const SSessionKey* key, SSessionKey* curKey) {
|
||||
stDebug("streamStateSessionGetKeyByRange_rocksdb");
|
||||
STaskDbWrapper* wrapper = pState->pTdbState->pOwner->pBackend;
|
||||
|
@ -3185,6 +3197,7 @@ int32_t streamStateSessionGetKeyByRange_rocksdb(SStreamState* pState, const SSes
|
|||
streamStateFreeCur(pCur);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t streamStateSessionAddIfNotExist_rocksdb(SStreamState* pState, SSessionKey* key, TSKEY gap, void** pVal,
|
||||
int32_t* pVLen) {
|
||||
|
@ -3317,6 +3330,7 @@ _end:
|
|||
return res;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
// partag cf
|
||||
int32_t streamStatePutParTag_rocksdb(SStreamState* pState, int64_t groupId, const void* tag, int32_t tagLen) {
|
||||
int code = 0;
|
||||
|
@ -3329,6 +3343,7 @@ int32_t streamStateGetParTag_rocksdb(SStreamState* pState, int64_t groupId, void
|
|||
STREAM_STATE_GET_ROCKSDB(pState, "partag", &groupId, tagVal, tagLen);
|
||||
return code;
|
||||
}
|
||||
#endif
|
||||
// parname cfg
|
||||
int32_t streamStatePutParName_rocksdb(SStreamState* pState, int64_t groupId, const char tbname[TSDB_TABLE_NAME_LEN]) {
|
||||
int code = 0;
|
||||
|
@ -3342,11 +3357,13 @@ int32_t streamStateGetParName_rocksdb(SStreamState* pState, int64_t groupId, voi
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t streamDefaultPut_rocksdb(SStreamState* pState, const void* key, void* pVal, int32_t pVLen) {
|
||||
int code = 0;
|
||||
STREAM_STATE_PUT_ROCKSDB(pState, "default", key, pVal, pVLen);
|
||||
return code;
|
||||
}
|
||||
#endif
|
||||
int32_t streamDefaultGet_rocksdb(SStreamState* pState, const void* key, void** pVal, int32_t* pVLen) {
|
||||
int code = 0;
|
||||
STREAM_STATE_GET_ROCKSDB(pState, "default", key, pVal, pVLen);
|
||||
|
@ -3400,6 +3417,7 @@ int32_t streamDefaultIterGet_rocksdb(SStreamState* pState, const void* start, co
|
|||
rocksdb_iter_destroy(pIter);
|
||||
return code;
|
||||
}
|
||||
#ifdef BUILD_NO_CALL
|
||||
void* streamDefaultIterCreate_rocksdb(SStreamState* pState) {
|
||||
SStreamStateCur* pCur = createStreamStateCursor();
|
||||
STaskDbWrapper* wrapper = pState->pTdbState->pOwner->pBackend;
|
||||
|
@ -3443,6 +3461,7 @@ char* streamDefaultIterVal_rocksdb(void* iter, int32_t* len) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
// batch func
|
||||
void* streamStateCreateBatch() {
|
||||
rocksdb_writebatch_t* pBatch = rocksdb_writebatch_create();
|
||||
|
@ -3796,11 +3815,12 @@ void dbChkpDestroy(SDbChkp* pChkp) {
|
|||
taosMemoryFree(pChkp->pManifest);
|
||||
taosMemoryFree(pChkp);
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t dbChkpInit(SDbChkp* p) {
|
||||
if (p == NULL) return 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int32_t dbChkpDumpTo(SDbChkp* p, char* dname, SArray* list) {
|
||||
taosThreadRwlockRdlock(&p->rwLock);
|
||||
int32_t code = -1;
|
||||
|
@ -3945,6 +3965,7 @@ int32_t bkdMgtGetDelta(SBkdMgt* bm, char* taskId, int64_t chkpId, SArray* list,
|
|||
return code;
|
||||
}
|
||||
|
||||
#ifdef BUILD_NO_CALL
|
||||
int32_t bkdMgtAddChkp(SBkdMgt* bm, char* task, char* path) {
|
||||
int32_t code = -1;
|
||||
|
||||
|
@ -3974,4 +3995,5 @@ int32_t bkdMgtDumpTo(SBkdMgt* bm, char* taskId, char* dname) {
|
|||
|
||||
taosThreadRwlockUnlock(&bm->rwLock);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -25,6 +25,7 @@ typedef struct {
|
|||
|
||||
SStreamTask* pTask;
|
||||
} SAsyncUploadArg;
|
||||
|
||||
int32_t tEncodeStreamCheckpointSourceReq(SEncoder* pEncoder, const SStreamCheckpointSourceReq* pReq) {
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1;
|
||||
|
@ -34,6 +35,7 @@ int32_t tEncodeStreamCheckpointSourceReq(SEncoder* pEncoder, const SStreamCheckp
|
|||
if (tEncodeSEpSet(pEncoder, &pReq->mgmtEps) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->mnodeId) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pReq->expireTime) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->transId) < 0) return -1;
|
||||
tEndEncode(pEncoder);
|
||||
return pEncoder->pos;
|
||||
}
|
||||
|
@ -47,6 +49,7 @@ int32_t tDecodeStreamCheckpointSourceReq(SDecoder* pDecoder, SStreamCheckpointSo
|
|||
if (tDecodeSEpSet(pDecoder, &pReq->mgmtEps) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->mnodeId) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pReq->expireTime) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->transId) < 0) return -1;
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
@ -111,6 +114,7 @@ static int32_t streamAlignCheckpoint(SStreamTask* pTask) {
|
|||
return atomic_sub_fetch_32(&pTask->chkInfo.downstreamAlignNum, 1);
|
||||
}
|
||||
|
||||
// todo handle down the transId of checkpoint to sink/agg tasks.
|
||||
static int32_t appendCheckpointIntoInputQ(SStreamTask* pTask, int32_t checkpointType) {
|
||||
SStreamDataBlock* pChkpoint = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM, sizeof(SSDataBlock));
|
||||
if (pChkpoint == NULL) {
|
||||
|
@ -149,6 +153,7 @@ int32_t streamProcessCheckpointSourceReq(SStreamTask* pTask, SStreamCheckpointSo
|
|||
// 1. set task status to be prepared for check point, no data are allowed to put into inputQ.
|
||||
streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_GEN_CHECKPOINT);
|
||||
|
||||
pTask->chkInfo.transId = pReq->transId;
|
||||
pTask->chkInfo.checkpointingId = pReq->checkpointId;
|
||||
pTask->chkInfo.checkpointNotReadyTasks = streamTaskGetNumOfDownstream(pTask);
|
||||
pTask->chkInfo.startTs = taosGetTimestampMs();
|
||||
|
@ -273,8 +278,9 @@ void streamTaskClearCheckInfo(SStreamTask* pTask, bool clearChkpReadyMsg) {
|
|||
pTask->chkInfo.failedId = 0;
|
||||
pTask->chkInfo.startTs = 0; // clear the recorded start time
|
||||
pTask->chkInfo.checkpointNotReadyTasks = 0;
|
||||
// pTask->chkInfo.checkpointAlignCnt = 0;
|
||||
pTask->chkInfo.transId = 0;
|
||||
pTask->chkInfo.dispatchCheckpointTrigger = false;
|
||||
|
||||
streamTaskOpenAllUpstreamInput(pTask); // open inputQ for all upstream tasks
|
||||
if (clearChkpReadyMsg) {
|
||||
streamClearChkptReadyMsg(pTask);
|
||||
|
@ -341,9 +347,8 @@ int32_t streamSaveTaskCheckpointInfo(SStreamTask* p, int64_t checkpointId) {
|
|||
return code;
|
||||
}
|
||||
|
||||
void streamTaskSetFailedId(SStreamTask* pTask) {
|
||||
void streamTaskSetCheckpointFailedId(SStreamTask* pTask) {
|
||||
pTask->chkInfo.failedId = pTask->chkInfo.checkpointingId;
|
||||
pTask->chkInfo.checkpointId = pTask->chkInfo.checkpointingId;
|
||||
}
|
||||
|
||||
int32_t getChkpMeta(char* id, char* path, SArray* list) {
|
||||
|
@ -485,7 +490,7 @@ int32_t streamTaskBuildCheckpoint(SStreamTask* pTask) {
|
|||
code = streamTaskHandleEvent(pTask->status.pSM, TASK_EVENT_CHECKPOINT_DONE);
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
streamTaskSetFailedId(pTask);
|
||||
streamTaskSetCheckpointFailedId(pTask);
|
||||
stDebug("s-task:%s clear checkpoint flag since gen checkpoint failed, checkpointId:%" PRId64, pTask->id.idStr,
|
||||
ckId);
|
||||
}
|
||||
|
|
|
@ -352,6 +352,7 @@ static int32_t doBuildDispatchMsg(SStreamTask* pTask, const SStreamDataBlock* pD
|
|||
return code;
|
||||
}
|
||||
|
||||
// it's a new vnode to receive dispatch msg, so add one
|
||||
if (pReqs[j].blockNum == 0) {
|
||||
atomic_add_fetch_32(&pTask->outputInfo.shuffleDispatcher.waitingRspCnt, 1);
|
||||
}
|
||||
|
@ -372,8 +373,15 @@ static int32_t doBuildDispatchMsg(SStreamTask* pTask, const SStreamDataBlock* pD
|
|||
pTask->msgInfo.pData = pReqs;
|
||||
}
|
||||
|
||||
stDebug("s-task:%s build dispatch msg success, msgId:%d, stage:%" PRId64, pTask->id.idStr, pTask->execInfo.dispatch,
|
||||
pTask->pMeta->stage);
|
||||
if (pTask->outputInfo.type == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||
stDebug("s-task:%s build dispatch msg success, msgId:%d, stage:%" PRId64 " %p", pTask->id.idStr,
|
||||
pTask->execInfo.dispatch, pTask->pMeta->stage, pTask->msgInfo.pData);
|
||||
} else {
|
||||
stDebug("s-task:%s build dispatch msg success, msgId:%d, stage:%" PRId64 " dstVgNum:%d %p", pTask->id.idStr,
|
||||
pTask->execInfo.dispatch, pTask->pMeta->stage, pTask->outputInfo.shuffleDispatcher.waitingRspCnt,
|
||||
pTask->msgInfo.pData);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -395,9 +403,11 @@ static int32_t sendDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pDispatch
|
|||
SArray* vgInfo = pTask->outputInfo.shuffleDispatcher.dbInfo.pVgroupInfos;
|
||||
int32_t numOfVgroups = taosArrayGetSize(vgInfo);
|
||||
|
||||
stDebug("s-task:%s (child taskId:%d) start to shuffle-dispatch blocks to %d vgroup(s), msgId:%d", id,
|
||||
pTask->info.selfChildId, numOfVgroups, msgId);
|
||||
int32_t actualVgroups = pTask->outputInfo.shuffleDispatcher.waitingRspCnt;
|
||||
stDebug("s-task:%s (child taskId:%d) start to shuffle-dispatch blocks to %d/%d vgroup(s), msgId:%d", id,
|
||||
pTask->info.selfChildId, actualVgroups, numOfVgroups, msgId);
|
||||
|
||||
int32_t numOfSend = 0;
|
||||
for (int32_t i = 0; i < numOfVgroups; i++) {
|
||||
if (pDispatchMsg[i].blockNum > 0) {
|
||||
SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i);
|
||||
|
@ -408,6 +418,11 @@ static int32_t sendDispatchMsg(SStreamTask* pTask, SStreamDispatchReq* pDispatch
|
|||
if (code < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// no need to try remain, all already send.
|
||||
if (++numOfSend == actualVgroups) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -731,7 +746,7 @@ int32_t streamTaskSendCheckpointSourceRsp(SStreamTask* pTask) {
|
|||
taosArrayClear(pTask->pReadyMsgList);
|
||||
stDebug("s-task:%s level:%d source checkpoint completed msg sent to mnode", pTask->id.idStr, pTask->info.taskLevel);
|
||||
} else {
|
||||
stDebug("s-task:%s level:%d already send rsp to mnode", pTask->id.idStr, pTask->info.taskLevel);
|
||||
stDebug("s-task:%s level:%d already send rsp checkpoint success to mnode", pTask->id.idStr, pTask->info.taskLevel);
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
@ -1081,6 +1096,7 @@ int32_t streamNotifyUpstreamContinue(SStreamTask* pTask) {
|
|||
|
||||
// this message has been sent successfully, let's try next one.
|
||||
static int32_t handleDispatchSuccessRsp(SStreamTask* pTask, int32_t downstreamId) {
|
||||
stDebug("s-task:%s destroy dispatch msg:%p", pTask->id.idStr, pTask->msgInfo.pData);
|
||||
destroyDispatchMsg(pTask->msgInfo.pData, getNumOfDispatchBranch(pTask));
|
||||
|
||||
bool delayDispatch = (pTask->msgInfo.dispatchMsgType == STREAM_INPUT__CHECKPOINT_TRIGGER);
|
||||
|
|
|
@ -356,9 +356,16 @@ int32_t streamDoTransferStateToStreamTask(SStreamTask* pTask) {
|
|||
if (pStreamTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
ASSERT(status == TASK_STATUS__HALT || status == TASK_STATUS__DROPPING || status == TASK_STATUS__STOP);
|
||||
} 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, id);
|
||||
ASSERT(status == TASK_STATUS__READY || status == TASK_STATUS__DROPPING || status == TASK_STATUS__STOP);
|
||||
int32_t code = streamTaskHandleEvent(pStreamTask->status.pSM, TASK_EVENT_HALT);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("s-task:%s halt stream task:%s failed, code:%s not transfer state to stream task", id,
|
||||
pStreamTask->id.idStr, tstrerror(code));
|
||||
streamMetaReleaseTask(pMeta, pStreamTask);
|
||||
return code;
|
||||
} else {
|
||||
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
|
||||
|
@ -625,10 +632,29 @@ int32_t doStreamExecTask(SStreamTask* pTask) {
|
|||
// todo other thread may change the status
|
||||
// do nothing after sync executor state to storage backend, untill the vnode-level checkpoint is completed.
|
||||
if (type == STREAM_INPUT__CHECKPOINT) {
|
||||
|
||||
// todo add lock
|
||||
char* p = NULL;
|
||||
streamTaskGetStatus(pTask, &p);
|
||||
stDebug("s-task:%s checkpoint block received, set status:%s", pTask->id.idStr, p);
|
||||
streamTaskBuildCheckpoint(pTask);
|
||||
ETaskStatus s = streamTaskGetStatus(pTask, &p);
|
||||
if (s == TASK_STATUS__CK) {
|
||||
stDebug("s-task:%s checkpoint block received, set status:%s", pTask->id.idStr, p);
|
||||
streamTaskBuildCheckpoint(pTask);
|
||||
} else {
|
||||
// todo refactor
|
||||
int32_t code = 0;
|
||||
if (pTask->info.taskLevel == TASK_LEVEL__SOURCE) {
|
||||
code = streamTaskSendCheckpointSourceRsp(pTask);
|
||||
} else {
|
||||
code = streamTaskSendCheckpointReadyMsg(pTask);
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
// todo: let's retry send rsp to upstream/mnode
|
||||
stError("s-task:%s failed to send checkpoint rsp to upstream, checkpointId:%d, code:%s", pTask->id.idStr,
|
||||
0, tstrerror(code));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -646,7 +672,7 @@ bool streamTaskIsIdle(const SStreamTask* pTask) {
|
|||
|
||||
bool streamTaskReadyToRun(const SStreamTask* pTask, char** pStatus) {
|
||||
ETaskStatus st = streamTaskGetStatus(pTask, NULL);
|
||||
return (st == TASK_STATUS__READY || st == TASK_STATUS__SCAN_HISTORY || st == TASK_STATUS__STREAM_SCAN_HISTORY ||
|
||||
return (st == TASK_STATUS__READY || st == TASK_STATUS__SCAN_HISTORY/* || st == TASK_STATUS__STREAM_SCAN_HISTORY*/ ||
|
||||
st == TASK_STATUS__CK);
|
||||
}
|
||||
|
||||
|
|
|
@ -266,11 +266,12 @@ int32_t streamTaskSetDb(SStreamMeta* pMeta, void* arg, char* key) {
|
|||
if (pBackend == NULL) {
|
||||
taosThreadMutexUnlock(&pMeta->backendMutex);
|
||||
taosMsleep(1000);
|
||||
stDebug("backed holded by other task, restart later, path: %s, key: %s", pMeta->path, key);
|
||||
stDebug("backend held by other task, restart later, path:%s, key:%s", pMeta->path, key);
|
||||
} else {
|
||||
taosThreadMutexUnlock(&pMeta->backendMutex);
|
||||
break;
|
||||
}
|
||||
|
||||
taosThreadMutexLock(&pMeta->backendMutex);
|
||||
pBackend = taskDbOpen(pMeta->path, key, chkpId);
|
||||
}
|
||||
|
@ -297,7 +298,9 @@ void streamMetaRemoveDB(void* arg, char* key) {
|
|||
|
||||
taosThreadMutexUnlock(&pMeta->backendMutex);
|
||||
}
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage) {
|
||||
|
||||
SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandFunc, int32_t vgId, int64_t stage,
|
||||
startComplete_fn_t fn) {
|
||||
int32_t code = -1;
|
||||
SStreamMeta* pMeta = taosMemoryCalloc(1, sizeof(SStreamMeta));
|
||||
if (pMeta == NULL) {
|
||||
|
@ -363,20 +366,9 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
|
|||
pMeta->stage = stage;
|
||||
pMeta->role = (vgId == SNODE_HANDLE) ? NODE_ROLE_LEADER : NODE_ROLE_UNINIT;
|
||||
|
||||
pMeta->startInfo.completeFn = fn;
|
||||
pMeta->pTaskDbUnique = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
|
||||
|
||||
// pMeta->chkpId = streamGetLatestCheckpointId(pMeta);
|
||||
// pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId);
|
||||
// while (pMeta->streamBackend == NULL) {
|
||||
// qError("vgId:%d failed to init stream backend", pMeta->vgId);
|
||||
// taosMsleep(2 * 1000);
|
||||
// qInfo("vgId:%d retry to init stream backend", pMeta->vgId);
|
||||
// pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId);
|
||||
// if (pMeta->streamBackend == NULL) {
|
||||
// }
|
||||
// }
|
||||
// pMeta->streamBackendRid = taosAddRef(streamBackendId, pMeta->streamBackend);
|
||||
|
||||
pMeta->numOfPausedTasks = 0;
|
||||
pMeta->numOfStreamTasks = 0;
|
||||
stInfo("vgId:%d open stream meta successfully, latest checkpoint:%" PRId64 ", stage:%" PRId64, vgId, pMeta->chkpId,
|
||||
|
@ -384,6 +376,17 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
|
|||
|
||||
pMeta->rid = taosAddRef(streamMetaId, pMeta);
|
||||
|
||||
// set the attribute when running on Linux OS
|
||||
#if defined LINUX
|
||||
TdThreadRwlockAttr attr;
|
||||
taosThreadRwlockAttrInit(&attr);
|
||||
|
||||
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
taosThreadRwlockInit(&pMeta->lock, &attr);
|
||||
|
||||
taosThreadRwlockAttrDestroy(&attr);
|
||||
#endif
|
||||
|
||||
int64_t* pRid = taosMemoryMalloc(sizeof(int64_t));
|
||||
memcpy(pRid, &pMeta->rid, sizeof(pMeta->rid));
|
||||
metaRefMgtAdd(pMeta->vgId, pRid);
|
||||
|
@ -416,6 +419,7 @@ _err:
|
|||
}
|
||||
|
||||
// todo refactor: the lock shoud be restricted in one function
|
||||
#ifdef BUILD_NO_CALL
|
||||
void streamMetaInitBackend(SStreamMeta* pMeta) {
|
||||
pMeta->streamBackend = streamBackendInit(pMeta->path, pMeta->chkpId, pMeta->vgId);
|
||||
if (pMeta->streamBackend == NULL) {
|
||||
|
@ -437,6 +441,7 @@ void streamMetaInitBackend(SStreamMeta* pMeta) {
|
|||
pMeta->streamBackendRid = taosAddRef(streamBackendId, pMeta->streamBackend);
|
||||
streamBackendLoadCheckpointInfo(pMeta);
|
||||
}
|
||||
#endif
|
||||
|
||||
void streamMetaClear(SStreamMeta* pMeta) {
|
||||
// remove all existed tasks in this vnode
|
||||
|
@ -458,7 +463,6 @@ void streamMetaClear(SStreamMeta* pMeta) {
|
|||
taosRemoveRef(streamBackendId, pMeta->streamBackendRid);
|
||||
|
||||
taosHashClear(pMeta->pTasksMap);
|
||||
taosHashClear(pMeta->pTaskDbUnique);
|
||||
|
||||
taosArrayClear(pMeta->pTaskList);
|
||||
taosArrayClear(pMeta->chkpSaved);
|
||||
|
@ -617,22 +621,23 @@ int32_t streamMetaGetNumOfTasks(SStreamMeta* pMeta) {
|
|||
return (int32_t)size;
|
||||
}
|
||||
|
||||
SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) {
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
SStreamTask* streamMetaAcquireTaskNoLock(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) {
|
||||
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);
|
||||
streamMetaRUnLock(pMeta);
|
||||
stTrace("s-task:%s acquire task, ref:%d", (*ppTask)->id.idStr, ref);
|
||||
return *ppTask;
|
||||
}
|
||||
if (ppTask == NULL || streamTaskShouldStop(*ppTask)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t ref = atomic_add_fetch_32(&(*ppTask)->refCnt, 1);
|
||||
stTrace("s-task:%s acquire task, ref:%d", (*ppTask)->id.idStr, ref);
|
||||
return *ppTask;
|
||||
}
|
||||
|
||||
SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int64_t streamId, int32_t taskId) {
|
||||
streamMetaRLock(pMeta);
|
||||
SStreamTask* p = streamMetaAcquireTaskNoLock(pMeta, streamId, taskId);
|
||||
streamMetaRUnLock(pMeta);
|
||||
return NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
void streamMetaReleaseTask(SStreamMeta* UNUSED_PARAM(pMeta), SStreamTask* pTask) {
|
||||
|
@ -950,6 +955,7 @@ int32_t tEncodeStreamHbMsg(SEncoder* pEncoder, const SStreamHbMsg* pReq) {
|
|||
if (tEncodeI64(pEncoder, ps->verEnd) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, ps->activeCheckpointId) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, ps->checkpointFailed) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, ps->chkpointTransId) < 0) return -1;
|
||||
}
|
||||
|
||||
int32_t numOfVgs = taosArrayGetSize(pReq->pUpdateNodes);
|
||||
|
@ -988,6 +994,7 @@ int32_t tDecodeStreamHbMsg(SDecoder* pDecoder, SStreamHbMsg* pReq) {
|
|||
if (tDecodeI64(pDecoder, &entry.verEnd) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &entry.activeCheckpointId) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, (int8_t*)&entry.checkpointFailed) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &entry.chkpointTransId) < 0) return -1;
|
||||
|
||||
entry.id.taskId = taskId;
|
||||
taosArrayPush(pReq->pTaskStatus, &entry);
|
||||
|
@ -1061,68 +1068,20 @@ static void addUpdateNodeIntoHbMsg(SStreamTask* pTask, SStreamHbMsg* pMsg) {
|
|||
taosThreadMutexUnlock(&pTask->lock);
|
||||
}
|
||||
|
||||
void metaHbToMnode(void* param, void* tmrId) {
|
||||
int64_t rid = *(int64_t*)param;
|
||||
|
||||
SStreamMeta* pMeta = taosAcquireRef(streamMetaId, rid);
|
||||
if (pMeta == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// need to stop, stop now
|
||||
if (pMeta->pHbInfo->stopFlag == STREAM_META_WILL_STOP) {
|
||||
pMeta->pHbInfo->stopFlag = STREAM_META_OK_TO_STOP;
|
||||
stDebug("vgId:%d jump out of meta timer", pMeta->vgId);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
return;
|
||||
}
|
||||
|
||||
// not leader not send msg
|
||||
if (pMeta->role != NODE_ROLE_LEADER) {
|
||||
stInfo("vgId:%d role:%d not leader not send hb to mnode", pMeta->vgId, pMeta->role);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
pMeta->pHbInfo->hbStart = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// set the hb start time
|
||||
if (pMeta->pHbInfo->hbStart == 0) {
|
||||
pMeta->pHbInfo->hbStart = taosGetTimestampMs();
|
||||
}
|
||||
|
||||
if (!waitForEnoughDuration(pMeta->pHbInfo)) {
|
||||
taosTmrReset(metaHbToMnode, META_HB_CHECK_INTERVAL, param, streamTimer, &pMeta->pHbInfo->hbTmr);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
return;
|
||||
}
|
||||
|
||||
stDebug("vgId:%d build stream task hb, leader:%d", pMeta->vgId, (pMeta->role == NODE_ROLE_LEADER));
|
||||
|
||||
static int32_t metaHeartbeatToMnodeImpl(SStreamMeta* pMeta) {
|
||||
SStreamHbMsg hbMsg = {0};
|
||||
SEpSet epset = {0};
|
||||
bool hasMnodeEpset = false;
|
||||
int64_t stage = 0;
|
||||
int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
|
||||
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
int32_t numOfTasks = streamMetaGetNumOfTasks(pMeta);
|
||||
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(pIdList, i);
|
||||
STaskId* pId = taosArrayGet(pMeta->pTaskList, i);
|
||||
|
||||
streamMetaRLock(pMeta);
|
||||
SStreamTask** pTask = taosHashGet(pMeta->pTasksMap, pId, sizeof(*pId));
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
if (pTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1136,7 +1095,7 @@ void metaHbToMnode(void* param, void* tmrId) {
|
|||
.id = *pId,
|
||||
.status = streamTaskGetStatus(*pTask, NULL),
|
||||
.nodeId = hbMsg.vgId,
|
||||
.stage = stage,
|
||||
.stage = pMeta->stage,
|
||||
.inputQUsed = SIZE_IN_MiB(streamQueueGetItemSize((*pTask)->inputq.queue)),
|
||||
};
|
||||
|
||||
|
@ -1149,6 +1108,11 @@ void metaHbToMnode(void* param, void* tmrId) {
|
|||
if ((*pTask)->chkInfo.checkpointingId != 0) {
|
||||
entry.checkpointFailed = ((*pTask)->chkInfo.failedId >= (*pTask)->chkInfo.checkpointingId);
|
||||
entry.activeCheckpointId = (*pTask)->chkInfo.checkpointingId;
|
||||
entry.chkpointTransId = (*pTask)->chkInfo.transId;
|
||||
|
||||
if (entry.checkpointFailed) {
|
||||
stInfo("s-task:%s send kill checkpoint trans info, transId:%d", (*pTask)->id.idStr, (*pTask)->chkInfo.transId);
|
||||
}
|
||||
}
|
||||
|
||||
if ((*pTask)->exec.pWalReader != NULL) {
|
||||
|
@ -1191,30 +1155,70 @@ void metaHbToMnode(void* param, void* tmrId) {
|
|||
}
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
SRpcMsg msg = {
|
||||
.info.noResp = 1,
|
||||
};
|
||||
SRpcMsg msg = {.info.noResp = 1};
|
||||
initRpcMsg(&msg, TDMT_MND_STREAM_HEARTBEAT, buf, tlen);
|
||||
|
||||
pMeta->pHbInfo->hbCount += 1;
|
||||
|
||||
stDebug("vgId:%d build and send hb to mnode, numOfTasks:%d total:%d", pMeta->vgId, hbMsg.numOfTasks,
|
||||
pMeta->pHbInfo->hbCount);
|
||||
|
||||
tmsgSendReq(&epset, &msg);
|
||||
} else {
|
||||
stDebug("vgId:%d no tasks and no mnd epset, not send stream hb to mnode", pMeta->vgId);
|
||||
}
|
||||
|
||||
_end:
|
||||
_end:
|
||||
streamMetaClearHbMsg(&hbMsg);
|
||||
taosArrayDestroy(pIdList);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void metaHbToMnode(void* param, void* tmrId) {
|
||||
int64_t rid = *(int64_t*)param;
|
||||
|
||||
SStreamMeta* pMeta = taosAcquireRef(streamMetaId, rid);
|
||||
if (pMeta == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// need to stop, stop now
|
||||
if (pMeta->pHbInfo->stopFlag == STREAM_META_WILL_STOP) {
|
||||
pMeta->pHbInfo->stopFlag = STREAM_META_OK_TO_STOP;
|
||||
stDebug("vgId:%d jump out of meta timer", pMeta->vgId);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
return;
|
||||
}
|
||||
|
||||
// not leader not send msg
|
||||
if (pMeta->role != NODE_ROLE_LEADER) {
|
||||
stInfo("vgId:%d role:%d not leader not send hb to mnode", pMeta->vgId, pMeta->role);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
pMeta->pHbInfo->hbStart = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// set the hb start time
|
||||
if (pMeta->pHbInfo->hbStart == 0) {
|
||||
pMeta->pHbInfo->hbStart = taosGetTimestampMs();
|
||||
}
|
||||
|
||||
if (!waitForEnoughDuration(pMeta->pHbInfo)) {
|
||||
taosTmrReset(metaHbToMnode, META_HB_CHECK_INTERVAL, param, streamTimer, &pMeta->pHbInfo->hbTmr);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
return;
|
||||
}
|
||||
|
||||
stDebug("vgId:%d build stream task hb, leader:%d", pMeta->vgId, (pMeta->role == NODE_ROLE_LEADER));
|
||||
streamMetaRLock(pMeta);
|
||||
metaHeartbeatToMnodeImpl(pMeta);
|
||||
streamMetaRUnLock(pMeta);
|
||||
|
||||
taosTmrReset(metaHbToMnode, META_HB_CHECK_INTERVAL, param, streamTimer, &pMeta->pHbInfo->hbTmr);
|
||||
taosReleaseRef(streamMetaId, rid);
|
||||
}
|
||||
|
||||
bool streamMetaTaskInTimer(SStreamMeta* pMeta) {
|
||||
bool inTimer = false;
|
||||
streamMetaWLock(pMeta);
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
void* pIter = NULL;
|
||||
while (1) {
|
||||
|
@ -1225,11 +1229,12 @@ bool streamMetaTaskInTimer(SStreamMeta* pMeta) {
|
|||
|
||||
SStreamTask* pTask = *(SStreamTask**)pIter;
|
||||
if (pTask->status.timerActive >= 1) {
|
||||
stDebug("s-task:%s in timer, blocking tasks in vgId:%d restart", pTask->id.idStr, pMeta->vgId);
|
||||
inTimer = true;
|
||||
}
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
streamMetaRUnLock(pMeta);
|
||||
return inTimer;
|
||||
}
|
||||
|
||||
|
@ -1288,26 +1293,37 @@ void streamMetaResetStartInfo(STaskStartInfo* pStartInfo) {
|
|||
taosHashClear(pStartInfo->pFailedTaskSet);
|
||||
pStartInfo->tasksWillRestart = 0;
|
||||
pStartInfo->readyTs = 0;
|
||||
|
||||
// reset the sentinel flag value to be 0
|
||||
atomic_store_32(&pStartInfo->taskStarting, 0);
|
||||
pStartInfo->taskStarting = 0;
|
||||
}
|
||||
|
||||
void streamMetaRLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-rlock", pMeta->vgId);
|
||||
taosRLockLatch(&pMeta->lock);
|
||||
taosThreadRwlockRdlock(&pMeta->lock);
|
||||
}
|
||||
|
||||
void streamMetaRUnLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-runlock", pMeta->vgId);
|
||||
taosRUnLockLatch(&pMeta->lock);
|
||||
int32_t code = taosThreadRwlockUnlock(&pMeta->lock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d meta-runlock failed, code:%d", pMeta->vgId, code);
|
||||
} else {
|
||||
stDebug("vgId:%d meta-runlock completed", pMeta->vgId);
|
||||
}
|
||||
}
|
||||
|
||||
void streamMetaWLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-wlock", pMeta->vgId);
|
||||
taosWLockLatch(&pMeta->lock);
|
||||
taosThreadRwlockWrlock(&pMeta->lock);
|
||||
stTrace("vgId:%d meta-wlock completed", pMeta->vgId);
|
||||
}
|
||||
|
||||
void streamMetaWUnLock(SStreamMeta* pMeta) {
|
||||
stTrace("vgId:%d meta-wunlock", pMeta->vgId);
|
||||
taosWUnLockLatch(&pMeta->lock);
|
||||
taosThreadRwlockUnlock(&pMeta->lock);
|
||||
}
|
||||
|
||||
static void execHelper(struct SSchedMsg* pSchedMsg) {
|
||||
__async_exec_fn_t execFn = (__async_exec_fn_t)pSchedMsg->ahandle;
|
||||
int32_t code = execFn(pSchedMsg->thandle);
|
||||
|
@ -1324,3 +1340,165 @@ int32_t streamMetaAsyncExec(SStreamMeta* pMeta, __stream_async_exec_fn_t fn, voi
|
|||
schedMsg.msg = code;
|
||||
return taosScheduleTask(pMeta->qHandle, &schedMsg);
|
||||
}
|
||||
|
||||
SArray* streamMetaSendMsgBeforeCloseTasks(SStreamMeta* pMeta) {
|
||||
SArray* pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
|
||||
bool sendMsg = pMeta->sendMsgBeforeClosing;
|
||||
if (!sendMsg) {
|
||||
stDebug("vgId:%d no need to send msg to mnode before closing tasks", pMeta->vgId);
|
||||
return pTaskList;
|
||||
}
|
||||
|
||||
stDebug("vgId:%d send msg to mnode before closing all tasks", pMeta->vgId);
|
||||
|
||||
// send hb msg to mnode before closing all tasks.
|
||||
int32_t numOfTasks = taosArrayGetSize(pTaskList);
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
SStreamTask* pTask = streamMetaAcquireTaskNoLock(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
char* p = NULL;
|
||||
ETaskStatus s = streamTaskGetStatus(pTask, &p);
|
||||
if (s == TASK_STATUS__CK) {
|
||||
streamTaskSetCheckpointFailedId(pTask);
|
||||
stDebug("s-task:%s mark the checkpoint:%"PRId64" failed", pTask->id.idStr, pTask->chkInfo.checkpointingId);
|
||||
} else {
|
||||
stDebug("s-task:%s status:%s not reset the checkpoint", pTask->id.idStr, p);
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
metaHeartbeatToMnodeImpl(pMeta);
|
||||
pMeta->sendMsgBeforeClosing = false;
|
||||
return pTaskList;
|
||||
}
|
||||
|
||||
void streamMetaUpdateStageRole(SStreamMeta* pMeta, int64_t stage, bool isLeader) {
|
||||
streamMetaWLock(pMeta);
|
||||
|
||||
int64_t prevStage = pMeta->stage;
|
||||
pMeta->stage = stage;
|
||||
|
||||
// mark the sign to send msg before close all tasks
|
||||
if ((!isLeader) && (pMeta->role == NODE_ROLE_LEADER)) {
|
||||
pMeta->sendMsgBeforeClosing = true;
|
||||
}
|
||||
|
||||
pMeta->role = (isLeader)? NODE_ROLE_LEADER:NODE_ROLE_FOLLOWER;
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
if (isLeader) {
|
||||
stInfo("vgId:%d update meta stage:%" PRId64 ", prev:%" PRId64 " leader:%d, start to send Hb", pMeta->vgId,
|
||||
prevStage, stage, isLeader);
|
||||
streamMetaStartHb(pMeta);
|
||||
} else {
|
||||
stInfo("vgId:%d update meta stage:%" PRId64 " prev:%" PRId64 " leader:%d sendMsg beforeClosing:%d", pMeta->vgId,
|
||||
prevStage, stage, isLeader, pMeta->sendMsgBeforeClosing);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t streamMetaStopAllTasks(SStreamMeta* pMeta) {
|
||||
streamMetaRLock(pMeta);
|
||||
|
||||
int32_t num = taosArrayGetSize(pMeta->pTaskList);
|
||||
stDebug("vgId:%d stop all %d stream task(s)", pMeta->vgId, num);
|
||||
if (num == 0) {
|
||||
streamMetaRUnLock(pMeta);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// send hb msg to mnode before closing all tasks.
|
||||
SArray* pTaskList = streamMetaSendMsgBeforeCloseTasks(pMeta);
|
||||
int32_t numOfTasks = taosArrayGetSize(pTaskList);
|
||||
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
SStreamTask* pTask = streamMetaAcquireTaskNoLock(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
streamTaskStop(pTask);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTaskList);
|
||||
|
||||
streamMetaRUnLock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t streamMetaStartAllTasks(SStreamMeta* pMeta) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t vgId = pMeta->vgId;
|
||||
|
||||
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||
stInfo("vgId:%d start to check all %d stream task(s) downstream status", vgId, numOfTasks);
|
||||
if (numOfTasks == 0) {
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SArray* pTaskList = NULL;
|
||||
streamMetaWLock(pMeta);
|
||||
pTaskList = taosArrayDup(pMeta->pTaskList, NULL);
|
||||
taosHashClear(pMeta->startInfo.pReadyTaskSet);
|
||||
taosHashClear(pMeta->startInfo.pFailedTaskSet);
|
||||
pMeta->startInfo.startTs = taosGetTimestampMs();
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
// broadcast the check downstream tasks msg
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||
SStreamTaskId* pTaskId = taosArrayGet(pTaskList, i);
|
||||
|
||||
SStreamTask* pTask = streamMetaAcquireTask(pMeta, pTaskId->streamId, pTaskId->taskId);
|
||||
if (pTask == NULL) {
|
||||
stError("vgId:%d failed to acquire task:0x%x during start tasks", pMeta->vgId, pTaskId->taskId);
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, 0, now, false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// fill-history task can only be launched by related stream tasks.
|
||||
STaskExecStatisInfo* pInfo = &pTask->execInfo;
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pTask->status.downstreamReady == 1) {
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
stDebug("s-task:%s downstream ready, no need to check downstream, check only related fill-history task",
|
||||
pTask->id.idStr);
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
}
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, true);
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
continue;
|
||||
}
|
||||
|
||||
EStreamTaskEvent event = /*(HAS_RELATED_FILLHISTORY_TASK(pTask)) ? TASK_EVENT_INIT_STREAM_SCANHIST : */TASK_EVENT_INIT;
|
||||
int32_t ret = streamTaskHandleEvent(pTask->status.pSM, event);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
stError("vgId:%d failed to handle event:%d", pMeta->vgId, event);
|
||||
code = ret;
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pMeta, pTaskId->streamId, pTaskId->taskId, pInfo->init, pInfo->start, false);
|
||||
}
|
||||
|
||||
streamMetaReleaseTask(pMeta, pTask);
|
||||
}
|
||||
|
||||
stInfo("vgId:%d start tasks completed", pMeta->vgId);
|
||||
taosArrayDestroy(pTaskList);
|
||||
return code;
|
||||
}
|
|
@ -117,7 +117,7 @@ int32_t getSessionWinResultBuff(SStreamFileState* pFileState, SSessionKey* pKey,
|
|||
void* pFileStore = getStateFileStore(pFileState);
|
||||
void* p = NULL;
|
||||
int32_t code_file = streamStateSessionAddIfNotExist_rocksdb(pFileStore, pKey, gap, &p, pVLen);
|
||||
if (code_file == TSDB_CODE_SUCCESS) {
|
||||
if (code_file == TSDB_CODE_SUCCESS || isFlushedState(pFileState, endTs, 0)) {
|
||||
(*pVal) = createSessionWinBuff(pFileState, pKey, p, pVLen);
|
||||
code = code_file;
|
||||
qDebug("===stream===0 get session win:%" PRId64 ",%" PRId64 " from disc, res %d", startTs, endTs, code_file);
|
||||
|
@ -449,13 +449,13 @@ int32_t sessionWinStateGetKVByCur(SStreamStateCur* pCur, SSessionKey* pKey, void
|
|||
|
||||
SSHashObj* pSessionBuff = getRowStateBuff(pCur->pStreamFileState);
|
||||
void** ppBuff = tSimpleHashGet(pSessionBuff, &pKey->groupId, sizeof(uint64_t));
|
||||
if (!ppBuff) {
|
||||
return TSDB_CODE_FAILED;
|
||||
SArray* pWinStates = NULL;
|
||||
if (ppBuff) {
|
||||
pWinStates = (SArray*)(*ppBuff);
|
||||
}
|
||||
|
||||
SArray* pWinStates = (SArray*)(*ppBuff);
|
||||
int32_t size = taosArrayGetSize(pWinStates);
|
||||
if (pCur->buffIndex >= 0) {
|
||||
int32_t size = taosArrayGetSize(pWinStates);
|
||||
if (pCur->buffIndex >= size) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
|
|
@ -48,11 +48,11 @@ static void tryLaunchHistoryTask(void* param, void* tmrId);
|
|||
static void doProcessDownstreamReadyRsp(SStreamTask* pTask);
|
||||
|
||||
int32_t streamTaskSetReady(SStreamTask* pTask) {
|
||||
char* p = NULL;
|
||||
int32_t numOfDowns = streamTaskGetNumOfDownstream(pTask);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, &p);
|
||||
char* p = NULL;
|
||||
int32_t numOfDowns = streamTaskGetNumOfDownstream(pTask);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, &p);
|
||||
|
||||
if ((status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__STREAM_SCAN_HISTORY) &&
|
||||
if ((status == TASK_STATUS__SCAN_HISTORY/* || status == TASK_STATUS__STREAM_SCAN_HISTORY*/) &&
|
||||
pTask->info.taskLevel != TASK_LEVEL__SOURCE) {
|
||||
pTask->numOfWaitingUpstream = taosArrayGetSize(pTask->upstreamInfo.pList);
|
||||
stDebug("s-task:%s level:%d task wait for %d upstream tasks complete scan-history procedure, status:%s",
|
||||
|
@ -66,9 +66,6 @@ int32_t streamTaskSetReady(SStreamTask* pTask) {
|
|||
int64_t el = (pTask->execInfo.start - pTask->execInfo.init);
|
||||
stDebug("s-task:%s all %d downstream ready, init completed, elapsed time:%" PRId64 "ms, task status:%s",
|
||||
pTask->id.idStr, numOfDowns, el, p);
|
||||
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, pTask->execInfo.init,
|
||||
pTask->execInfo.start, true);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -161,7 +158,7 @@ int32_t streamTaskStartScanHistory(SStreamTask* pTask) {
|
|||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
|
||||
ASSERT(pTask->status.downstreamReady == 1 &&
|
||||
((status == TASK_STATUS__SCAN_HISTORY) || (status == TASK_STATUS__STREAM_SCAN_HISTORY)));
|
||||
((status == TASK_STATUS__SCAN_HISTORY)/* || (status == TASK_STATUS__STREAM_SCAN_HISTORY)*/));
|
||||
|
||||
if (level == TASK_LEVEL__SOURCE) {
|
||||
return doStartScanHistoryTask(pTask);
|
||||
|
@ -209,7 +206,11 @@ void streamTaskCheckDownstream(SStreamTask* pTask) {
|
|||
|
||||
int32_t numOfVgs = taosArrayGetSize(vgInfo);
|
||||
pTask->notReadyTasks = numOfVgs;
|
||||
pTask->checkReqIds = taosArrayInit(numOfVgs, sizeof(int64_t));
|
||||
if (pTask->checkReqIds == NULL) {
|
||||
pTask->checkReqIds = taosArrayInit(numOfVgs, sizeof(int64_t));
|
||||
} else {
|
||||
taosArrayClear(pTask->checkReqIds);
|
||||
}
|
||||
|
||||
stDebug("s-task:%s check %d downstream tasks, ver:%" PRId64 "-%" PRId64 " window:%" PRId64 "-%" PRId64,
|
||||
pTask->id.idStr, numOfVgs, pRange->range.minVer, pRange->range.maxVer, pWindow->skey, pWindow->ekey);
|
||||
|
@ -312,9 +313,24 @@ int32_t streamTaskCheckStatus(SStreamTask* pTask, int32_t upstreamTaskId, int32_
|
|||
stError("s-task:%s receive check msg from upstream task:0x%x(vgId:%d), new stage received:%" PRId64
|
||||
", prev:%" PRId64,
|
||||
id, upstreamTaskId, vgId, stage, pInfo->stage);
|
||||
// record the checkpoint failure id and sent to mnode
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
if (status == TASK_STATUS__CK) {
|
||||
streamTaskSetCheckpointFailedId(pTask);
|
||||
}
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
}
|
||||
|
||||
if (pInfo->stage != stage) {
|
||||
|
||||
taosThreadMutexLock(&pTask->lock);
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, NULL);
|
||||
if (status == TASK_STATUS__CK) {
|
||||
streamTaskSetCheckpointFailedId(pTask);
|
||||
}
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
return TASK_UPSTREAM_NEW_STAGE;
|
||||
} else if (pTask->status.downstreamReady != 1) {
|
||||
stDebug("s-task:%s vgId:%d leader:%d, downstream not ready", id, vgId, (pTask->pMeta->role == NODE_ROLE_LEADER));
|
||||
|
@ -358,28 +374,44 @@ int32_t streamTaskOnScanhistoryTaskReady(SStreamTask* pTask) {
|
|||
|
||||
char* p = NULL;
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, &p);
|
||||
ASSERT(status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__STREAM_SCAN_HISTORY);
|
||||
ASSERT(status == TASK_STATUS__SCAN_HISTORY/* || status == TASK_STATUS__STREAM_SCAN_HISTORY*/);
|
||||
|
||||
stDebug("s-task:%s enter into scan-history data stage, status:%s", id, p);
|
||||
streamTaskStartScanHistory(pTask);
|
||||
|
||||
// start the related fill-history task, when current task is ready
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
if (pTask->info.fillHistory == 1) {
|
||||
stDebug("s-task:%s fill-history task enters into scan-history data stage, status:%s", id, p);
|
||||
streamTaskStartScanHistory(pTask);
|
||||
} else {
|
||||
stDebug("s-task:%s scan wal data, status:%s", id, p);
|
||||
}
|
||||
|
||||
// NOTE: there will be an deadlock if launch fill history here.
|
||||
// // start the related fill-history task, when current task is ready
|
||||
// if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
// streamLaunchFillHistoryTask(pTask);
|
||||
// }
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void doProcessDownstreamReadyRsp(SStreamTask* pTask) {
|
||||
EStreamTaskEvent event;
|
||||
if (pTask->info.fillHistory == 0) {
|
||||
event = HAS_RELATED_FILLHISTORY_TASK(pTask) ? TASK_EVENT_INIT_STREAM_SCANHIST : TASK_EVENT_INIT;
|
||||
event = /*HAS_RELATED_FILLHISTORY_TASK(pTask) ? TASK_EVENT_INIT_STREAM_SCANHIST : */TASK_EVENT_INIT;
|
||||
} else {
|
||||
event = TASK_EVENT_INIT_SCANHIST;
|
||||
}
|
||||
|
||||
streamTaskOnHandleEventSuccess(pTask->status.pSM, event);
|
||||
|
||||
int64_t initTs = pTask->execInfo.init;
|
||||
int64_t startTs = pTask->execInfo.start;
|
||||
streamMetaUpdateTaskDownstreamStatus(pTask->pMeta, pTask->id.streamId, pTask->id.taskId, initTs, startTs, true);
|
||||
|
||||
// start the related fill-history task, when current task is ready
|
||||
// not invoke in success callback due to the deadlock.
|
||||
if (HAS_RELATED_FILLHISTORY_TASK(pTask)) {
|
||||
stDebug("s-task:%s try to launch related fill-history task", pTask->id.idStr);
|
||||
streamLaunchFillHistoryTask(pTask);
|
||||
}
|
||||
}
|
||||
|
||||
static void addIntoNodeUpdateList(SStreamTask* pTask, int32_t nodeId) {
|
||||
|
@ -436,8 +468,7 @@ int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRs
|
|||
ASSERT(left >= 0);
|
||||
|
||||
if (left == 0) {
|
||||
taosArrayDestroy(pTask->checkReqIds);
|
||||
pTask->checkReqIds = NULL;
|
||||
pTask->checkReqIds = taosArrayDestroy(pTask->checkReqIds);;
|
||||
|
||||
doProcessDownstreamReadyRsp(pTask);
|
||||
} else {
|
||||
|
@ -458,8 +489,7 @@ int32_t streamProcessCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRs
|
|||
if (pRsp->status == TASK_UPSTREAM_NEW_STAGE) {
|
||||
stError("s-task:%s vgId:%d self vnode-transfer/leader-change/restart detected, old stage:%" PRId64
|
||||
", current stage:%" PRId64
|
||||
", "
|
||||
"not check wait for downstream task nodeUpdate, and all tasks restart",
|
||||
", not check wait for downstream task nodeUpdate, and all tasks restart",
|
||||
id, pRsp->upstreamNodeId, pRsp->oldStage, pTask->pMeta->stage);
|
||||
addIntoNodeUpdateList(pTask, pRsp->upstreamNodeId);
|
||||
} else {
|
||||
|
@ -605,7 +635,7 @@ int32_t streamProcessScanHistoryFinishReq(SStreamTask* pTask, SStreamScanHistory
|
|||
char* p = NULL;
|
||||
ETaskStatus status = streamTaskGetStatus(pTask, &p);
|
||||
|
||||
if (status != TASK_STATUS__SCAN_HISTORY && status != TASK_STATUS__STREAM_SCAN_HISTORY) {
|
||||
if (status != TASK_STATUS__SCAN_HISTORY /*&& status != TASK_STATUS__STREAM_SCAN_HISTORY*/) {
|
||||
stError("s-task:%s not in scan-history status, status:%s return upstream:0x%x scan-history finish directly", id, p,
|
||||
pReq->upstreamTaskId);
|
||||
|
||||
|
@ -667,7 +697,7 @@ int32_t streamProcessScanHistoryFinishRsp(SStreamTask* pTask) {
|
|||
return TSDB_CODE_INVALID_MSG;
|
||||
}
|
||||
|
||||
ASSERT(status == TASK_STATUS__SCAN_HISTORY || status == TASK_STATUS__STREAM_SCAN_HISTORY);
|
||||
ASSERT(status == TASK_STATUS__SCAN_HISTORY/* || status == TASK_STATUS__STREAM_SCAN_HISTORY*/);
|
||||
SStreamMeta* pMeta = pTask->pMeta;
|
||||
|
||||
// execute in the scan history complete call back msg, ready to process data from inputQ
|
||||
|
@ -1096,19 +1126,23 @@ int32_t streamMetaUpdateTaskDownstreamStatus(SStreamMeta* pMeta, int64_t streamI
|
|||
pStartInfo->readyTs = taosGetTimestampMs();
|
||||
pStartInfo->elapsedTime = (pStartInfo->startTs != 0) ? pStartInfo->readyTs - pStartInfo->startTs : 0;
|
||||
|
||||
stDebug("vgId:%d all %d task(s) check downstream completed, last completed task:0x%x startTs:%" PRId64
|
||||
stDebug("vgId:%d all %d task(s) check downstream completed, last completed task:0x%x (succ:%d) startTs:%" PRId64
|
||||
", readyTs:%" PRId64 " total elapsed time:%.2fs",
|
||||
pMeta->vgId, numOfTotal, taskId, pStartInfo->startTs, pStartInfo->readyTs,
|
||||
pMeta->vgId, numOfTotal, taskId, ready, pStartInfo->startTs, pStartInfo->readyTs,
|
||||
pStartInfo->elapsedTime / 1000.0);
|
||||
|
||||
// print the initialization elapsed time and info
|
||||
displayStatusInfo(pMeta, pStartInfo->pReadyTaskSet, true);
|
||||
displayStatusInfo(pMeta, pStartInfo->pFailedTaskSet, false);
|
||||
streamMetaResetStartInfo(pStartInfo);
|
||||
streamMetaWUnLock(pMeta);
|
||||
|
||||
pStartInfo->completeFn(pMeta);
|
||||
} else {
|
||||
stDebug("vgId:%d recv check down results:%d, total:%d", pMeta->vgId, numOfRecv, numOfTotal);
|
||||
streamMetaWUnLock(pMeta);
|
||||
stDebug("vgId:%d recv check downstream results, s-task:0x%x succ:%d, received:%d, total:%d", pMeta->vgId, taskId,
|
||||
ready, numOfRecv, numOfTotal);
|
||||
}
|
||||
|
||||
streamMetaWUnLock(pMeta);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -796,5 +796,6 @@ void streamTaskStatusCopy(STaskStatusEntry* pDst, const STaskStatusEntry* pSrc)
|
|||
pDst->sinkDataSize = pSrc->sinkDataSize;
|
||||
pDst->activeCheckpointId = pSrc->activeCheckpointId;
|
||||
pDst->checkpointFailed = pSrc->checkpointFailed;
|
||||
pDst->chkpointTransId = pSrc->chkpointTransId;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,14 +31,14 @@ SStreamTaskState StreamTaskStatusList[9] = {
|
|||
{.state = TASK_STATUS__HALT, .name = "halt"},
|
||||
{.state = TASK_STATUS__PAUSE, .name = "paused"},
|
||||
{.state = TASK_STATUS__CK, .name = "checkpoint"},
|
||||
{.state = TASK_STATUS__STREAM_SCAN_HISTORY, .name = "stream-scan-history"},
|
||||
// {.state = TASK_STATUS__STREAM_SCAN_HISTORY, .name = "stream-scan-history"},
|
||||
};
|
||||
|
||||
SStreamEventInfo StreamTaskEventList[12] = {
|
||||
{.event = 0, .name = ""}, // dummy event, place holder
|
||||
{.event = TASK_EVENT_INIT, .name = "initialize"},
|
||||
{.event = TASK_EVENT_INIT_SCANHIST, .name = "scan-history-init"},
|
||||
{.event = TASK_EVENT_INIT_STREAM_SCANHIST, .name = "stream-scan-history-init"},
|
||||
// {.event = TASK_EVENT_INIT_STREAM_SCANHIST, .name = "stream-scan-history-init"},
|
||||
{.event = TASK_EVENT_SCANHIST_DONE, .name = "scan-history-completed"},
|
||||
{.event = TASK_EVENT_STOP, .name = "stopping"},
|
||||
{.event = TASK_EVENT_GEN_CHECKPOINT, .name = "checkpoint"},
|
||||
|
@ -110,12 +110,12 @@ int32_t streamTaskKeepCurrentVerInWal(SStreamTask* pTask) {
|
|||
|
||||
// todo check rsp code for handle Event:TASK_EVENT_SCANHIST_DONE
|
||||
static bool isInvalidStateTransfer(ETaskStatus state, const EStreamTaskEvent event) {
|
||||
if (event == TASK_EVENT_INIT_STREAM_SCANHIST || event == TASK_EVENT_INIT || event == TASK_EVENT_INIT_SCANHIST) {
|
||||
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);
|
||||
return (state != TASK_STATUS__SCAN_HISTORY/* && state != TASK_STATUS__STREAM_SCAN_HISTORY*/);
|
||||
}
|
||||
|
||||
if (event == TASK_EVENT_GEN_CHECKPOINT) {
|
||||
|
@ -160,6 +160,45 @@ static STaskStateTrans* streamTaskFindTransform(ETaskStatus state, const EStream
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t doHandleWaitingEvent(SStreamTaskSM* pSM, const char* pEventName, SStreamTask* pTask) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int64_t el = (taosGetTimestampMs() - pSM->startTs);
|
||||
stDebug("s-task:%s handle event:%s completed, elapsed time:%" PRId64 "ms state:%s -> %s", pTask->id.idStr,
|
||||
pEventName, 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,
|
||||
GET_EVT_NAME(pEvtInfo->event), pSM->current.name);
|
||||
|
||||
// remove it
|
||||
taosArrayPop(pSM->pWaitingEventList);
|
||||
|
||||
STaskStateTrans* pNextTrans = streamTaskFindTransform(pSM->current.state, pEvtInfo->event);
|
||||
ASSERT(pSM->pActiveTrans == NULL && pNextTrans != NULL);
|
||||
|
||||
pSM->pActiveTrans = pNextTrans;
|
||||
pSM->startTs = taosGetTimestampMs();
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
code = pNextTrans->pAction(pSM->pTask);
|
||||
if (pNextTrans->autoInvokeEndFn) {
|
||||
return streamTaskOnHandleEventSuccess(pSM, pNextTrans->event);
|
||||
} 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, GET_EVT_NAME(pEvtInfo->event),
|
||||
StreamTaskStatusList[pEvtInfo->status].name);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void streamTaskRestoreStatus(SStreamTask* pTask) {
|
||||
SStreamTaskSM* pSM = pTask->status.pSM;
|
||||
|
||||
|
@ -175,7 +214,13 @@ void streamTaskRestoreStatus(SStreamTask* pTask) {
|
|||
pSM->prev.evt = 0;
|
||||
|
||||
pSM->startTs = taosGetTimestampMs();
|
||||
stDebug("s-task:%s restore status, %s -> %s", pTask->id.idStr, pSM->prev.state.name, pSM->current.name);
|
||||
|
||||
if (taosArrayGetSize(pSM->pWaitingEventList) > 0) {
|
||||
stDebug("s-task:%s restore status, %s -> %s, and then handle waiting event", pTask->id.idStr, pSM->prev.state.name, pSM->current.name);
|
||||
doHandleWaitingEvent(pSM, "restore-pause/halt", pTask);
|
||||
} else {
|
||||
stDebug("s-task:%s restore status, %s -> %s", pTask->id.idStr, pSM->prev.state.name, pSM->current.name);
|
||||
}
|
||||
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
}
|
||||
|
@ -233,10 +278,10 @@ static int32_t doHandleEvent(SStreamTaskSM* pSM, EStreamTaskEvent event, STaskSt
|
|||
ETaskStatus s = streamTaskGetStatus(pTask, NULL);
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
if ((s == pTrans->next.state) && (pSM->prev.evt == pTrans->event)) {
|
||||
if ((s == pTrans->next.state) && (pSM->prev.evt == pTrans->event)) {// this event has been handled already
|
||||
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
|
||||
} else if (s != TASK_STATUS__DROPPING && s != TASK_STATUS__STOP && s != TASK_STATUS__UNINIT) {
|
||||
stDebug("s-task:%s not handle event:%s yet, wait for 100ms and recheck", id, GET_EVT_NAME(event));
|
||||
taosMsleep(100);
|
||||
} else {
|
||||
|
@ -343,39 +388,7 @@ int32_t streamTaskOnHandleEventSuccess(SStreamTaskSM* pSM, EStreamTaskEvent even
|
|||
pTrans->pSuccAction(pTask);
|
||||
|
||||
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,
|
||||
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,
|
||||
GET_EVT_NAME(pEvtInfo->event), pSM->current.name);
|
||||
|
||||
// remove it
|
||||
taosArrayPop(pSM->pWaitingEventList);
|
||||
|
||||
STaskStateTrans* pNextTrans = streamTaskFindTransform(pSM->current.state, pEvtInfo->event);
|
||||
ASSERT(pSM->pActiveTrans == NULL && pNextTrans != NULL);
|
||||
|
||||
pSM->pActiveTrans = pNextTrans;
|
||||
pSM->startTs = taosGetTimestampMs();
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
int32_t code = pNextTrans->pAction(pSM->pTask);
|
||||
if (pNextTrans->autoInvokeEndFn) {
|
||||
return streamTaskOnHandleEventSuccess(pSM, pNextTrans->event);
|
||||
} 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, GET_EVT_NAME(pEvtInfo->event),
|
||||
StreamTaskStatusList[pEvtInfo->status].name);
|
||||
}
|
||||
doHandleWaitingEvent(pSM, GET_EVT_NAME(pTrans->event), pTask);
|
||||
} else {
|
||||
taosThreadMutexUnlock(&pTask->lock);
|
||||
|
||||
|
@ -469,14 +482,14 @@ void doInitStateTransferTable(void) {
|
|||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__UNINIT, TASK_STATUS__SCAN_HISTORY, TASK_EVENT_INIT_SCANHIST, streamTaskInitStatus, streamTaskOnScanhistoryTaskReady, false, false);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__UNINIT, TASK_STATUS__STREAM_SCAN_HISTORY, TASK_EVENT_INIT_STREAM_SCANHIST, streamTaskInitStatus, streamTaskOnScanhistoryTaskReady, false, false);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__UNINIT, TASK_STATUS__STREAM_SCAN_HISTORY, TASK_EVENT_INIT_STREAM_SCANHIST, streamTaskInitStatus, streamTaskOnScanhistoryTaskReady, false, false);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
|
||||
// scan-history related event
|
||||
trans = createStateTransform(TASK_STATUS__SCAN_HISTORY, TASK_STATUS__READY, TASK_EVENT_SCANHIST_DONE, NULL, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__READY, TASK_EVENT_SCANHIST_DONE, NULL, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__READY, TASK_EVENT_SCANHIST_DONE, NULL, NULL, NULL, true);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
|
||||
// halt stream task, from other task status
|
||||
trans = createStateTransform(TASK_STATUS__READY, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, streamTaskKeepCurrentVerInWal, NULL, true);
|
||||
|
@ -486,8 +499,8 @@ void doInitStateTransferTable(void) {
|
|||
|
||||
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);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, streamTaskKeepCurrentVerInWal, &info, true);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__CK, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, streamTaskKeepCurrentVerInWal, &info, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__PAUSE, TASK_STATUS__HALT, TASK_EVENT_HALT, NULL, streamTaskKeepCurrentVerInWal, NULL, true);
|
||||
|
@ -506,8 +519,8 @@ void doInitStateTransferTable(void) {
|
|||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
|
||||
info = (SAttachedEventInfo){.status = TASK_STATUS__READY, .event = TASK_EVENT_PAUSE};
|
||||
trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__PAUSE, TASK_EVENT_PAUSE, NULL, NULL, &info, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__PAUSE, TASK_EVENT_PAUSE, NULL, NULL, &info, true);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__CK, TASK_STATUS__PAUSE, TASK_EVENT_PAUSE, NULL, NULL, &info, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__HALT, TASK_STATUS__PAUSE, TASK_EVENT_PAUSE, NULL, NULL, &info, true);
|
||||
|
@ -541,8 +554,8 @@ void doInitStateTransferTable(void) {
|
|||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__CK, TASK_STATUS__STOP, TASK_EVENT_STOP, NULL, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__STOP, TASK_EVENT_STOP, NULL, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__STOP, TASK_EVENT_STOP, NULL, NULL, NULL, true);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
|
||||
// dropping related event
|
||||
trans = createStateTransform(TASK_STATUS__READY, TASK_STATUS__DROPPING, TASK_EVENT_DROPPING, NULL, NULL, NULL, true);
|
||||
|
@ -561,7 +574,7 @@ void doInitStateTransferTable(void) {
|
|||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__CK, TASK_STATUS__DROPPING, TASK_EVENT_DROPPING, streamTaskSendTransSuccessMsg, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__DROPPING, TASK_EVENT_DROPPING, NULL, NULL, NULL, true);
|
||||
taosArrayPush(streamTaskSMTrans, &trans);
|
||||
// trans = createStateTransform(TASK_STATUS__STREAM_SCAN_HISTORY, TASK_STATUS__DROPPING, TASK_EVENT_DROPPING, NULL, NULL, NULL, true);
|
||||
// taosArrayPush(streamTaskSMTrans, &trans);
|
||||
}
|
||||
//clang-format on
|
|
@ -1162,9 +1162,12 @@ int32_t syncNodeRestore(SSyncNode* pSyncNode) {
|
|||
ASSERTS(pSyncNode->pLogStore != NULL, "log store not created");
|
||||
ASSERTS(pSyncNode->pLogBuf != NULL, "ring log buffer not created");
|
||||
|
||||
taosThreadMutexLock(&pSyncNode->pLogBuf->mutex);
|
||||
SyncIndex lastVer = pSyncNode->pLogStore->syncLogLastIndex(pSyncNode->pLogStore);
|
||||
SyncIndex commitIndex = pSyncNode->pLogStore->syncLogCommitIndex(pSyncNode->pLogStore);
|
||||
SyncIndex endIndex = pSyncNode->pLogBuf->endIndex;
|
||||
taosThreadMutexUnlock(&pSyncNode->pLogBuf->mutex);
|
||||
|
||||
if (lastVer != -1 && endIndex != lastVer + 1) {
|
||||
terrno = TSDB_CODE_WAL_LOG_INCOMPLETE;
|
||||
sError("vgId:%d, failed to restore sync node since %s. expected lastLogIndex:%" PRId64 ", lastVer:%" PRId64 "",
|
||||
|
|
|
@ -558,22 +558,31 @@ int32_t syncFsmExecute(SSyncNode* pNode, SSyncFSM* pFsm, ESyncState role, SyncTe
|
|||
pEntry->term);
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg = {.code = applyCode};
|
||||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
int32_t code = 0;
|
||||
bool retry = false;
|
||||
do {
|
||||
SRpcMsg rpcMsg = {.code = applyCode};
|
||||
syncEntry2OriginalRpc(pEntry, &rpcMsg);
|
||||
|
||||
SFsmCbMeta cbMeta = {0};
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(pNode, pEntry->index);
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
cbMeta.code = applyCode;
|
||||
cbMeta.state = role;
|
||||
cbMeta.seqNum = pEntry->seqNum;
|
||||
cbMeta.term = pEntry->term;
|
||||
cbMeta.currentTerm = term;
|
||||
cbMeta.flag = -1;
|
||||
SFsmCbMeta cbMeta = {0};
|
||||
cbMeta.index = pEntry->index;
|
||||
cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(pNode, pEntry->index);
|
||||
cbMeta.isWeak = pEntry->isWeak;
|
||||
cbMeta.code = applyCode;
|
||||
cbMeta.state = role;
|
||||
cbMeta.seqNum = pEntry->seqNum;
|
||||
cbMeta.term = pEntry->term;
|
||||
cbMeta.currentTerm = term;
|
||||
cbMeta.flag = -1;
|
||||
|
||||
(void)syncRespMgrGetAndDel(pNode->pSyncRespMgr, cbMeta.seqNum, &rpcMsg.info);
|
||||
int32_t code = pFsm->FpCommitCb(pFsm, &rpcMsg, &cbMeta);
|
||||
(void)syncRespMgrGetAndDel(pNode->pSyncRespMgr, cbMeta.seqNum, &rpcMsg.info);
|
||||
code = pFsm->FpCommitCb(pFsm, &rpcMsg, &cbMeta);
|
||||
retry = (code != 0) && (terrno == TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE);
|
||||
if (retry) {
|
||||
taosMsleep(10);
|
||||
sError("vgId:%d, retry on fsm commit since %s. index:%" PRId64, pNode->vgId, terrstr(), pEntry->index);
|
||||
}
|
||||
} while (retry);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -806,6 +806,13 @@ static int32_t syncNodeOnSnapshotBegin(SSyncNode *pSyncNode, SyncSnapshotSend *p
|
|||
goto _SEND_REPLY;
|
||||
}
|
||||
|
||||
SyncIndex beginIndex = syncNodeGetSnapBeginIndex(pSyncNode);
|
||||
if (pReceiver->snapshotParam.start != beginIndex) {
|
||||
sRError(pReceiver, "snapshot begin index is changed unexpectedly. sver:%" PRId64 ", beginIndex:%" PRId64,
|
||||
pReceiver->snapshotParam.start, beginIndex);
|
||||
goto _SEND_REPLY;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
_SEND_REPLY:
|
||||
if (code != 0 && terrno != 0) {
|
||||
|
@ -1087,7 +1094,10 @@ static int32_t syncSnapSenderExchgSnapInfo(SSyncNode *pSyncNode, SSyncSnapshotSe
|
|||
|
||||
// sender
|
||||
static int32_t syncNodeOnSnapshotPrepRsp(SSyncNode *pSyncNode, SSyncSnapshotSender *pSender, SyncSnapshotRsp *pMsg) {
|
||||
int32_t code = -1;
|
||||
SSnapshot snapshot = {0};
|
||||
|
||||
taosThreadMutexLock(&pSender->pSndBuf->mutex);
|
||||
pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, &snapshot);
|
||||
|
||||
// prepare <begin, end>
|
||||
|
@ -1103,20 +1113,24 @@ static int32_t syncNodeOnSnapshotPrepRsp(SSyncNode *pSyncNode, SSyncSnapshotSend
|
|||
// start reader
|
||||
if (pMsg->payloadType == TDMT_SYNC_PREP_SNAPSHOT_REPLY) {
|
||||
if (syncSnapSenderExchgSnapInfo(pSyncNode, pSender, pMsg) != 0) {
|
||||
return -1;
|
||||
goto _out;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code = pSyncNode->pFsm->FpSnapshotStartRead(pSyncNode->pFsm, &pSender->snapshotParam, &pSender->pReader);
|
||||
code = pSyncNode->pFsm->FpSnapshotStartRead(pSyncNode->pFsm, &pSender->snapshotParam, &pSender->pReader);
|
||||
if (code != 0) {
|
||||
sSError(pSender, "prepare snapshot failed since %s", terrstr());
|
||||
return -1;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
// update next index
|
||||
syncIndexMgrSetIndex(pSyncNode->pNextIndex, &pMsg->srcId, snapshot.lastApplyIndex + 1);
|
||||
|
||||
return snapshotSend(pSender);
|
||||
code = snapshotSend(pSender);
|
||||
|
||||
_out:
|
||||
taosThreadMutexUnlock(&pSender->pSndBuf->mutex);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t snapshotSenderSignatureCmp(SSyncSnapshotSender *pSender, SyncSnapshotRsp *pMsg) {
|
||||
|
|
|
@ -259,11 +259,6 @@ int32_t walFetchHead(SWalReader *pRead, int64_t ver) {
|
|||
int64_t contLen;
|
||||
bool seeked = false;
|
||||
|
||||
wDebug("vgId:%d, try to fetch ver %" PRId64 ", first ver:%" PRId64 ", commit ver:%" PRId64 ", last ver:%" PRId64
|
||||
", applied ver:%" PRId64", 0x%"PRIx64,
|
||||
pRead->pWal->cfg.vgId, ver, pRead->pWal->vers.firstVer, pRead->pWal->vers.commitVer, pRead->pWal->vers.lastVer,
|
||||
pRead->pWal->vers.appliedVer, pRead->readerId);
|
||||
|
||||
// TODO: valid ver
|
||||
if (ver > pRead->pWal->vers.commitVer) {
|
||||
return -1;
|
||||
|
|
|
@ -72,7 +72,7 @@ TEST(osTest, osSystem) {
|
|||
const int sysLen = 64;
|
||||
char osSysName[sysLen];
|
||||
int ret = taosGetOsReleaseName(osSysName, NULL, NULL, sysLen);
|
||||
printf("os systeme name:%s\n", osSysName);
|
||||
printf("os system name:%s\n", osSysName);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1070,6 +1070,11 @@ int32_t patternMatch(const char *pattern, size_t psize, const char *str, size_t
|
|||
return TSDB_PATTERN_MATCH; /* "*" at the end of the pattern matches */
|
||||
}
|
||||
|
||||
if (c == '\\' && (pattern[i] == '_' || pattern[i] == '%')) {
|
||||
c = pattern[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
char rejectList[2] = {toupper(c), tolower(c)};
|
||||
|
||||
str += nMatchChar;
|
||||
|
@ -1139,6 +1144,11 @@ int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str,
|
|||
return TSDB_PATTERN_MATCH;
|
||||
}
|
||||
|
||||
if (c == '\\' && (pattern[i] == '_' || pattern[i] == '%')) {
|
||||
c = pattern[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
TdUcs4 rejectList[2] = {towupper(c), towlower(c)};
|
||||
|
||||
str += nMatchChar;
|
||||
|
@ -1166,7 +1176,8 @@ int32_t wcsPatternMatch(const TdUcs4 *pattern, size_t psize, const TdUcs4 *str,
|
|||
c1 = str[j++];
|
||||
nMatchChar++;
|
||||
|
||||
if (c == L'\\' && pattern[i] == L'_' && c1 == L'_') {
|
||||
if (c == '\\' && pattern[i] == c1 &&
|
||||
(c1 == '_' || c1 == '%')) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -286,6 +286,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_CLOG_IS_NULL, "Transaction commitlog
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_NETWORK_UNAVAILL, "Unable to establish connection While execute transaction and will continue in the background")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_LAST_TRANS_NOT_FINISHED, "Last Transaction not finished")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_SYNC_TIMEOUT, "Sync timeout While execute transaction and will continue in the background")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_CTX_SWITCH, "Transaction context switch")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_TRANS_UNKNOW_ERROR, "Unknown transaction error")
|
||||
|
||||
// mnode-mq
|
||||
|
|
|
@ -337,14 +337,10 @@ static int32_t taosOpenNewLogFile() {
|
|||
}
|
||||
|
||||
void taosResetLog() {
|
||||
char lastName[LOG_FILE_NAME_LEN + 20];
|
||||
sprintf(lastName, "%s.%d", tsLogObj.logName, tsLogObj.flag);
|
||||
|
||||
// force create a new log file
|
||||
tsLogObj.lines = tsNumOfLogLines + 10;
|
||||
|
||||
taosOpenNewLogFile();
|
||||
(void)taosRemoveFile(lastName);
|
||||
|
||||
uInfo("==================================");
|
||||
uInfo(" reset log file ");
|
||||
|
|
|
@ -76,6 +76,16 @@ TEST(utilTest, wchar_pattern_match_test) {
|
|||
const TdWchar* str12 = L"";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern12), 4, reinterpret_cast<const TdUcs4*>(str12), 0, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
||||
|
||||
const TdWchar* pattern13 = L"%\\_6 ";
|
||||
const TdWchar* str13 = L"6a6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern13), 6, reinterpret_cast<const TdUcs4*>(str13), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||
|
||||
const TdWchar* pattern14 = L"%\\%6 ";
|
||||
const TdWchar* str14 = L"6a6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern14), 6, reinterpret_cast<const TdUcs4*>(str14), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||
}
|
||||
|
||||
TEST(utilTest, wchar_pattern_match_no_terminated) {
|
||||
|
@ -126,14 +136,24 @@ TEST(utilTest, wchar_pattern_match_no_terminated) {
|
|||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern8), 8, reinterpret_cast<const TdUcs4*>(str8), 6, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||
|
||||
const TdWchar* pattern9 = L"6\\_6 ";
|
||||
const TdWchar* pattern9 = L"6\\_6 ";
|
||||
const TdWchar* str9 = L"6_6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern9), 4, reinterpret_cast<const TdUcs4*>(str9), 3, &pInfo);
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern9), 6, reinterpret_cast<const TdUcs4*>(str9), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const TdWchar* pattern10 = L"% ";
|
||||
const TdWchar* str10 = L"6_6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern10), 1, reinterpret_cast<const TdUcs4*>(str10), 3, &pInfo);
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern10), 2, reinterpret_cast<const TdUcs4*>(str10), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const TdWchar* pattern11 = L"%\\_6 ";
|
||||
const TdWchar* str11 = L"6_6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern11), 6, reinterpret_cast<const TdUcs4*>(str11), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const TdWchar* pattern12 = L"%\\%6 ";
|
||||
const TdWchar* str12 = L"6%6 ";
|
||||
ret = wcsPatternMatch(reinterpret_cast<const TdUcs4*>(pattern12), 6, reinterpret_cast<const TdUcs4*>(str12), 4, &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
}
|
||||
|
||||
|
@ -209,6 +229,36 @@ TEST(utilTest, char_pattern_match_test) {
|
|||
const char* str13 = "a%c";
|
||||
ret = patternMatch(pattern13, 5, str13, strlen(str13), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const char* pattern14 = "%a\\%c";
|
||||
const char* str14 = "a%c";
|
||||
ret = patternMatch(pattern14, strlen(pattern14), str14, strlen(str14), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const char* pattern15 = "_a\\%c";
|
||||
const char* str15 = "ba%c";
|
||||
ret = patternMatch(pattern15, strlen(pattern15), str15, strlen(str15), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const char* pattern16 = "_\\%c";
|
||||
const char* str16 = "a%c";
|
||||
ret = patternMatch(pattern16, strlen(pattern16), str16, strlen(str16), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_MATCH);
|
||||
|
||||
const char* pattern17 = "_\\%c";
|
||||
const char* str17 = "ba%c";
|
||||
ret = patternMatch(pattern17, strlen(pattern17), str17, strlen(str17), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOMATCH);
|
||||
|
||||
const char* pattern18 = "%\\%c";
|
||||
const char* str18 = "abc";
|
||||
ret = patternMatch(pattern18, strlen(pattern18), str18, strlen(str18), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||
|
||||
const char* pattern19 = "%\\_c";
|
||||
const char* str19 = "abc";
|
||||
ret = patternMatch(pattern19, strlen(pattern19), str19, strlen(str19), &pInfo);
|
||||
ASSERT_EQ(ret, TSDB_PATTERN_NOWILDCARDMATCH);
|
||||
}
|
||||
|
||||
TEST(utilTest, char_pattern_match_no_terminated) {
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"filetype": "insert",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 2000,
|
||||
"thread_count": 2,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
"databases": [
|
||||
{
|
||||
"dbinfo": {
|
||||
"name": "db",
|
||||
"drop": "yes",
|
||||
"vgroups": 2,
|
||||
"replica": 3,
|
||||
"duration":"1d",
|
||||
"wal_retention_period": 1,
|
||||
"wal_retention_size": 1,
|
||||
"keep": "3d,6d,30d"
|
||||
},
|
||||
"super_tables": [
|
||||
{
|
||||
"name": "stb",
|
||||
"child_table_exists": "no",
|
||||
"childtable_count": 10,
|
||||
"insert_rows": 100000,
|
||||
"childtable_prefix": "d",
|
||||
"insert_mode": "taosc",
|
||||
"timestamp_step": 10000,
|
||||
"start_timestamp":"now-12d",
|
||||
"columns": [
|
||||
{ "type": "bool", "name": "bc"},
|
||||
{ "type": "float", "name": "fc" },
|
||||
{ "type": "double", "name": "dc"},
|
||||
{ "type": "tinyint", "name": "ti"},
|
||||
{ "type": "smallint", "name": "si" },
|
||||
{ "type": "int", "name": "ic" },
|
||||
{ "type": "bigint", "name": "bi" },
|
||||
{ "type": "utinyint", "name": "uti"},
|
||||
{ "type": "usmallint", "name": "usi"},
|
||||
{ "type": "uint", "name": "ui" },
|
||||
{ "type": "ubigint", "name": "ubi"},
|
||||
{ "type": "binary", "name": "bin", "len": 16},
|
||||
{ "type": "nchar", "name": "nch", "len": 32}
|
||||
],
|
||||
"tags": [
|
||||
{"type": "tinyint", "name": "groupid","max": 10,"min": 1},
|
||||
{"name": "location","type": "binary", "len": 16, "values":
|
||||
["San Francisco", "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View","Sunnyvale", "Santa Clara", "Cupertino"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import time
|
||||
import random
|
||||
|
||||
import taos
|
||||
import frame
|
||||
import frame.etool
|
||||
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
||||
|
||||
def insertData(self):
|
||||
tdLog.info(f"insert data.")
|
||||
# taosBenchmark run
|
||||
jfile = etool.curFile(__file__, "snapshot.json")
|
||||
etool.runBenchmark(json=jfile)
|
||||
|
||||
tdSql.execute(f"use {self.db}")
|
||||
# set insert data information
|
||||
self.childtable_count = 10
|
||||
self.insert_rows = 100000
|
||||
self.timestamp_step = 10000
|
||||
|
||||
def doAction(self):
|
||||
tdLog.info(f"do action.")
|
||||
self.flushDb()
|
||||
|
||||
# split vgroups
|
||||
self.splitVGroups()
|
||||
self.trimDb()
|
||||
self.checkAggCorrect()
|
||||
|
||||
# balance vgroups
|
||||
self.balanceVGroupLeader()
|
||||
|
||||
# replica to 1
|
||||
self.alterReplica(1)
|
||||
self.checkAggCorrect()
|
||||
self.compactDb()
|
||||
self.alterReplica(3)
|
||||
|
||||
vgids = self.getVGroup(self.db)
|
||||
selid = random.choice(vgids)
|
||||
self.balanceVGroupLeaderOn(selid)
|
||||
|
||||
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
|
||||
# insert data
|
||||
self.insertData()
|
||||
|
||||
# check insert data correct
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# save
|
||||
self.snapshotAgg()
|
||||
|
||||
# do action
|
||||
self.doAction()
|
||||
|
||||
# check save agg result correct
|
||||
self.checkAggCorrect()
|
||||
|
||||
# check insert correct again
|
||||
self.checkInsertCorrect()
|
||||
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"filetype": "insert",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 2000,
|
||||
"thread_count": 2,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
"databases": [
|
||||
{
|
||||
"dbinfo": {
|
||||
"name": "db",
|
||||
"drop": "yes",
|
||||
"vgroups": 2,
|
||||
"replica": 1,
|
||||
"duration":"1d",
|
||||
"keep": "3d,6d,30d"
|
||||
},
|
||||
"super_tables": [
|
||||
{
|
||||
"name": "stb",
|
||||
"child_table_exists": "no",
|
||||
"childtable_count": 4,
|
||||
"insert_rows": 1000000,
|
||||
"childtable_prefix": "d",
|
||||
"insert_mode": "taosc",
|
||||
"timestamp_step": 1000,
|
||||
"start_timestamp":"now-12d",
|
||||
"columns": [
|
||||
{ "type": "bool", "name": "bc"},
|
||||
{ "type": "float", "name": "fc" },
|
||||
{ "type": "double", "name": "dc"},
|
||||
{ "type": "tinyint", "name": "ti", "values":["1"]},
|
||||
{ "type": "smallint", "name": "si" },
|
||||
{ "type": "int", "name": "ic" },
|
||||
{ "type": "bigint", "name": "bi" },
|
||||
{ "type": "utinyint", "name": "uti"},
|
||||
{ "type": "usmallint", "name": "usi"},
|
||||
{ "type": "uint", "name": "ui" },
|
||||
{ "type": "ubigint", "name": "ubi"},
|
||||
{ "type": "binary", "name": "bin", "len": 32},
|
||||
{ "type": "nchar", "name": "nch", "len": 64}
|
||||
],
|
||||
"tags": [
|
||||
{"type": "tinyint", "name": "groupid","max": 10,"min": 1},
|
||||
{"name": "location","type": "binary", "len": 16, "values":
|
||||
["San Francisco", "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View","Sunnyvale", "Santa Clara", "Cupertino"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -15,26 +15,62 @@ import sys
|
|||
import time
|
||||
|
||||
import taos
|
||||
import frame
|
||||
import frame.etool
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame import *
|
||||
|
||||
class TDTestCase:
|
||||
# init
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
class TDTestCase(TBase):
|
||||
|
||||
|
||||
def insertData(self):
|
||||
tdLog.info(f"insert data.")
|
||||
# taosBenchmark run
|
||||
json = etool.curFile(__file__, "mlevel_basic.json")
|
||||
etool.runBenchmark(json=json)
|
||||
|
||||
tdSql.execute(f"use {self.db}")
|
||||
# set insert data information
|
||||
self.childtable_count = 4
|
||||
self.insert_rows = 1000000
|
||||
self.timestamp_step = 1000
|
||||
|
||||
def doAction(self):
|
||||
tdLog.info(f"do action.")
|
||||
self.flushDb()
|
||||
self.trimDb()
|
||||
self.compactDb()
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
# check two db query result same
|
||||
tdLog.info(f"hello world.")
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
|
||||
# insert data
|
||||
self.insertData()
|
||||
|
||||
# check insert data correct
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# save
|
||||
self.snapshotAgg()
|
||||
|
||||
# do action
|
||||
self.doAction()
|
||||
|
||||
# check save agg result correct
|
||||
self.checkAggCorrect()
|
||||
|
||||
# check insert correct again
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# stop
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"filetype": "insert",
|
||||
"cfgdir": "/etc/taos",
|
||||
"host": "127.0.0.1",
|
||||
"port": 6030,
|
||||
"user": "root",
|
||||
"password": "taosdata",
|
||||
"connection_pool_size": 8,
|
||||
"num_of_records_per_req": 2000,
|
||||
"thread_count": 2,
|
||||
"create_table_thread_count": 1,
|
||||
"confirm_parameter_prompt": "no",
|
||||
"databases": [
|
||||
{
|
||||
"dbinfo": {
|
||||
"name": "db",
|
||||
"drop": "yes",
|
||||
"vgroups": 2,
|
||||
"replica": 1,
|
||||
"duration":"1d",
|
||||
"keep": "3d,6d,30d"
|
||||
},
|
||||
"super_tables": [
|
||||
{
|
||||
"name": "stb",
|
||||
"child_table_exists": "no",
|
||||
"childtable_count": 4,
|
||||
"insert_rows": 1000000,
|
||||
"childtable_prefix": "d",
|
||||
"insert_mode": "taosc",
|
||||
"timestamp_step": 1000,
|
||||
"start_timestamp":"now-13d",
|
||||
"columns": [
|
||||
{ "type": "bool", "name": "bc"},
|
||||
{ "type": "float", "name": "fc" },
|
||||
{ "type": "double", "name": "dc"},
|
||||
{ "type": "tinyint", "name": "ti", "values":["1"]},
|
||||
{ "type": "smallint", "name": "si" },
|
||||
{ "type": "int", "name": "ic" },
|
||||
{ "type": "bigint", "name": "bi" },
|
||||
{ "type": "utinyint", "name": "uti"},
|
||||
{ "type": "usmallint", "name": "usi"},
|
||||
{ "type": "uint", "name": "ui" },
|
||||
{ "type": "ubigint", "name": "ubi"},
|
||||
{ "type": "binary", "name": "bin", "len": 32},
|
||||
{ "type": "nchar", "name": "nch", "len": 64}
|
||||
],
|
||||
"tags": [
|
||||
{"type": "tinyint", "name": "groupid","max": 10,"min": 1},
|
||||
{"name": "location","type": "binary", "len": 16, "values":
|
||||
["San Francisco", "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View","Sunnyvale", "Santa Clara", "Cupertino"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
import taos
|
||||
import frame
|
||||
import frame.etool
|
||||
import frame.eos
|
||||
|
||||
from frame.log import *
|
||||
from frame.cases import *
|
||||
from frame.sql import *
|
||||
from frame.caseBase import *
|
||||
from frame.srvCtl import *
|
||||
from frame import *
|
||||
from frame.eos import *
|
||||
|
||||
#
|
||||
# 192.168.1.52 MINIO S3 API KEY: MQCEIoaPGUs1mhXgpUAu:XTgpN2dEMInnYgqN4gj3G5zgb39ROtsisKKy0GFa
|
||||
#
|
||||
|
||||
'''
|
||||
s3EndPoint http://192.168.1.52:9000
|
||||
s3AccessKey MQCEIoaPGUs1mhXgpUAu:XTgpN2dEMInnYgqN4gj3G5zgb39ROtsisKKy0GFa
|
||||
s3BucketName ci-bucket
|
||||
s3UploadDelaySec 60
|
||||
'''
|
||||
|
||||
|
||||
class TDTestCase(TBase):
|
||||
updatecfgDict = {
|
||||
's3EndPoint': 'http://192.168.1.52:9000',
|
||||
's3AccessKey': 'MQCEIoaPGUs1mhXgpUAu:XTgpN2dEMInnYgqN4gj3G5zgb39ROtsisKKy0GFa',
|
||||
's3BucketName': 'ci-bucket',
|
||||
's3BlockSize': '10240',
|
||||
's3BlockCacheSize': '320',
|
||||
's3PageCacheSize': '10240',
|
||||
's3UploadDelaySec':'60'
|
||||
}
|
||||
|
||||
def insertData(self):
|
||||
tdLog.info(f"insert data.")
|
||||
# taosBenchmark run
|
||||
json = etool.curFile(__file__, "s3_basic.json")
|
||||
etool.runBenchmark(json=json)
|
||||
|
||||
tdSql.execute(f"use {self.db}")
|
||||
# set insert data information
|
||||
self.childtable_count = 4
|
||||
self.insert_rows = 1000000
|
||||
self.timestamp_step = 1000
|
||||
|
||||
def doAction(self):
|
||||
tdLog.info(f"do action.")
|
||||
self.flushDb()
|
||||
self.compactDb()
|
||||
|
||||
# sleep 70s
|
||||
tdLog.info(f"wait 65s ...")
|
||||
time.sleep(65)
|
||||
self.trimDb(True)
|
||||
|
||||
rootPath = sc.clusterRootPath()
|
||||
cmd = f"ls {rootPath}/dnode1/data20/vnode/vnode*/tsdb/*.data"
|
||||
tdLog.info(cmd)
|
||||
loop = 0
|
||||
while len(eos.runRetList(cmd)) > 0 and loop < 40:
|
||||
time.sleep(5)
|
||||
self.trimDb(True)
|
||||
loop += 1
|
||||
|
||||
# run
|
||||
def run(self):
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
|
||||
# insert data
|
||||
self.insertData()
|
||||
|
||||
# check insert data correct
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# save
|
||||
self.snapshotAgg()
|
||||
|
||||
# do action
|
||||
self.doAction()
|
||||
|
||||
# check save agg result correct
|
||||
self.checkAggCorrect()
|
||||
|
||||
# check insert correct again
|
||||
self.checkInsertCorrect()
|
||||
|
||||
# drop database and free s3 file
|
||||
self.dropDb()
|
||||
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,190 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import random
|
||||
|
||||
from frame.log import *
|
||||
from frame.sql import *
|
||||
|
||||
# test case base
|
||||
class TBase:
|
||||
|
||||
#
|
||||
# frame call
|
||||
#
|
||||
|
||||
# init
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
# save param
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdSql.init(conn.cursor(), True)
|
||||
|
||||
# record server information
|
||||
self.dnodeNum = 0
|
||||
self.mnodeNum = 0
|
||||
self.mLevel = 0
|
||||
self.mLevelDisk = 0
|
||||
|
||||
# test case information
|
||||
self.db = "db"
|
||||
self.stb = "stb"
|
||||
|
||||
# sql
|
||||
self.sqlSum = f"select sum(ic) from {self.stb}"
|
||||
self.sqlMax = f"select max(ic) from {self.stb}"
|
||||
self.sqlMin = f"select min(ic) from {self.stb}"
|
||||
self.sqlAvg = f"select avg(ic) from {self.stb}"
|
||||
self.sqlFirst = f"select first(ts) from {self.stb}"
|
||||
self.sqlLast = f"select last(ts) from {self.stb}"
|
||||
|
||||
# stop
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
||||
|
||||
#
|
||||
# db action
|
||||
#
|
||||
|
||||
def trimDb(self, show = False):
|
||||
tdSql.execute(f"trim database {self.db}", show = show)
|
||||
|
||||
def compactDb(self, show = False):
|
||||
tdSql.execute(f"compact database {self.db}", show = show)
|
||||
|
||||
def flushDb(self, show = False):
|
||||
tdSql.execute(f"flush database {self.db}", show = show)
|
||||
|
||||
def dropDb(self, show = False):
|
||||
tdSql.execute(f"drop database {self.db}", show = show)
|
||||
|
||||
def splitVGroups(self):
|
||||
vgids = self.getVGroup(self.db)
|
||||
selid = random.choice(vgids)
|
||||
sql = f"split vgroup {selid}"
|
||||
tdSql.execute(sql, show=True)
|
||||
if self.waitTransactionZero() is False:
|
||||
tdLog.exit(f"{sql} transaction not finished")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def alterReplica(self, replica):
|
||||
sql = f"alter database {self.db} replica {replica}"
|
||||
tdSql.execute(sql, show=True)
|
||||
if self.waitTransactionZero() is False:
|
||||
tdLog.exit(f"{sql} transaction not finished")
|
||||
return False
|
||||
return True
|
||||
|
||||
def balanceVGroup(self):
|
||||
sql = f"balance vgroup"
|
||||
tdSql.execute(sql, show=True)
|
||||
if self.waitTransactionZero() is False:
|
||||
tdLog.exit(f"{sql} transaction not finished")
|
||||
return False
|
||||
return True
|
||||
|
||||
def balanceVGroupLeader(self):
|
||||
sql = f"balance vgroup leader"
|
||||
tdSql.execute(sql, show=True)
|
||||
if self.waitTransactionZero() is False:
|
||||
tdLog.exit(f"{sql} transaction not finished")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def balanceVGroupLeaderOn(self, vgId):
|
||||
sql = f"balance vgroup leader on {vgId}"
|
||||
tdSql.execute(sql, show=True)
|
||||
if self.waitTransactionZero() is False:
|
||||
tdLog.exit(f"{sql} transaction not finished")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
#
|
||||
# check db correct
|
||||
#
|
||||
|
||||
# basic
|
||||
def checkInsertCorrect(self):
|
||||
# check count
|
||||
sql = f"select count(*) from {self.stb}"
|
||||
tdSql.checkAgg(sql, self.childtable_count * self.insert_rows)
|
||||
|
||||
# check child table count
|
||||
sql = f" select count(*) from (select count(*) as cnt , tbname from {self.stb} group by tbname) where cnt = {self.insert_rows} "
|
||||
tdSql.checkAgg(sql, self.childtable_count)
|
||||
|
||||
# check step
|
||||
sql = f"select count(*) from (select diff(ts) as dif from {self.stb} partition by tbname) where dif != {self.timestamp_step}"
|
||||
tdSql.checkAgg(sql, 0)
|
||||
|
||||
# save agg result
|
||||
def snapshotAgg(self):
|
||||
self.sum = tdSql.getFirstValue(self.sqlSum)
|
||||
self.avg = tdSql.getFirstValue(self.sqlAvg)
|
||||
self.min = tdSql.getFirstValue(self.sqlMin)
|
||||
self.max = tdSql.getFirstValue(self.sqlMax)
|
||||
self.first = tdSql.getFirstValue(self.sqlFirst)
|
||||
self.last = tdSql.getFirstValue(self.sqlLast)
|
||||
|
||||
# check agg
|
||||
def checkAggCorrect(self):
|
||||
tdSql.checkAgg(self.sqlSum, self.sum)
|
||||
tdSql.checkAgg(self.sqlAvg, self.avg)
|
||||
tdSql.checkAgg(self.sqlMin, self.min)
|
||||
tdSql.checkAgg(self.sqlMax, self.max)
|
||||
tdSql.checkAgg(self.sqlFirst, self.first)
|
||||
tdSql.checkAgg(self.sqlLast, self.last)
|
||||
|
||||
|
||||
#
|
||||
# get db information
|
||||
#
|
||||
|
||||
# get vgroups
|
||||
def getVGroup(self, db_name):
|
||||
vgidList = []
|
||||
sql = f"select vgroup_id from information_schema.ins_vgroups where db_name='{db_name}'"
|
||||
res = tdSql.getResult(sql)
|
||||
rows = len(res)
|
||||
for i in range(rows):
|
||||
vgidList.append(res[i][0])
|
||||
|
||||
return vgidList
|
||||
|
||||
|
||||
|
||||
#
|
||||
# util
|
||||
#
|
||||
|
||||
# wait transactions count to zero , return False is translation not finished
|
||||
def waitTransactionZero(self, seconds = 300, interval = 1):
|
||||
# wait end
|
||||
for i in range(seconds):
|
||||
sql ="show transactions;"
|
||||
rows = tdSql.query(sql)
|
||||
if rows == 0:
|
||||
tdLog.info("transaction count became zero.")
|
||||
return True
|
||||
#tdLog.info(f"i={i} wait ...")
|
||||
time.sleep(interval)
|
||||
|
||||
return False
|
|
@ -23,7 +23,7 @@ import taos
|
|||
from frame.log import *
|
||||
from frame.sql import *
|
||||
from frame.cases import *
|
||||
from frame.dnodes import *
|
||||
from frame.server.dnodes import *
|
||||
from frame.common import *
|
||||
from frame.constant import *
|
||||
from dataclasses import dataclass,field
|
||||
|
|
|
@ -1,502 +0,0 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
from frame.log import *
|
||||
|
||||
|
||||
class TDSimClient:
|
||||
def __init__(self):
|
||||
self.testCluster = False
|
||||
|
||||
self.cfgDict = {
|
||||
"numOfLogLines": "100000000",
|
||||
"numOfThreadsPerCore": "2.0",
|
||||
"locale": "en_US.UTF-8",
|
||||
"charset": "UTF-8",
|
||||
"asyncLog": "0",
|
||||
"minTablesPerVnode": "4",
|
||||
"maxTablesPerVnode": "1000",
|
||||
"tableIncStepPerVnode": "10000",
|
||||
"maxVgroupsPerDb": "1000",
|
||||
"sdbDebugFlag": "143",
|
||||
"rpcDebugFlag": "135",
|
||||
"tmrDebugFlag": "131",
|
||||
"cDebugFlag": "135",
|
||||
"udebugFlag": "135",
|
||||
"jnidebugFlag": "135",
|
||||
"qdebugFlag": "135",
|
||||
"telemetryReporting": "0",
|
||||
}
|
||||
def init(self, path):
|
||||
self.__init__()
|
||||
self.path = path
|
||||
|
||||
def getLogDir(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
return self.logDir
|
||||
|
||||
def getCfgDir(self):
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
return self.cfgDir
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def addExtraCfg(self, option, value):
|
||||
self.cfgDict.update({option: value})
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","psim","cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("logDir", self.logDir)
|
||||
|
||||
for key, value in self.cfgDict.items():
|
||||
self.cfg(key, value)
|
||||
|
||||
tdLog.debug("psim is deployed and configured by %s" % (self.cfgPath))
|
||||
|
||||
|
||||
class TDDnode:
|
||||
def __init__(self, index):
|
||||
self.index = index
|
||||
self.running = 0
|
||||
self.deployed = 0
|
||||
self.testCluster = False
|
||||
self.valgrind = 0
|
||||
|
||||
def init(self, path):
|
||||
self.path = path
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def getDataSize(self):
|
||||
totalSize = 0
|
||||
|
||||
if (self.deployed == 1):
|
||||
for dirpath, dirnames, filenames in os.walk(self.dataDir):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
|
||||
if not os.path.islink(fp):
|
||||
totalSize = totalSize + os.path.getsize(fp)
|
||||
|
||||
return totalSize
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","dnode%d" % self.index, "log")
|
||||
self.dataDir = os.path.join(self.path,"sim","dnode%d" % self.index, "data")
|
||||
self.cfgDir = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.startIP()
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("publicIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("internalIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("privateIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("dataDir", self.dataDir)
|
||||
self.cfg("logDir", self.logDir)
|
||||
self.cfg("numOfLogLines", "100000000")
|
||||
self.cfg("mnodeEqualVnodeNum", "0")
|
||||
self.cfg("walLevel", "2")
|
||||
self.cfg("fsync", "1000")
|
||||
self.cfg("statusInterval", "1")
|
||||
self.cfg("numOfMnodes", "3")
|
||||
self.cfg("numOfThreadsPerCore", "2.0")
|
||||
self.cfg("monitor", "0")
|
||||
self.cfg("maxVnodeConnections", "30000")
|
||||
self.cfg("maxMgmtConnections", "30000")
|
||||
self.cfg("maxMeterConnections", "30000")
|
||||
self.cfg("maxShellConns", "30000")
|
||||
self.cfg("locale", "en_US.UTF-8")
|
||||
self.cfg("charset", "UTF-8")
|
||||
self.cfg("asyncLog", "0")
|
||||
self.cfg("anyIp", "0")
|
||||
self.cfg("dDebugFlag", "135")
|
||||
self.cfg("mDebugFlag", "135")
|
||||
self.cfg("sdbDebugFlag", "135")
|
||||
self.cfg("rpcDebugFlag", "135")
|
||||
self.cfg("tmrDebugFlag", "131")
|
||||
self.cfg("cDebugFlag", "135")
|
||||
self.cfg("httpDebugFlag", "135")
|
||||
self.cfg("monitorDebugFlag", "135")
|
||||
self.cfg("udebugFlag", "135")
|
||||
self.cfg("jnidebugFlag", "135")
|
||||
self.cfg("qdebugFlag", "135")
|
||||
self.deployed = 1
|
||||
tdLog.debug(
|
||||
"dnode:%d is deployed and configured by %s" %
|
||||
(self.index, self.cfgPath))
|
||||
|
||||
def getBuildPath(self):
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root)-len("/build/bin")]
|
||||
break
|
||||
return buildPath
|
||||
|
||||
def start(self):
|
||||
buildPath = self.getBuildPath()
|
||||
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info("taosd found in %s" % buildPath)
|
||||
|
||||
binPath = buildPath + "/build/bin/taosd"
|
||||
|
||||
if self.deployed == 0:
|
||||
tdLog.exit("dnode:%d is not deployed" % (self.index))
|
||||
|
||||
if self.valgrind == 0:
|
||||
cmd = "nohup %s -c %s > /dev/null 2>&1 & " % (
|
||||
binPath, self.cfgDir)
|
||||
else:
|
||||
valgrindCmdline = "valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes"
|
||||
|
||||
cmd = "nohup %s %s -c %s 2>&1 & " % (
|
||||
valgrindCmdline, binPath, self.cfgDir)
|
||||
|
||||
print(cmd)
|
||||
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
self.running = 1
|
||||
tdLog.debug("dnode:%d is running with %s " % (self.index, cmd))
|
||||
|
||||
tdLog.debug("wait 5 seconds for the dnode:%d to start." % (self.index))
|
||||
time.sleep(5)
|
||||
|
||||
def stop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -INT %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -INT" % (self.index))
|
||||
|
||||
def forcestop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -KILL" % (self.index))
|
||||
|
||||
def startIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d up" % (self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def stopIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d down" % (
|
||||
self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def getDnodeRootDir(self, index):
|
||||
dnodeRootDir = os.path.join(self.path,"sim","psim","dnode%d" % index)
|
||||
return dnodeRootDir
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = os.path.join(self.path,"sim","psim")
|
||||
return dnodesRootDir
|
||||
|
||||
|
||||
class TDDnodes:
|
||||
def __init__(self):
|
||||
self.dnodes = []
|
||||
self.dnodes.append(TDDnode(1))
|
||||
self.dnodes.append(TDDnode(2))
|
||||
self.dnodes.append(TDDnode(3))
|
||||
self.dnodes.append(TDDnode(4))
|
||||
self.dnodes.append(TDDnode(5))
|
||||
self.dnodes.append(TDDnode(6))
|
||||
self.dnodes.append(TDDnode(7))
|
||||
self.dnodes.append(TDDnode(8))
|
||||
self.dnodes.append(TDDnode(9))
|
||||
self.dnodes.append(TDDnode(10))
|
||||
self.simDeployed = False
|
||||
|
||||
def init(self, path):
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
binPath = os.path.dirname(os.path.realpath(__file__))
|
||||
binPath = binPath + "/../../../debug/"
|
||||
tdLog.debug("binPath %s" % (binPath))
|
||||
binPath = os.path.realpath(binPath)
|
||||
tdLog.debug("binPath real path %s" % (binPath))
|
||||
|
||||
# cmd = "sudo cp %s/build/lib/libtaos.so /usr/local/lib/taos/" % (binPath)
|
||||
# tdLog.debug(cmd)
|
||||
# os.system(cmd)
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taos /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taosd /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
if path == "":
|
||||
# self.path = os.path.expanduser('~')
|
||||
self.path = os.path.abspath(binPath + "../../")
|
||||
else:
|
||||
self.path = os.path.realpath(path)
|
||||
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].init(self.path)
|
||||
|
||||
self.sim = TDSimClient()
|
||||
self.sim.init(self.path)
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def deploy(self, index):
|
||||
self.sim.setTestCluster(self.testCluster)
|
||||
|
||||
if (self.simDeployed == False):
|
||||
self.sim.deploy()
|
||||
self.simDeployed = True
|
||||
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].setTestCluster(self.testCluster)
|
||||
self.dnodes[index - 1].setValgrind(self.valgrind)
|
||||
self.dnodes[index - 1].deploy()
|
||||
|
||||
def cfg(self, index, option, value):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].cfg(option, value)
|
||||
|
||||
def start(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].start()
|
||||
|
||||
def stop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].stop()
|
||||
|
||||
def getDataSize(self, index):
|
||||
self.check(index)
|
||||
return self.dnodes[index - 1].getDataSize()
|
||||
|
||||
def forcestop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].forcestop()
|
||||
|
||||
def startIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.testCluster:
|
||||
self.dnodes[index - 1].startIP()
|
||||
|
||||
def stopIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.dnodes[index - 1].testCluster:
|
||||
self.dnodes[index - 1].stopIP()
|
||||
|
||||
def check(self, index):
|
||||
if index < 1 or index > 10:
|
||||
tdLog.exit("index:%d should on a scale of [1, 10]" % (index))
|
||||
|
||||
def stopAll(self):
|
||||
tdLog.info("stop all dnodes")
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].stop()
|
||||
|
||||
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
if processID:
|
||||
cmd = "sudo systemctl stop taosd"
|
||||
os.system(cmd)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = "%s/sim" % (self.path)
|
||||
return dnodesRootDir
|
||||
|
||||
def getSimCfgPath(self):
|
||||
return self.sim.getCfgDir()
|
||||
|
||||
def getSimLogPath(self):
|
||||
return self.sim.getLogDir()
|
||||
|
||||
def addSimExtraCfg(self, option, value):
|
||||
self.sim.addExtraCfg(option, value)
|
||||
|
||||
|
||||
tdDnodes = TDDnodes()
|
|
@ -1,500 +0,0 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
from frame.log import *
|
||||
|
||||
|
||||
class TDSimClient:
|
||||
def __init__(self):
|
||||
self.testCluster = False
|
||||
|
||||
self.cfgDict = {
|
||||
"numOfLogLines": "100000000",
|
||||
"numOfThreadsPerCore": "2.0",
|
||||
"locale": "en_US.UTF-8",
|
||||
"charset": "UTF-8",
|
||||
"asyncLog": "0",
|
||||
"anyIp": "0",
|
||||
"sdbDebugFlag": "135",
|
||||
"rpcDebugFlag": "135",
|
||||
"tmrDebugFlag": "131",
|
||||
"cDebugFlag": "135",
|
||||
"udebugFlag": "135",
|
||||
"jnidebugFlag": "135",
|
||||
"qdebugFlag": "135",
|
||||
"telemetryReporting": "0",
|
||||
}
|
||||
|
||||
def init(self, path):
|
||||
self.__init__()
|
||||
self.path = path
|
||||
|
||||
def getLogDir(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
return self.logDir
|
||||
|
||||
def getCfgDir(self):
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
return self.cfgDir
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def addExtraCfg(self, option, value):
|
||||
self.cfgDict.update({option: value})
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","psim","cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("logDir", self.logDir)
|
||||
|
||||
for key, value in self.cfgDict.items():
|
||||
self.cfg(key, value)
|
||||
|
||||
tdLog.debug("psim is deployed and configured by %s" % (self.cfgPath))
|
||||
|
||||
|
||||
class TDDnode:
|
||||
def __init__(self, index):
|
||||
self.index = index
|
||||
self.running = 0
|
||||
self.deployed = 0
|
||||
self.testCluster = False
|
||||
self.valgrind = 0
|
||||
|
||||
def init(self, path):
|
||||
self.path = path
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def getDataSize(self):
|
||||
totalSize = 0
|
||||
|
||||
if (self.deployed == 1):
|
||||
for dirpath, dirnames, filenames in os.walk(self.dataDir):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
|
||||
if not os.path.islink(fp):
|
||||
totalSize = totalSize + os.path.getsize(fp)
|
||||
|
||||
return totalSize
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","dnode%d" % self.index, "log")
|
||||
self.dataDir = os.path.join(self.path,"sim","dnode%d" % self.index, "data")
|
||||
self.cfgDir = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.startIP()
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("publicIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("internalIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("privateIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("dataDir", self.dataDir)
|
||||
self.cfg("logDir", self.logDir)
|
||||
self.cfg("numOfLogLines", "100000000")
|
||||
self.cfg("mnodeEqualVnodeNum", "0")
|
||||
self.cfg("walLevel", "2")
|
||||
self.cfg("fsync", "1000")
|
||||
self.cfg("statusInterval", "1")
|
||||
self.cfg("numOfMnodes", "3")
|
||||
self.cfg("numOfThreadsPerCore", "2.0")
|
||||
self.cfg("monitor", "0")
|
||||
self.cfg("maxVnodeConnections", "30000")
|
||||
self.cfg("maxMgmtConnections", "30000")
|
||||
self.cfg("maxMeterConnections", "30000")
|
||||
self.cfg("maxShellConns", "30000")
|
||||
self.cfg("locale", "en_US.UTF-8")
|
||||
self.cfg("charset", "UTF-8")
|
||||
self.cfg("asyncLog", "0")
|
||||
self.cfg("anyIp", "0")
|
||||
self.cfg("dDebugFlag", "135")
|
||||
self.cfg("mDebugFlag", "135")
|
||||
self.cfg("sdbDebugFlag", "135")
|
||||
self.cfg("rpcDebugFlag", "135")
|
||||
self.cfg("tmrDebugFlag", "131")
|
||||
self.cfg("cDebugFlag", "135")
|
||||
self.cfg("httpDebugFlag", "135")
|
||||
self.cfg("monitorDebugFlag", "135")
|
||||
self.cfg("udebugFlag", "135")
|
||||
self.cfg("jnidebugFlag", "135")
|
||||
self.cfg("qdebugFlag", "135")
|
||||
self.deployed = 1
|
||||
tdLog.debug(
|
||||
"dnode:%d is deployed and configured by %s" %
|
||||
(self.index, self.cfgPath))
|
||||
|
||||
def getBuildPath(self):
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root)-len("/build/bin")]
|
||||
break
|
||||
return buildPath
|
||||
|
||||
def start(self):
|
||||
buildPath = self.getBuildPath()
|
||||
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info("taosd found in %s" % buildPath)
|
||||
|
||||
binPath = buildPath + "/build/bin/taosd"
|
||||
|
||||
if self.deployed == 0:
|
||||
tdLog.exit("dnode:%d is not deployed" % (self.index))
|
||||
|
||||
if self.valgrind == 0:
|
||||
cmd = "nohup %s -c %s --random-file-fail-factor 0 > /dev/null 2>&1 & " % (
|
||||
binPath, self.cfgDir)
|
||||
else:
|
||||
valgrindCmdline = "valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes"
|
||||
|
||||
cmd = "nohup %s %s -c %s 2>&1 & " % (
|
||||
valgrindCmdline, binPath, self.cfgDir)
|
||||
|
||||
print(cmd)
|
||||
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
self.running = 1
|
||||
tdLog.debug("dnode:%d is running with %s " % (self.index, cmd))
|
||||
|
||||
tdLog.debug("wait 5 seconds for the dnode:%d to start." % (self.index))
|
||||
time.sleep(5)
|
||||
|
||||
def stop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -INT %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -INT" % (self.index))
|
||||
|
||||
def forcestop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -KILL" % (self.index))
|
||||
|
||||
def startIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d up" % (self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def stopIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d down" % (
|
||||
self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def getDnodeRootDir(self, index):
|
||||
dnodeRootDir = os.path.join(self.path,"sim","psim","dnode%d" % index)
|
||||
return dnodeRootDir
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = os.path.join(self.path,"sim","psim")
|
||||
return dnodesRootDir
|
||||
|
||||
|
||||
class TDDnodes:
|
||||
def __init__(self):
|
||||
self.dnodes = []
|
||||
self.dnodes.append(TDDnode(1))
|
||||
self.dnodes.append(TDDnode(2))
|
||||
self.dnodes.append(TDDnode(3))
|
||||
self.dnodes.append(TDDnode(4))
|
||||
self.dnodes.append(TDDnode(5))
|
||||
self.dnodes.append(TDDnode(6))
|
||||
self.dnodes.append(TDDnode(7))
|
||||
self.dnodes.append(TDDnode(8))
|
||||
self.dnodes.append(TDDnode(9))
|
||||
self.dnodes.append(TDDnode(10))
|
||||
self.simDeployed = False
|
||||
|
||||
def init(self, path):
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
binPath = os.path.dirname(os.path.realpath(__file__))
|
||||
binPath = binPath + "/../../../debug/"
|
||||
tdLog.debug("binPath %s" % (binPath))
|
||||
binPath = os.path.realpath(binPath)
|
||||
tdLog.debug("binPath real path %s" % (binPath))
|
||||
|
||||
# cmd = "sudo cp %s/build/lib/libtaos.so /usr/local/lib/taos/" % (binPath)
|
||||
# tdLog.debug(cmd)
|
||||
# os.system(cmd)
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taos /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taosd /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
if path == "":
|
||||
# self.path = os.path.expanduser('~')
|
||||
self.path = os.path.abspath(binPath + "../../")
|
||||
else:
|
||||
self.path = os.path.realpath(path)
|
||||
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].init(self.path)
|
||||
|
||||
self.sim = TDSimClient()
|
||||
self.sim.init(self.path)
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def deploy(self, index):
|
||||
self.sim.setTestCluster(self.testCluster)
|
||||
|
||||
if (self.simDeployed == False):
|
||||
self.sim.deploy()
|
||||
self.simDeployed = True
|
||||
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].setTestCluster(self.testCluster)
|
||||
self.dnodes[index - 1].setValgrind(self.valgrind)
|
||||
self.dnodes[index - 1].deploy()
|
||||
|
||||
def cfg(self, index, option, value):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].cfg(option, value)
|
||||
|
||||
def start(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].start()
|
||||
|
||||
def stop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].stop()
|
||||
|
||||
def getDataSize(self, index):
|
||||
self.check(index)
|
||||
return self.dnodes[index - 1].getDataSize()
|
||||
|
||||
def forcestop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].forcestop()
|
||||
|
||||
def startIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.testCluster:
|
||||
self.dnodes[index - 1].startIP()
|
||||
|
||||
def stopIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.dnodes[index - 1].testCluster:
|
||||
self.dnodes[index - 1].stopIP()
|
||||
|
||||
def check(self, index):
|
||||
if index < 1 or index > 10:
|
||||
tdLog.exit("index:%d should on a scale of [1, 10]" % (index))
|
||||
|
||||
def stopAll(self):
|
||||
tdLog.info("stop all dnodes")
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].stop()
|
||||
|
||||
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
if processID:
|
||||
cmd = "sudo systemctl stop taosd"
|
||||
os.system(cmd)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = "%s/sim" % (self.path)
|
||||
return dnodesRootDir
|
||||
|
||||
def getSimCfgPath(self):
|
||||
return self.sim.getCfgDir()
|
||||
|
||||
def getSimLogPath(self):
|
||||
return self.sim.getLogDir()
|
||||
|
||||
def addSimExtraCfg(self, option, value):
|
||||
self.sim.addExtraCfg(option, value)
|
||||
|
||||
|
||||
tdDnodes = TDDnodes()
|
|
@ -1,497 +0,0 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
from frame.log import *
|
||||
|
||||
|
||||
class TDSimClient:
|
||||
def __init__(self):
|
||||
self.testCluster = False
|
||||
|
||||
self.cfgDict = {
|
||||
"numOfLogLines": "100000000",
|
||||
"locale": "en_US.UTF-8",
|
||||
"charset": "UTF-8",
|
||||
"asyncLog": "0",
|
||||
"rpcDebugFlag": "135",
|
||||
"tmrDebugFlag": "131",
|
||||
"cDebugFlag": "135",
|
||||
"udebugFlag": "135",
|
||||
"jnidebugFlag": "135",
|
||||
"qdebugFlag": "135",
|
||||
"telemetryReporting": "0",
|
||||
}
|
||||
|
||||
def init(self, path):
|
||||
self.__init__()
|
||||
self.path = path
|
||||
|
||||
def getLogDir(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
return self.logDir
|
||||
|
||||
def getCfgDir(self):
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
return self.cfgDir
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def addExtraCfg(self, option, value):
|
||||
self.cfgDict.update({option: value})
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","psim","log")
|
||||
self.cfgDir = os.path.join(self.path,"sim","psim","cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","psim","cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("logDir", self.logDir)
|
||||
|
||||
for key, value in self.cfgDict.items():
|
||||
self.cfg(key, value)
|
||||
|
||||
tdLog.debug("psim is deployed and configured by %s" % (self.cfgPath))
|
||||
|
||||
|
||||
class TDDnode:
|
||||
def __init__(self, index):
|
||||
self.index = index
|
||||
self.running = 0
|
||||
self.deployed = 0
|
||||
self.testCluster = False
|
||||
self.valgrind = 0
|
||||
|
||||
def init(self, path):
|
||||
self.path = path
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def getDataSize(self):
|
||||
totalSize = 0
|
||||
|
||||
if (self.deployed == 1):
|
||||
for dirpath, dirnames, filenames in os.walk(self.dataDir):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
|
||||
if not os.path.islink(fp):
|
||||
totalSize = totalSize + os.path.getsize(fp)
|
||||
|
||||
return totalSize
|
||||
|
||||
def deploy(self):
|
||||
self.logDir = os.path.join(self.path,"sim","dnode%d" % self.index, "log")
|
||||
self.dataDir = os.path.join(self.path,"sim","dnode%d" % self.index, "data")
|
||||
self.cfgDir = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "mkdir -p " + self.cfgDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "touch " + self.cfgPath
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
if self.testCluster:
|
||||
self.startIP()
|
||||
|
||||
if self.testCluster:
|
||||
self.cfg("masterIp", "192.168.0.1")
|
||||
self.cfg("secondIp", "192.168.0.2")
|
||||
self.cfg("publicIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("internalIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("privateIp", "192.168.0.%d" % (self.index))
|
||||
self.cfg("dataDir", self.dataDir)
|
||||
self.cfg("logDir", self.logDir)
|
||||
self.cfg("numOfLogLines", "100000000")
|
||||
self.cfg("mnodeEqualVnodeNum", "0")
|
||||
self.cfg("walLevel", "2")
|
||||
self.cfg("fsync", "1000")
|
||||
self.cfg("statusInterval", "1")
|
||||
self.cfg("numOfMnodes", "3")
|
||||
self.cfg("numOfThreadsPerCore", "2.0")
|
||||
self.cfg("monitor", "0")
|
||||
self.cfg("maxVnodeConnections", "30000")
|
||||
self.cfg("maxMgmtConnections", "30000")
|
||||
self.cfg("maxMeterConnections", "30000")
|
||||
self.cfg("maxShellConns", "30000")
|
||||
self.cfg("locale", "en_US.UTF-8")
|
||||
self.cfg("charset", "UTF-8")
|
||||
self.cfg("asyncLog", "0")
|
||||
self.cfg("anyIp", "0")
|
||||
self.cfg("dDebugFlag", "135")
|
||||
self.cfg("mDebugFlag", "135")
|
||||
self.cfg("sdbDebugFlag", "135")
|
||||
self.cfg("rpcDebugFlag", "135")
|
||||
self.cfg("tmrDebugFlag", "131")
|
||||
self.cfg("cDebugFlag", "135")
|
||||
self.cfg("httpDebugFlag", "135")
|
||||
self.cfg("monitorDebugFlag", "135")
|
||||
self.cfg("udebugFlag", "135")
|
||||
self.cfg("jnidebugFlag", "135")
|
||||
self.cfg("qdebugFlag", "135")
|
||||
self.deployed = 1
|
||||
tdLog.debug(
|
||||
"dnode:%d is deployed and configured by %s" %
|
||||
(self.index, self.cfgPath))
|
||||
|
||||
def getBuildPath(self):
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root)-len("/build/bin")]
|
||||
break
|
||||
return buildPath
|
||||
|
||||
def start(self):
|
||||
buildPath = self.getBuildPath()
|
||||
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info("taosd found in %s" % buildPath)
|
||||
|
||||
binPath = buildPath + "/build/bin/taosd"
|
||||
|
||||
if self.deployed == 0:
|
||||
tdLog.exit("dnode:%d is not deployed" % (self.index))
|
||||
|
||||
if self.valgrind == 0:
|
||||
cmd = "nohup %s -c %s --alloc-random-fail --random-file-fail-factor 5 > /dev/null 2>&1 & " % (
|
||||
binPath, self.cfgDir)
|
||||
else:
|
||||
valgrindCmdline = "valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes"
|
||||
|
||||
cmd = "nohup %s %s -c %s 2>&1 & " % (
|
||||
valgrindCmdline, binPath, self.cfgDir)
|
||||
|
||||
print(cmd)
|
||||
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
self.running = 1
|
||||
tdLog.debug("dnode:%d is running with %s " % (self.index, cmd))
|
||||
|
||||
tdLog.debug("wait 5 seconds for the dnode:%d to start." % (self.index))
|
||||
time.sleep(5)
|
||||
|
||||
def stop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -INT %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -INT" % (self.index))
|
||||
|
||||
def forcestop(self):
|
||||
if self.valgrind == 0:
|
||||
toBeKilled = "taosd"
|
||||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
if self.running != 0:
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -KILL" % (self.index))
|
||||
|
||||
def startIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d up" % (self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def stopIP(self):
|
||||
cmd = "sudo ifconfig lo:%d 192.168.0.%d down" % (
|
||||
self.index, self.index)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def cfg(self, option, value):
|
||||
cmd = "echo %s %s >> %s" % (option, value, self.cfgPath)
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
def getDnodeRootDir(self, index):
|
||||
dnodeRootDir = os.path.join(self.path,"sim","psim","dnode%d" % index)
|
||||
return dnodeRootDir
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = os.path.join(self.path,"sim","psim")
|
||||
return dnodesRootDir
|
||||
|
||||
|
||||
class TDDnodes:
|
||||
def __init__(self):
|
||||
self.dnodes = []
|
||||
self.dnodes.append(TDDnode(1))
|
||||
self.dnodes.append(TDDnode(2))
|
||||
self.dnodes.append(TDDnode(3))
|
||||
self.dnodes.append(TDDnode(4))
|
||||
self.dnodes.append(TDDnode(5))
|
||||
self.dnodes.append(TDDnode(6))
|
||||
self.dnodes.append(TDDnode(7))
|
||||
self.dnodes.append(TDDnode(8))
|
||||
self.dnodes.append(TDDnode(9))
|
||||
self.dnodes.append(TDDnode(10))
|
||||
self.simDeployed = False
|
||||
|
||||
def init(self, path):
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
binPath = os.path.dirname(os.path.realpath(__file__))
|
||||
binPath = binPath + "/../../../debug/"
|
||||
tdLog.debug("binPath %s" % (binPath))
|
||||
binPath = os.path.realpath(binPath)
|
||||
tdLog.debug("binPath real path %s" % (binPath))
|
||||
|
||||
# cmd = "sudo cp %s/build/lib/libtaos.so /usr/local/lib/taos/" % (binPath)
|
||||
# tdLog.debug(cmd)
|
||||
# os.system(cmd)
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taos /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
# cmd = "sudo cp %s/build/bin/taosd /usr/local/bin/taos/" % (binPath)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
# tdLog.debug("execute %s" % (cmd))
|
||||
|
||||
if path == "":
|
||||
# self.path = os.path.expanduser('~')
|
||||
self.path = os.path.abspath(binPath + "../../")
|
||||
else:
|
||||
self.path = os.path.realpath(path)
|
||||
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].init(self.path)
|
||||
|
||||
self.sim = TDSimClient()
|
||||
self.sim.init(self.path)
|
||||
|
||||
def setTestCluster(self, value):
|
||||
self.testCluster = value
|
||||
|
||||
def setValgrind(self, value):
|
||||
self.valgrind = value
|
||||
|
||||
def deploy(self, index):
|
||||
self.sim.setTestCluster(self.testCluster)
|
||||
|
||||
if (self.simDeployed == False):
|
||||
self.sim.deploy()
|
||||
self.simDeployed = True
|
||||
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].setTestCluster(self.testCluster)
|
||||
self.dnodes[index - 1].setValgrind(self.valgrind)
|
||||
self.dnodes[index - 1].deploy()
|
||||
|
||||
def cfg(self, index, option, value):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].cfg(option, value)
|
||||
|
||||
def start(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].start()
|
||||
|
||||
def stop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].stop()
|
||||
|
||||
def getDataSize(self, index):
|
||||
self.check(index)
|
||||
return self.dnodes[index - 1].getDataSize()
|
||||
|
||||
def forcestop(self, index):
|
||||
self.check(index)
|
||||
self.dnodes[index - 1].forcestop()
|
||||
|
||||
def startIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.testCluster:
|
||||
self.dnodes[index - 1].startIP()
|
||||
|
||||
def stopIP(self, index):
|
||||
self.check(index)
|
||||
|
||||
if self.dnodes[index - 1].testCluster:
|
||||
self.dnodes[index - 1].stopIP()
|
||||
|
||||
def check(self, index):
|
||||
if index < 1 or index > 10:
|
||||
tdLog.exit("index:%d should on a scale of [1, 10]" % (index))
|
||||
|
||||
def stopAll(self):
|
||||
tdLog.info("stop all dnodes")
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].stop()
|
||||
|
||||
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
if processID:
|
||||
cmd = "sudo systemctl stop taosd"
|
||||
os.system(cmd)
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
# if os.system(cmd) != 0 :
|
||||
# tdLog.exit(cmd)
|
||||
|
||||
def getDnodesRootDir(self):
|
||||
dnodesRootDir = "%s/sim" % (self.path)
|
||||
return dnodesRootDir
|
||||
|
||||
def getSimCfgPath(self):
|
||||
return self.sim.getCfgDir()
|
||||
|
||||
def getSimLogPath(self):
|
||||
return self.sim.getLogDir()
|
||||
|
||||
def addSimExtraCfg(self, option, value):
|
||||
self.sim.addExtraCfg(option, value)
|
||||
|
||||
|
||||
tdDnodes = TDDnodes()
|
|
@ -0,0 +1,57 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2023 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# about system funciton extension
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import platform
|
||||
import subprocess
|
||||
|
||||
# if windows platform return True
|
||||
def isWin():
|
||||
return platform.system().lower() == 'windows'
|
||||
|
||||
#
|
||||
# execute programe
|
||||
#
|
||||
|
||||
# wait util execute file finished
|
||||
def exe(file):
|
||||
return os.system(file)
|
||||
|
||||
# execute file and return immediately
|
||||
def exeNoWait(file):
|
||||
print("exe no wait")
|
||||
|
||||
|
||||
# run return output and error
|
||||
def run(command):
|
||||
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
process.wait(3)
|
||||
|
||||
output = process.stdout.read().decode(encoding="gbk")
|
||||
error = process.stderr.read().decode(encoding="gbk")
|
||||
|
||||
return output, error
|
||||
|
||||
|
||||
# return list after run
|
||||
def runRetList(command):
|
||||
lines = []
|
||||
output,error = run(command)
|
||||
return output.splitlines()
|
|
@ -0,0 +1,56 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# about path function extension
|
||||
#
|
||||
|
||||
import os
|
||||
from frame.log import *
|
||||
|
||||
# build/bin path
|
||||
binDir = ""
|
||||
|
||||
def binPath():
|
||||
global binDir
|
||||
|
||||
if binDir != "":
|
||||
return binDir
|
||||
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if ("community/tests" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community/tests")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("TDengine/tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root)-len("/build/bin")]
|
||||
break
|
||||
# check
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info(f"taosd found in {buildPath}")
|
||||
# return
|
||||
binDir = buildPath + "/build/bin/"
|
||||
return binDir
|
||||
|
||||
def binFile(filename):
|
||||
return binPath() + filename
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2023 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# about tools funciton extension
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2023 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# about system funciton extension
|
||||
#
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
import frame.epath
|
||||
import frame.eos
|
||||
from frame.log import *
|
||||
|
||||
# run taosBenchmark with command or json file mode
|
||||
def runBenchmark(command = "", json = "") :
|
||||
# get taosBenchmark path
|
||||
bmFile = frame.epath.binFile("taosBenchmark")
|
||||
if frame.eos.isWin():
|
||||
bmFile += ".exe"
|
||||
|
||||
# run
|
||||
if command != "":
|
||||
frame.eos.exe(bmFile + " " + command)
|
||||
if json != "":
|
||||
cmd = f"{bmFile} -f {json}"
|
||||
print(cmd)
|
||||
status = frame.eos.exe(cmd)
|
||||
if status !=0:
|
||||
tdLog.exit(f"run failed {cmd} status={status}")
|
||||
|
||||
|
||||
# get current directory file name
|
||||
def curFile(fullPath, filename):
|
||||
return os.path.dirname(fullPath) + "/" + filename
|
|
@ -1,83 +0,0 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import os
|
||||
from frame.log import *
|
||||
|
||||
|
||||
|
||||
class TDFindPath:
|
||||
"""This class is for finding path within TDengine
|
||||
"""
|
||||
def __init__(self):
|
||||
self.file = ""
|
||||
|
||||
|
||||
def init(self, file):
|
||||
"""[summary]
|
||||
|
||||
Args:
|
||||
file (str): the file location you want to start the query. Generally using __file__
|
||||
"""
|
||||
self.file = file
|
||||
|
||||
def getTaosdemoPath(self):
|
||||
"""for finding the path of directory containing taosdemo
|
||||
|
||||
Returns:
|
||||
str: the path to directory containing taosdemo
|
||||
"""
|
||||
selfPath = os.path.dirname(os.path.realpath(self.file))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root)-len("/build/bin")]
|
||||
break
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info(f"taosd found in {buildPath}")
|
||||
return buildPath + "/build/bin/"
|
||||
|
||||
def getTDenginePath(self):
|
||||
"""for finding the root path of TDengine
|
||||
|
||||
Returns:
|
||||
str: the root path of TDengine
|
||||
"""
|
||||
selfPath = os.path.dirname(os.path.realpath(self.file))
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
print(projPath)
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("sim" in dirs):
|
||||
print(root)
|
||||
rootRealPath = os.path.realpath(root)
|
||||
if (rootRealPath == ""):
|
||||
tdLog.exit("TDengine not found!")
|
||||
else:
|
||||
tdLog.info(f"TDengine found in {rootRealPath}")
|
||||
return rootRealPath
|
||||
|
||||
tdFindPath = TDFindPath()
|
|
@ -8,7 +8,7 @@ import socket
|
|||
from frame.log import *
|
||||
from frame.sql import *
|
||||
from frame.cases import *
|
||||
from frame.dnodes import *
|
||||
from frame.server.dnodes import *
|
||||
from frame.common import *
|
||||
|
||||
class ClusterDnodes(TDDnodes):
|
||||
|
@ -35,17 +35,21 @@ class ConfigureyCluster:
|
|||
self.startPort = 6030
|
||||
self.portStep = 100
|
||||
self.mnodeNums = 0
|
||||
self.level = 0
|
||||
self.disk = 0
|
||||
|
||||
def configure_cluster(self ,dnodeNums=5,mnodeNums=0,independentMnode=True,startPort=6030,portStep=100,hostname="%s"%hostname):
|
||||
def configure_cluster(self ,dnodeNums=5, mnodeNums=0, independentMnode=True, startPort=6030, portStep=100, hostname="%s"%hostname, level=1, disk=1):
|
||||
self.startPort=int(startPort)
|
||||
self.portStep=int(portStep)
|
||||
self.hostname=hostname
|
||||
self.dnodeNums = int(dnodeNums)
|
||||
self.mnodeNums = int(mnodeNums)
|
||||
self.level = int(level)
|
||||
self.disk = int(disk)
|
||||
self.dnodes = []
|
||||
startPort_sec = int(startPort+portStep)
|
||||
for num in range(1, (self.dnodeNums+1)):
|
||||
dnode = TDDnode(num)
|
||||
dnode = TDDnode(num, self.level, self.disk)
|
||||
dnode.addExtraCfg("firstEp", f"{hostname}:{self.startPort}")
|
||||
dnode.addExtraCfg("fqdn", f"{hostname}")
|
||||
dnode.addExtraCfg("serverPort", f"{self.startPort + (num-1)*self.portStep}")
|
|
@ -115,8 +115,11 @@ class TDSimClient:
|
|||
|
||||
|
||||
class TDDnode:
|
||||
def __init__(self, index):
|
||||
def __init__(self, index=1, level=1, disk=1):
|
||||
self.index = index
|
||||
self.level = level
|
||||
self.disk = disk
|
||||
self.dataDir = []
|
||||
self.running = 0
|
||||
self.deployed = 0
|
||||
self.testCluster = False
|
||||
|
@ -209,14 +212,30 @@ class TDDnode:
|
|||
self.remote_conn.run("python3 ./test.py %s -d %s -e %s"%(valgrindStr,remoteCfgDictStr,execCmdStr))
|
||||
|
||||
def deploy(self, *updatecfgDict):
|
||||
# logDir
|
||||
self.logDir = os.path.join(self.path,"sim","dnode%d" % self.index, "log")
|
||||
self.dataDir = os.path.join(self.path,"sim","dnode%d" % self.index, "data")
|
||||
# dataDir
|
||||
simPath = os.path.join(self.path, "sim", "dnode%d" % self.index)
|
||||
primary = 1
|
||||
if self.level == 1 and self.disk == 1:
|
||||
eDir = os.path.join(simPath, "data")
|
||||
self.dataDir.append(eDir)
|
||||
else:
|
||||
for i in range(self.level):
|
||||
for j in range(self.disk):
|
||||
eDir = os.path.join(simPath, f"data{i}{j}")
|
||||
self.dataDir.append(f"{eDir} {i} {primary}")
|
||||
if primary == 1:
|
||||
primary = 0
|
||||
|
||||
# taos.cfg
|
||||
self.cfgDir = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg")
|
||||
self.cfgPath = os.path.join(self.path,"sim","dnode%d" % self.index, "cfg","taos.cfg")
|
||||
|
||||
cmd = "rm -rf " + self.dataDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
for eDir in self.dataDir:
|
||||
cmd = "rm -rf " + eDir
|
||||
if os.system(cmd) != 0:
|
||||
tdLog.exit(cmd)
|
||||
|
||||
cmd = "rm -rf " + self.logDir
|
||||
if os.system(cmd) != 0:
|
||||
|
@ -229,7 +248,8 @@ class TDDnode:
|
|||
# cmd = "mkdir -p " + self.dataDir
|
||||
# if os.system(cmd) != 0:
|
||||
# tdLog.exit(cmd)
|
||||
os.makedirs(self.dataDir)
|
||||
for eDir in self.dataDir:
|
||||
os.makedirs(eDir.split(' ')[0])
|
||||
|
||||
# cmd = "mkdir -p " + self.logDir
|
||||
# if os.system(cmd) != 0:
|
||||
|
@ -275,7 +295,11 @@ class TDDnode:
|
|||
self.addExtraCfg(key, value)
|
||||
if (self.remoteIP == ""):
|
||||
for key, value in self.cfgDict.items():
|
||||
self.cfg(key, value)
|
||||
if type(value) == list:
|
||||
for v in value:
|
||||
self.cfg(key, v)
|
||||
else:
|
||||
self.cfg(key, value)
|
||||
else:
|
||||
self.remoteExec(self.cfgDict, "tdDnodes.deploy(%d,updateCfgDict)"%self.index)
|
||||
|
||||
|
@ -887,4 +911,10 @@ class TDDnodes:
|
|||
def getAsan(self):
|
||||
return self.asan
|
||||
|
||||
tdDnodes = TDDnodes()
|
||||
def setLevelDisk(self, level, disk):
|
||||
for i in range(len(self.dnodes)):
|
||||
self.dnodes[i].level = int(level)
|
||||
self.dnodes[i].disk = int(disk)
|
||||
|
||||
|
||||
tdDnodes = TDDnodes()
|
|
@ -535,6 +535,16 @@ class TDSql:
|
|||
tdLog.info("%s(%d) failed: sql:%s, elm:%s == expect_elm:%s" % args)
|
||||
raise Exception
|
||||
|
||||
# check like select count(*) ... sql
|
||||
def checkAgg(self, sql, expectCnt):
|
||||
self.query(sql)
|
||||
self.checkData(0, 0, expectCnt)
|
||||
|
||||
# get first value
|
||||
def getFirstValue(self, sql) :
|
||||
self.query(sql)
|
||||
return self.getData(0, 0)
|
||||
|
||||
def get_times(self, time_str, precision="ms"):
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
if time_str[-1] not in TAOS_TIME_INIT:
|
||||
|
@ -602,6 +612,7 @@ class TDSql:
|
|||
if self.cursor.istype(col, "BIGINT UNSIGNED"):
|
||||
return "BIGINT UNSIGNED"
|
||||
|
||||
'''
|
||||
def taosdStatus(self, state):
|
||||
tdLog.sleep(5)
|
||||
pstate = 0
|
||||
|
@ -630,6 +641,7 @@ class TDSql:
|
|||
tdLog.exit("taosd state is %d != expect:%d" %args)
|
||||
pass
|
||||
|
||||
|
||||
def haveFile(self, dir, state):
|
||||
if os.path.exists(dir) and os.path.isdir(dir):
|
||||
if not os.listdir(dir):
|
||||
|
@ -644,6 +656,7 @@ class TDSql:
|
|||
tdLog.exit("dir: %s is not empty, expect: empty" %dir)
|
||||
else:
|
||||
tdLog.exit("dir: %s doesn't exist" %dir)
|
||||
|
||||
def createDir(self, dir):
|
||||
if os.path.exists(dir):
|
||||
shrmtree(dir)
|
||||
|
@ -651,5 +664,6 @@ class TDSql:
|
|||
os.makedirs( dir, 755 )
|
||||
tdLog.info("dir: %s is created" %dir)
|
||||
pass
|
||||
'''
|
||||
|
||||
tdSql = TDSql()
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import datetime
|
||||
|
||||
from frame.server.dnodes import *
|
||||
|
||||
class srvCtl:
|
||||
def __init__(self):
|
||||
# record server information
|
||||
self.dnodeNum = 0
|
||||
self.mnodeNum = 0
|
||||
self.mLevel = 0
|
||||
self.mLevelDisk = 0
|
||||
|
||||
#
|
||||
# about path
|
||||
#
|
||||
|
||||
# get cluster root path like /root/TDinternal/sim/
|
||||
def clusterRootPath(self):
|
||||
return tdDnodes.getDnodesRootDir()
|
||||
|
||||
# return dnode data files list
|
||||
def dnodeDataFiles(self, idx):
|
||||
files = []
|
||||
return files
|
||||
|
||||
|
||||
|
||||
sc = srvCtl()
|
|
@ -28,9 +28,9 @@ import importlib
|
|||
import toml
|
||||
|
||||
from frame.log import *
|
||||
from frame.dnodes import *
|
||||
from frame.server.dnodes import *
|
||||
from frame.server.cluster import *
|
||||
from frame.cases import *
|
||||
from frame.cluster import *
|
||||
from frame.taosadapter import *
|
||||
|
||||
import taos
|
||||
|
@ -111,8 +111,12 @@ if __name__ == "__main__":
|
|||
asan = False
|
||||
independentMnode = False
|
||||
previousCluster = False
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], 'f:p:m:l:scghrd:k:e:N:M:Q:C:RWD:n:i:aP', [
|
||||
'file=', 'path=', 'master', 'logSql', 'stop', 'cluster', 'valgrind', 'help', 'restart', 'updateCfgDict', 'killv', 'execCmd','dnodeNums','mnodeNums','queryPolicy','createDnodeNums','restful','websocket','adaptercfgupdate','replicaVar','independentMnode','previous'])
|
||||
level = 1
|
||||
disk = 1
|
||||
|
||||
opts, args = getopt.gnu_getopt(sys.argv[1:], 'f:p:m:l:scghrd:k:e:N:M:Q:C:RWU:n:i:aP:L:D:', [
|
||||
'file=', 'path=', 'master', 'logSql', 'stop', 'cluster', 'valgrind', 'help', 'restart', 'updateCfgDict', 'killv', 'execCmd','dnodeNums','mnodeNums',
|
||||
'queryPolicy','createDnodeNums','restful','websocket','adaptercfgupdate','replicaVar','independentMnode',"asan",'previous','level','disk'])
|
||||
for key, value in opts:
|
||||
if key in ['-h', '--help']:
|
||||
tdLog.printNoPrefix(
|
||||
|
@ -134,11 +138,13 @@ if __name__ == "__main__":
|
|||
tdLog.printNoPrefix('-C create Dnode Numbers in one cluster')
|
||||
tdLog.printNoPrefix('-R restful realization form')
|
||||
tdLog.printNoPrefix('-W websocket connection')
|
||||
tdLog.printNoPrefix('-D taosadapter update cfg dict ')
|
||||
tdLog.printNoPrefix('-U taosadapter update cfg dict ')
|
||||
tdLog.printNoPrefix('-n the number of replicas')
|
||||
tdLog.printNoPrefix('-i independentMnode Mnode')
|
||||
tdLog.printNoPrefix('-a address sanitizer mode')
|
||||
tdLog.printNoPrefix('-P run case with [P]revious cluster, do not create new cluster to run case.')
|
||||
tdLog.printNoPrefix('-L set multiple level number. range 1 ~ 3')
|
||||
tdLog.printNoPrefix('-D set disk number on each level. range 1 ~ 10')
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
@ -213,7 +219,7 @@ if __name__ == "__main__":
|
|||
if key in ['-a', '--asan']:
|
||||
asan = True
|
||||
|
||||
if key in ['-D', '--adaptercfgupdate']:
|
||||
if key in ['-U', '--adaptercfgupdate']:
|
||||
try:
|
||||
adaptercfgupdate = eval(base64.b64decode(value.encode()).decode())
|
||||
except:
|
||||
|
@ -226,6 +232,12 @@ if __name__ == "__main__":
|
|||
if key in ['-P', '--previous']:
|
||||
previousCluster = True
|
||||
|
||||
if key in ['-L', '--level']:
|
||||
level = value
|
||||
|
||||
if key in ['-D', '--disk']:
|
||||
disk = value
|
||||
|
||||
#
|
||||
# do exeCmd command
|
||||
#
|
||||
|
@ -361,6 +373,7 @@ if __name__ == "__main__":
|
|||
tAdapter.stop(force_kill=True)
|
||||
|
||||
if dnodeNums == 1 :
|
||||
tdDnodes.setLevelDisk(level, disk)
|
||||
tdDnodes.deploy(1,updateCfgDict)
|
||||
tdDnodes.start(1)
|
||||
tdCases.logSql(logSql)
|
||||
|
@ -391,7 +404,7 @@ if __name__ == "__main__":
|
|||
tdLog.exit(f"alter queryPolicy to {queryPolicy} failed")
|
||||
else :
|
||||
tdLog.debug("create an cluster with %s nodes and make %s dnode as independent mnode"%(dnodeNums,mnodeNums))
|
||||
dnodeslist = cluster.configure_cluster(dnodeNums=dnodeNums, mnodeNums=mnodeNums, independentMnode=independentMnode)
|
||||
dnodeslist = cluster.configure_cluster(dnodeNums=dnodeNums, mnodeNums=mnodeNums, independentMnode=independentMnode, level=level, disk=disk)
|
||||
tdDnodes = ClusterDnodes(dnodeslist)
|
||||
tdDnodes.init(deployPath, masterIp)
|
||||
tdDnodes.setTestCluster(testCluster)
|
||||
|
@ -498,6 +511,7 @@ if __name__ == "__main__":
|
|||
else:
|
||||
tdLog.info("not need to query")
|
||||
else:
|
||||
# except windows
|
||||
tdDnodes.setKillValgrind(killValgrind)
|
||||
tdDnodes.init(deployPath, masterIp)
|
||||
tdDnodes.setTestCluster(testCluster)
|
||||
|
@ -529,6 +543,7 @@ if __name__ == "__main__":
|
|||
|
||||
if dnodeNums == 1 :
|
||||
# dnode is one
|
||||
tdDnodes.setLevelDisk(level, disk)
|
||||
tdDnodes.deploy(1,updateCfgDict)
|
||||
tdDnodes.start(1)
|
||||
tdCases.logSql(logSql)
|
||||
|
@ -574,7 +589,8 @@ if __name__ == "__main__":
|
|||
# dnode > 1 cluster
|
||||
tdLog.debug("create an cluster with %s nodes and make %s dnode as independent mnode"%(dnodeNums,mnodeNums))
|
||||
print(independentMnode,"independentMnode valuse")
|
||||
dnodeslist = cluster.configure_cluster(dnodeNums=dnodeNums, mnodeNums=mnodeNums, independentMnode=independentMnode)
|
||||
# create dnode list
|
||||
dnodeslist = cluster.configure_cluster(dnodeNums=dnodeNums, mnodeNums=mnodeNums, independentMnode=independentMnode, level=level, disk=disk)
|
||||
tdDnodes = ClusterDnodes(dnodeslist)
|
||||
tdDnodes.init(deployPath, masterIp)
|
||||
tdDnodes.setTestCluster(testCluster)
|
||||
|
|
|
@ -5,10 +5,17 @@
|
|||
#unit-test
|
||||
,,y,unit-test,bash test.sh
|
||||
|
||||
#army-test
|
||||
,,y,army,./pytest.sh python3 ./test.py -f empty.py
|
||||
#
|
||||
# army-test
|
||||
#
|
||||
,,y,army,./pytest.sh python3 ./test.py -f enterprise/multi-level/mlevel_basic.py -N 3 -L 3 -D 2
|
||||
,,y,army,./pytest.sh python3 ./test.py -f enterprise/s3/s3_basic.py -L 3 -D 1
|
||||
,,y,army,./pytest.sh python3 ./test.py -f community/cluster/snapshot.py -N 3 -L 3 -D 2
|
||||
|
||||
#system test
|
||||
|
||||
#
|
||||
# system test
|
||||
#
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/stream_basic.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/scalar_function.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 8-stream/at_once_interval.py
|
||||
|
@ -29,6 +36,7 @@
|
|||
,,n,system-test,python3 ./test.py -f 8-stream/snode_restart_with_checkpoint.py -N 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/tbname_vgroup.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/compact-col.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stbJoin.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stbJoin.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stbJoin.py -Q 3
|
||||
|
@ -131,6 +139,10 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/ts-4233.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/like.py -Q 4
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreDnode.py -N 5 -M 3 -i False
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 3-enterprise/restore/restoreVnode.py -N 5 -M 3 -i False
|
||||
|
@ -514,6 +526,7 @@ e
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/json_tag.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQueryInterval.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/systable_func.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/test_ts4382.py
|
||||
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stablity.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/stablity_1.py
|
||||
|
|
|
@ -506,7 +506,22 @@ class TDCom:
|
|||
if ("packaging" not in rootRealPath):
|
||||
buildPath = root[:len(root) - len("/build/bin")]
|
||||
break
|
||||
if platform.system().lower() == 'windows':
|
||||
win_sep = "\\"
|
||||
buildPath = buildPath.replace(win_sep,'/')
|
||||
|
||||
return buildPath
|
||||
|
||||
def getTaosdPath(self, dnodeID="dnode1"):
|
||||
buildPath = self.getBuildPath()
|
||||
if (buildPath == ""):
|
||||
tdLog.exit("taosd not found!")
|
||||
else:
|
||||
tdLog.info("taosd found in %s" % buildPath)
|
||||
taosdPath = buildPath + "/../sim/" + dnodeID
|
||||
tdLog.info("taosdPath: %s" % taosdPath)
|
||||
return taosdPath
|
||||
|
||||
|
||||
def getClientCfgPath(self):
|
||||
buildPath = self.getBuildPath()
|
||||
|
|
|
@ -78,6 +78,26 @@ class TDSql:
|
|||
self.cursor.execute(s)
|
||||
time.sleep(2)
|
||||
|
||||
def execute(self, sql, queryTimes=30, show=False):
|
||||
self.sql = sql
|
||||
if show:
|
||||
tdLog.info(sql)
|
||||
i=1
|
||||
while i <= queryTimes:
|
||||
try:
|
||||
self.affectedRows = self.cursor.execute(sql)
|
||||
return self.affectedRows
|
||||
except Exception as e:
|
||||
tdLog.notice("Try to execute sql again, query times: %d "%i)
|
||||
if i == queryTimes:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, sql, repr(e))
|
||||
tdLog.notice("%s(%d) failed: sql:%s, %s" % args)
|
||||
raise Exception(repr(e))
|
||||
i+=1
|
||||
time.sleep(1)
|
||||
pass
|
||||
|
||||
def error(self, sql, expectedErrno = None, expectErrInfo = None, fullMatched = True):
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
expectErrNotOccured = True
|
||||
|
@ -108,7 +128,7 @@ class TDSql:
|
|||
if expectErrInfo == self.error_info:
|
||||
tdLog.info("sql:%s, expected expectErrInfo '%s' occured" % (sql, expectErrInfo))
|
||||
else:
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo '%s' occured, but not expected errno '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo '%s' occured, but not expected expectErrInfo '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
else:
|
||||
if expectedErrno != None:
|
||||
if expectedErrno in self.errno:
|
||||
|
@ -120,7 +140,7 @@ class TDSql:
|
|||
if expectErrInfo in self.error_info:
|
||||
tdLog.info("sql:%s, expected expectErrInfo '%s' occured" % (sql, expectErrInfo))
|
||||
else:
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo %s occured, but not expected errno '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo %s occured, but not expected expectErrInfo '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
|
||||
return self.error_info
|
||||
|
||||
|
@ -158,6 +178,63 @@ class TDSql:
|
|||
time.sleep(1)
|
||||
pass
|
||||
|
||||
def query_success_failed(self, sql, row_tag=None, queryTimes=10, count_expected_res=None, expectErrInfo = None, fullMatched = True):
|
||||
self.sql = sql
|
||||
i=1
|
||||
while i <= queryTimes:
|
||||
try:
|
||||
self.cursor.execute(sql)
|
||||
self.queryResult = self.cursor.fetchall()
|
||||
self.queryRows = len(self.queryResult)
|
||||
self.queryCols = len(self.cursor.description)
|
||||
|
||||
if count_expected_res is not None:
|
||||
counter = 0
|
||||
while count_expected_res != self.queryResult[0][0]:
|
||||
self.cursor.execute(sql)
|
||||
self.queryResult = self.cursor.fetchall()
|
||||
if counter < queryTimes:
|
||||
counter += 0.5
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
return False
|
||||
|
||||
tdLog.info("query is success")
|
||||
time.sleep(1)
|
||||
continue
|
||||
except Exception as e:
|
||||
tdLog.notice("Try to query again, query times: %d "%i)
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
if i < queryTimes:
|
||||
error_info = repr(e)
|
||||
print(error_info)
|
||||
self.error_info = ','.join(error_info[error_info.index('(')+1:-1].split(",")[:-1]).replace("'","")
|
||||
self.queryRows = 0
|
||||
self.queryCols = 0
|
||||
self.queryResult = None
|
||||
|
||||
if fullMatched:
|
||||
if expectErrInfo != None:
|
||||
if expectErrInfo == self.error_info:
|
||||
tdLog.info("sql:%s, expected expectErrInfo '%s' occured" % (sql, expectErrInfo))
|
||||
else:
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo '%s' occured, but not expected expectErrInfo '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
else:
|
||||
if expectErrInfo != None:
|
||||
if expectErrInfo in self.error_info:
|
||||
tdLog.info("sql:%s, expected expectErrInfo '%s' occured" % (sql, expectErrInfo))
|
||||
else:
|
||||
tdLog.exit("%s(%d) failed: sql:%s, expectErrInfo %s occured, but not expected expectErrInfo '%s'" % (caller.filename, caller.lineno, sql, self.error_info, expectErrInfo))
|
||||
|
||||
return self.error_info
|
||||
elif i == queryTimes:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, sql, repr(e))
|
||||
tdLog.notice("%s(%d) failed: sql:%s, %s" % args)
|
||||
raise Exception(repr(e))
|
||||
i+=1
|
||||
time.sleep(1)
|
||||
pass
|
||||
|
||||
def is_err_sql(self, sql):
|
||||
err_flag = True
|
||||
|
@ -471,25 +548,7 @@ class TDSql:
|
|||
time.sleep(1)
|
||||
continue
|
||||
|
||||
def execute(self, sql, queryTimes=30, show=False):
|
||||
self.sql = sql
|
||||
if show:
|
||||
tdLog.info(sql)
|
||||
i=1
|
||||
while i <= queryTimes:
|
||||
try:
|
||||
self.affectedRows = self.cursor.execute(sql)
|
||||
return self.affectedRows
|
||||
except Exception as e:
|
||||
tdLog.notice("Try to execute sql again, query times: %d "%i)
|
||||
if i == queryTimes:
|
||||
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||
args = (caller.filename, caller.lineno, sql, repr(e))
|
||||
tdLog.notice("%s(%d) failed: sql:%s, %s" % args)
|
||||
raise Exception(repr(e))
|
||||
i+=1
|
||||
time.sleep(1)
|
||||
pass
|
||||
|
||||
|
||||
def checkAffectedRows(self, expectAffectedRows):
|
||||
if self.affectedRows != expectAffectedRows:
|
||||
|
|
|
@ -31,6 +31,8 @@ sql insert into t4 values(1648791223000,1,1,10,3.0);
|
|||
sql insert into t4 values(1648791233000,0,2,11,1.0);
|
||||
sql insert into t4 values(1648791243000,1,9,12,2.0);
|
||||
|
||||
sleep 1000
|
||||
|
||||
sql create stream streams0 trigger at_once IGNORE EXPIRED 0 IGNORE UPDATE 0 fill_history 1 into streamt0 as select _wstart as s, count(*) c1, sum(b), max(c), _wend as e from st partition by tbname event_window start with a = 0 end with b = 9;
|
||||
|
||||
sleep 1000
|
||||
|
@ -79,6 +81,37 @@ if $data21 != 2 then
|
|||
goto loop0
|
||||
endi
|
||||
|
||||
sql insert into t3 values(1648791222000,0,1,7,3.0);
|
||||
|
||||
$loop_count = 0
|
||||
loop1:
|
||||
|
||||
sleep 300
|
||||
print 2 sql select * from streamt0 order by 1, 2, 3, 4;
|
||||
sql select * from streamt0 order by 1, 2, 3, 4;
|
||||
|
||||
print
|
||||
print $data00 $data01 $data02 $data03 $data04
|
||||
print $data10 $data11 $data12 $data13 $data14
|
||||
print $data20 $data21 $data22 $data23 $data24
|
||||
print $data30 $data31 $data32 $data33 $data34
|
||||
print
|
||||
|
||||
$loop_count = $loop_count + 1
|
||||
if $loop_count == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $rows != 4 then
|
||||
print ======rows=$rows
|
||||
goto loop1
|
||||
endi
|
||||
|
||||
if $data01 != 5 then
|
||||
print ======data01=$data01
|
||||
goto loop0
|
||||
endi
|
||||
|
||||
|
||||
print event1 end
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -327,4 +327,40 @@ if $rows != 1 then
|
|||
goto loop17
|
||||
endi
|
||||
|
||||
sql create database test2 vgroups 4;
|
||||
sql use test2;
|
||||
sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int);
|
||||
sql create table t1 using st tags(1,1,1);
|
||||
sql create table t2 using st tags(2,2,2);
|
||||
sql create stream streams4 trigger at_once ignore update 0 ignore expired 0 into streamt4 as select _wstart, count(*) c1, count(a) c2 from st session(ts, 2s) ;
|
||||
|
||||
sql insert into t1 values(1648791255100,1,2,3);
|
||||
sql insert into t1 values(1648791255300,1,2,3);
|
||||
|
||||
sleep 1000
|
||||
|
||||
sql insert into t1 values(1648791253000,1,2,3) (1648791254000,1,2,3);
|
||||
|
||||
$loop_count = 0
|
||||
loop18:
|
||||
sleep 1000
|
||||
sql select * from streamt4;
|
||||
|
||||
$loop_count = $loop_count + 1
|
||||
if $loop_count == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $rows != 1 then
|
||||
print =====rows=$rows
|
||||
goto loop18
|
||||
endi
|
||||
|
||||
if $data01 != 4 then
|
||||
print =====data01=$data01
|
||||
goto loop18
|
||||
endi
|
||||
|
||||
print =====over
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
./test.sh -f tsim/dnode/balance2.sim
|
||||
./test.sh -f tsim/vnode/replica3_repeat.sim
|
||||
./test.sh -f tsim/parser/col_arithmetic_operation.sim
|
||||
./test.sh -f tsim/trans/create_db.sim
|
||||
./test.sh -f tsim/dnode/balance3.sim
|
||||
./test.sh -f tsim/vnode/replica3_many.sim
|
||||
./test.sh -f tsim/stable/metrics_idx.sim
|
||||
|
@ -201,6 +200,7 @@
|
|||
./test.sh -f tsim/query/show_db_table_kind.sim
|
||||
./test.sh -f tsim/query/bi_star_table.sim
|
||||
./test.sh -f tsim/query/bi_tag_scan.sim
|
||||
./test.sh -f tsim/query/bi_tbname_col.sim
|
||||
./test.sh -f tsim/query/tag_scan.sim
|
||||
./test.sh -f tsim/query/nullColSma.sim
|
||||
./test.sh -f tsim/query/bug3398.sim
|
||||
|
|
|
@ -164,7 +164,7 @@ class TDTestCase:
|
|||
self.c2Sum = None
|
||||
|
||||
# create database db
|
||||
sql = f"create database @db_name vgroups {self.vgroups1} replica 1"
|
||||
sql = f"create database @db_name vgroups {self.vgroups1} replica 1 wal_retention_period 1 wal_retention_size 1"
|
||||
self.exeDouble(sql)
|
||||
|
||||
# create super talbe st
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue