merge main
This commit is contained in:
commit
00f15c19aa
|
@ -189,7 +189,7 @@ show table distributed d0\G;
|
||||||
<summary> Show Example </summary>
|
<summary> Show Example </summary>
|
||||||
<pre><code>
|
<pre><code>
|
||||||
*************************** 1.row ***************************
|
*************************** 1.row ***************************
|
||||||
_block_dist: Total_Blocks=[5] Total_Size=[93.65 Kb] Average_size=[18.73 Kb] Compression_Ratio=[23.98 %]
|
_block_dist: Total_Blocks=[5] Total_Size=[93.65 KB] Average_size=[18.73 KB] Compression_Ratio=[23.98 %]
|
||||||
|
|
||||||
Total_Blocks : Table `d0` contains total 5 blocks
|
Total_Blocks : Table `d0` contains total 5 blocks
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
taos.exec_many([
|
taos.exec_many([
|
||||||
format!("DROP TOPIC IF EXISTS tmq_meters"),
|
format!("DROP TOPIC IF EXISTS tmq_meters"),
|
||||||
format!("DROP DATABASE IF EXISTS `{db}`"),
|
format!("DROP DATABASE IF EXISTS `{db}`"),
|
||||||
format!("CREATE DATABASE `{db}`"),
|
format!("CREATE DATABASE `{db}` WAL_RETENTION_PERIOD 3600"),
|
||||||
format!("USE `{db}`"),
|
format!("USE `{db}`"),
|
||||||
// create super table
|
// create super table
|
||||||
format!("CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(24))"),
|
format!("CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(24))"),
|
||||||
|
|
|
@ -189,7 +189,7 @@ SHOW TABLE DISTRIBUTED table_name;
|
||||||
|
|
||||||
*************************** 1.row ***************************
|
*************************** 1.row ***************************
|
||||||
|
|
||||||
_block_dist: Total_Blocks=[5] Total_Size=[93.65 Kb] Average_size=[18.73 Kb] Compression_Ratio=[23.98 %]
|
_block_dist: Total_Blocks=[5] Total_Size=[93.65 KB] Average_size=[18.73 KB] Compression_Ratio=[23.98 %]
|
||||||
|
|
||||||
Total_Blocks: 表 d0 占用的 block 个数为 5 个
|
Total_Blocks: 表 d0 占用的 block 个数为 5 个
|
||||||
|
|
||||||
|
|
|
@ -212,14 +212,6 @@ enum {
|
||||||
FETCH_TYPE__NONE,
|
FETCH_TYPE__NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int8_t fetchType;
|
|
||||||
union {
|
|
||||||
SSDataBlock data;
|
|
||||||
void* meta;
|
|
||||||
};
|
|
||||||
} SFetchRet;
|
|
||||||
|
|
||||||
typedef struct SVarColAttr {
|
typedef struct SVarColAttr {
|
||||||
int32_t* offset; // start position for each entry in the list
|
int32_t* offset; // start position for each entry in the list
|
||||||
uint32_t length; // used buffer size that contain the valid data
|
uint32_t length; // used buffer size that contain the valid data
|
||||||
|
|
|
@ -415,7 +415,7 @@ static FORCE_INLINE SSchemaWrapper* tCloneSSchemaWrapper(const SSchemaWrapper* p
|
||||||
return pSW;
|
return pSW;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE void tDeleteSSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
|
static FORCE_INLINE void tDeleteSchemaWrapper(SSchemaWrapper* pSchemaWrapper) {
|
||||||
if (pSchemaWrapper) {
|
if (pSchemaWrapper) {
|
||||||
taosMemoryFree(pSchemaWrapper->pSchema);
|
taosMemoryFree(pSchemaWrapper->pSchema);
|
||||||
taosMemoryFree(pSchemaWrapper);
|
taosMemoryFree(pSchemaWrapper);
|
||||||
|
@ -3421,10 +3421,10 @@ typedef struct {
|
||||||
char data[]; // SSubmitReq2
|
char data[]; // SSubmitReq2
|
||||||
} SSubmitReq2Msg;
|
} SSubmitReq2Msg;
|
||||||
|
|
||||||
int32_t tEncodeSSubmitReq2(SEncoder* pCoder, const SSubmitReq2* pReq);
|
int32_t tEncodeSubmitReq(SEncoder* pCoder, const SSubmitReq2* pReq);
|
||||||
int32_t tDecodeSSubmitReq2(SDecoder* pCoder, SSubmitReq2* pReq);
|
int32_t tDecodeSubmitReq(SDecoder* pCoder, SSubmitReq2* pReq);
|
||||||
void tDestroySSubmitTbData(SSubmitTbData* pTbData, int32_t flag);
|
void tDestroySubmitTbData(SSubmitTbData* pTbData, int32_t flag);
|
||||||
void tDestroySSubmitReq(SSubmitReq2* pReq, int32_t flag);
|
void tDestroySubmitReq(SSubmitReq2* pReq, int32_t flag);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int32_t affectedRows;
|
int32_t affectedRows;
|
||||||
|
|
|
@ -190,9 +190,9 @@ STimeWindow getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int
|
||||||
|
|
||||||
SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo);
|
SArray* qGetQueriedTableListInfo(qTaskInfo_t tinfo);
|
||||||
|
|
||||||
int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType);
|
void verifyOffset(void *pWalReader, STqOffsetVal* pOffset);
|
||||||
|
|
||||||
int32_t qStreamSetScanMemData(qTaskInfo_t tinfo, SPackedData submit);
|
int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType);
|
||||||
|
|
||||||
void qStreamSetOpen(qTaskInfo_t tinfo);
|
void qStreamSetOpen(qTaskInfo_t tinfo);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ enum {
|
||||||
TASK_STATUS__RECOVER_PREPARE,
|
TASK_STATUS__RECOVER_PREPARE,
|
||||||
TASK_STATUS__RECOVER1,
|
TASK_STATUS__RECOVER1,
|
||||||
TASK_STATUS__RECOVER2,
|
TASK_STATUS__RECOVER2,
|
||||||
TASK_STATUS__RESTORE, // only available for source task to replay WAL from the checkpoint
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -341,12 +340,13 @@ typedef struct SStreamMeta {
|
||||||
TTB* pTaskDb;
|
TTB* pTaskDb;
|
||||||
TTB* pCheckpointDb;
|
TTB* pCheckpointDb;
|
||||||
SHashObj* pTasks;
|
SHashObj* pTasks;
|
||||||
|
SArray* pTaskList; // SArray<task_id*>
|
||||||
void* ahandle;
|
void* ahandle;
|
||||||
TXN* txn;
|
TXN* txn;
|
||||||
FTaskExpand* expandFunc;
|
FTaskExpand* expandFunc;
|
||||||
int32_t vgId;
|
int32_t vgId;
|
||||||
SRWLatch lock;
|
SRWLatch lock;
|
||||||
int32_t walScan;
|
int32_t walScanCounter;
|
||||||
} SStreamMeta;
|
} SStreamMeta;
|
||||||
|
|
||||||
int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo);
|
int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo);
|
||||||
|
@ -545,8 +545,9 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz);
|
||||||
// recover and fill history
|
// recover and fill history
|
||||||
int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version);
|
int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version);
|
||||||
int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version);
|
int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version);
|
||||||
int32_t streamProcessTaskCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq);
|
int32_t streamTaskCheckStatus(SStreamTask* pTask);
|
||||||
int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version);
|
int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version);
|
||||||
|
|
||||||
// common
|
// common
|
||||||
int32_t streamSetParamForRecover(SStreamTask* pTask);
|
int32_t streamSetParamForRecover(SStreamTask* pTask);
|
||||||
int32_t streamRestoreParam(SStreamTask* pTask);
|
int32_t streamRestoreParam(SStreamTask* pTask);
|
||||||
|
|
|
@ -132,7 +132,7 @@ typedef struct {
|
||||||
} SWalRef;
|
} SWalRef;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int8_t scanUncommited;
|
// int8_t scanUncommited;
|
||||||
int8_t scanNotApplied;
|
int8_t scanNotApplied;
|
||||||
int8_t scanMeta;
|
int8_t scanMeta;
|
||||||
int8_t enableRef;
|
int8_t enableRef;
|
||||||
|
@ -147,8 +147,6 @@ typedef struct SWalReader {
|
||||||
int64_t curFileFirstVer;
|
int64_t curFileFirstVer;
|
||||||
int64_t curVersion;
|
int64_t curVersion;
|
||||||
int64_t capacity;
|
int64_t capacity;
|
||||||
// int8_t curInvalid;
|
|
||||||
// int8_t curStopped;
|
|
||||||
TdThreadMutex mutex;
|
TdThreadMutex mutex;
|
||||||
SWalFilterCond cond;
|
SWalFilterCond cond;
|
||||||
// TODO remove it
|
// TODO remove it
|
||||||
|
|
|
@ -146,7 +146,7 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_TSC_CONN_KILLED TAOS_DEF_ERROR_CODE(0, 0x0215)
|
#define TSDB_CODE_TSC_CONN_KILLED TAOS_DEF_ERROR_CODE(0, 0x0215)
|
||||||
#define TSDB_CODE_TSC_SQL_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x0216)
|
#define TSDB_CODE_TSC_SQL_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x0216)
|
||||||
#define TSDB_CODE_TSC_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0217)
|
#define TSDB_CODE_TSC_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0217)
|
||||||
#define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218)
|
//#define TSDB_CODE_TSC_INVALID_TABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x0218)
|
||||||
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219)
|
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219)
|
||||||
#define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A)
|
#define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A)
|
||||||
#define TSDB_CODE_TSC_LINE_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x021B)
|
#define TSDB_CODE_TSC_LINE_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x021B)
|
||||||
|
@ -261,6 +261,7 @@ int32_t* taosGetErrno();
|
||||||
// #define TSDB_CODE_MND_INVALID_STABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x036D) // 2.x
|
// #define TSDB_CODE_MND_INVALID_STABLE_NAME TAOS_DEF_ERROR_CODE(0, 0x036D) // 2.x
|
||||||
#define TSDB_CODE_MND_INVALID_STB_OPTION TAOS_DEF_ERROR_CODE(0, 0x036E)
|
#define TSDB_CODE_MND_INVALID_STB_OPTION TAOS_DEF_ERROR_CODE(0, 0x036E)
|
||||||
#define TSDB_CODE_MND_INVALID_ROW_BYTES TAOS_DEF_ERROR_CODE(0, 0x036F)
|
#define TSDB_CODE_MND_INVALID_ROW_BYTES TAOS_DEF_ERROR_CODE(0, 0x036F)
|
||||||
|
#define TSDB_CODE_MND_FIELD_VALUE_OVERFLOW TAOS_DEF_ERROR_CODE(0, 0x0370)
|
||||||
|
|
||||||
|
|
||||||
// mnode-func
|
// mnode-func
|
||||||
|
|
|
@ -55,7 +55,7 @@ else
|
||||||
exit $?
|
exit $?
|
||||||
fi
|
fi
|
||||||
while true; do
|
while true; do
|
||||||
es=$(taos -h $FIRST_EP_HOST -P $FIRST_EP_PORT --check)
|
es=$(taos -h $FIRST_EP_HOST -P $FIRST_EP_PORT --check | grep "^[0-9]*:")
|
||||||
echo ${es}
|
echo ${es}
|
||||||
if [ "${es%%:*}" -eq 2 ]; then
|
if [ "${es%%:*}" -eq 2 ]; then
|
||||||
echo "execute create dnode"
|
echo "execute create dnode"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
es=$(taos --check)
|
es=$(taos --check | grep "^[0-9]*:")
|
||||||
code=${es%%:*}
|
code=${es%%:*}
|
||||||
if [ "$code" -ne "0" ] && [ "$code" -ne "4" ]; then
|
if [ "$code" -ne "0" ] && [ "$code" -ne "4" ]; then
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -169,6 +169,7 @@ typedef struct {
|
||||||
int32_t uid; // used for automatic create child table
|
int32_t uid; // used for automatic create child table
|
||||||
|
|
||||||
SHashObj *childTables;
|
SHashObj *childTables;
|
||||||
|
SHashObj *tableUids;
|
||||||
SHashObj *superTables;
|
SHashObj *superTables;
|
||||||
SHashObj *pVgHash;
|
SHashObj *pVgHash;
|
||||||
|
|
||||||
|
@ -242,6 +243,7 @@ int8_t smlGetTsTypeByLen(int32_t len);
|
||||||
SSmlTableInfo* smlBuildTableInfo(int numRows, const char* measure, int32_t measureLen);
|
SSmlTableInfo* smlBuildTableInfo(int numRows, const char* measure, int32_t measureLen);
|
||||||
SSmlSTableMeta* smlBuildSTableMeta(bool isDataFormat);
|
SSmlSTableMeta* smlBuildSTableMeta(bool isDataFormat);
|
||||||
int32_t smlSetCTableName(SSmlTableInfo *oneTable);
|
int32_t smlSetCTableName(SSmlTableInfo *oneTable);
|
||||||
|
void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo);
|
||||||
STableMeta* smlGetMeta(SSmlHandle *info, const void* measure, int32_t measureLen);
|
STableMeta* smlGetMeta(SSmlHandle *info, const void* measure, int32_t measureLen);
|
||||||
int32_t is_same_child_table_telnet(const void *a, const void *b);
|
int32_t is_same_child_table_telnet(const void *a, const void *b);
|
||||||
int64_t smlParseOpenTsdbTime(SSmlHandle *info, const char *data, int32_t len);
|
int64_t smlParseOpenTsdbTime(SSmlHandle *info, const char *data, int32_t len);
|
||||||
|
|
|
@ -191,7 +191,7 @@ void taos_free_result(TAOS_RES *res) {
|
||||||
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
||||||
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
||||||
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
||||||
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
// taosx
|
// taosx
|
||||||
taosArrayDestroy(pRsp->rsp.createTableLen);
|
taosArrayDestroy(pRsp->rsp.createTableLen);
|
||||||
taosArrayDestroyP(pRsp->rsp.createTableReq, taosMemoryFree);
|
taosArrayDestroyP(pRsp->rsp.createTableReq, taosMemoryFree);
|
||||||
|
@ -204,7 +204,7 @@ void taos_free_result(TAOS_RES *res) {
|
||||||
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
taosArrayDestroyP(pRsp->rsp.blockData, taosMemoryFree);
|
||||||
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
taosArrayDestroy(pRsp->rsp.blockDataLen);
|
||||||
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
taosArrayDestroyP(pRsp->rsp.blockTbName, taosMemoryFree);
|
||||||
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->rsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
pRsp->resInfo.pRspMsg = NULL;
|
pRsp->resInfo.pRspMsg = NULL;
|
||||||
doFreeReqResultInfo(&pRsp->resInfo);
|
doFreeReqResultInfo(&pRsp->resInfo);
|
||||||
taosMemoryFree(pRsp);
|
taosMemoryFree(pRsp);
|
||||||
|
|
|
@ -195,6 +195,20 @@ int32_t smlSetCTableName(SSmlTableInfo *oneTable) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getTableUid(SSmlHandle *info, SSmlLineInfo *currElement, SSmlTableInfo *tinfo){
|
||||||
|
char key[TSDB_TABLE_NAME_LEN * 2 + 1] = {0};
|
||||||
|
size_t nLen = strlen(tinfo->childTableName);
|
||||||
|
memcpy(key, currElement->measure, currElement->measureLen);
|
||||||
|
memcpy(key + currElement->measureLen + 1, tinfo->childTableName, nLen);
|
||||||
|
void *uid = taosHashGet(info->tableUids, key, currElement->measureLen + 1 + nLen); // use \0 as separator for stable name and child table name
|
||||||
|
if (uid == NULL) {
|
||||||
|
tinfo->uid = info->uid++;
|
||||||
|
taosHashPut(info->tableUids, key, currElement->measureLen + 1 + nLen, &tinfo->uid, sizeof(uint64_t));
|
||||||
|
}else{
|
||||||
|
tinfo->uid = *(uint64_t*)uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SSmlSTableMeta *smlBuildSTableMeta(bool isDataFormat) {
|
SSmlSTableMeta *smlBuildSTableMeta(bool isDataFormat) {
|
||||||
SSmlSTableMeta *meta = (SSmlSTableMeta *)taosMemoryCalloc(sizeof(SSmlSTableMeta), 1);
|
SSmlSTableMeta *meta = (SSmlSTableMeta *)taosMemoryCalloc(sizeof(SSmlSTableMeta), 1);
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
|
@ -534,7 +548,7 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm
|
||||||
uint16_t *index = colHash ? (uint16_t *)taosHashGet(colHash, kv->key, kv->keyLen) : NULL;
|
uint16_t *index = colHash ? (uint16_t *)taosHashGet(colHash, kv->key, kv->keyLen) : NULL;
|
||||||
if (index) {
|
if (index) {
|
||||||
if (colField[*index].type != kv->type) {
|
if (colField[*index].type != kv->type) {
|
||||||
uError("SML:0x%" PRIx64 " point type and db type mismatch. point type: %d, db type: %d, key: %s", info->id, colField[*index].type, kv->type, kv->key);
|
uError("SML:0x%" PRIx64 " point type and db type mismatch. db type: %d, point type: %d, key: %s", info->id, colField[*index].type, kv->type, kv->key);
|
||||||
return TSDB_CODE_SML_INVALID_DATA;
|
return TSDB_CODE_SML_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,10 +572,15 @@ static int32_t smlGenerateSchemaAction(SSchema *colField, SHashObj *colHash, SSm
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BOUNDARY 1024
|
||||||
static int32_t smlFindNearestPowerOf2(int32_t length, uint8_t type) {
|
static int32_t smlFindNearestPowerOf2(int32_t length, uint8_t type) {
|
||||||
int32_t result = 1;
|
int32_t result = 1;
|
||||||
while (result <= length) {
|
if (length >= BOUNDARY){
|
||||||
result *= 2;
|
result = length;
|
||||||
|
}else{
|
||||||
|
while (result <= length) {
|
||||||
|
result *= 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (type == TSDB_DATA_TYPE_BINARY && result > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
|
if (type == TSDB_DATA_TYPE_BINARY && result > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
|
||||||
result = TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE;
|
result = TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE;
|
||||||
|
@ -657,7 +676,7 @@ static int32_t smlBuildFieldsList(SSmlHandle *info, SSchema *schemaField, SHashO
|
||||||
len += field->bytes;
|
len += field->bytes;
|
||||||
}
|
}
|
||||||
if(len > maxLen){
|
if(len > maxLen){
|
||||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
return isTag ? TSDB_CODE_PAR_INVALID_TAGS_LENGTH : TSDB_CODE_PAR_INVALID_ROW_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1137,6 +1156,7 @@ void smlDestroyInfo(SSmlHandle *info) {
|
||||||
taosHashCleanup(info->pVgHash);
|
taosHashCleanup(info->pVgHash);
|
||||||
taosHashCleanup(info->childTables);
|
taosHashCleanup(info->childTables);
|
||||||
taosHashCleanup(info->superTables);
|
taosHashCleanup(info->superTables);
|
||||||
|
taosHashCleanup(info->tableUids);
|
||||||
|
|
||||||
for (int i = 0; i < taosArrayGetSize(info->tagJsonArray); i++) {
|
for (int i = 0; i < taosArrayGetSize(info->tagJsonArray); i++) {
|
||||||
cJSON *tags = (cJSON *)taosArrayGetP(info->tagJsonArray, i);
|
cJSON *tags = (cJSON *)taosArrayGetP(info->tagJsonArray, i);
|
||||||
|
@ -1187,6 +1207,7 @@ SSmlHandle *smlBuildSmlInfo(TAOS *taos) {
|
||||||
|
|
||||||
info->pVgHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
|
info->pVgHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
|
||||||
info->childTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
info->childTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||||
|
info->tableUids = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||||
info->superTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
info->superTables = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||||
|
|
||||||
info->id = smlGenId();
|
info->id = smlGenId();
|
||||||
|
@ -1197,7 +1218,7 @@ SSmlHandle *smlBuildSmlInfo(TAOS *taos) {
|
||||||
info->valueJsonArray = taosArrayInit(8, POINTER_BYTES);
|
info->valueJsonArray = taosArrayInit(8, POINTER_BYTES);
|
||||||
info->preLineTagKV = taosArrayInit(8, sizeof(SSmlKv));
|
info->preLineTagKV = taosArrayInit(8, sizeof(SSmlKv));
|
||||||
|
|
||||||
if (NULL == info->pVgHash || NULL == info->childTables || NULL == info->superTables) {
|
if (NULL == info->pVgHash || NULL == info->childTables || NULL == info->superTables || NULL == info->tableUids) {
|
||||||
uError("create SSmlHandle failed");
|
uError("create SSmlHandle failed");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -1315,23 +1336,23 @@ static int32_t smlInsertData(SSmlHandle *info) {
|
||||||
if (info->pRequest->dbList == NULL) {
|
if (info->pRequest->dbList == NULL) {
|
||||||
info->pRequest->dbList = taosArrayInit(1, TSDB_DB_FNAME_LEN);
|
info->pRequest->dbList = taosArrayInit(1, TSDB_DB_FNAME_LEN);
|
||||||
}
|
}
|
||||||
void *data = taosArrayReserve(info->pRequest->dbList, 1);
|
char *data = (char*)taosArrayReserve(info->pRequest->dbList, 1);
|
||||||
memcpy(data, info->pRequest->pDb,
|
SName pName = {TSDB_TABLE_NAME_T, info->taos->acctId, {0}, {0}};
|
||||||
TSDB_DB_FNAME_LEN > strlen(info->pRequest->pDb) ? strlen(info->pRequest->pDb) : TSDB_DB_FNAME_LEN);
|
tstrncpy(pName.dbname, info->pRequest->pDb, sizeof(pName.dbname));
|
||||||
|
tNameGetFullDbName(&pName, data);
|
||||||
|
|
||||||
SSmlTableInfo **oneTable = (SSmlTableInfo **)taosHashIterate(info->childTables, NULL);
|
SSmlTableInfo **oneTable = (SSmlTableInfo **)taosHashIterate(info->childTables, NULL);
|
||||||
while (oneTable) {
|
while (oneTable) {
|
||||||
SSmlTableInfo *tableData = *oneTable;
|
SSmlTableInfo *tableData = *oneTable;
|
||||||
|
tstrncpy(pName.tname, tableData->sTableName, tableData->sTableNameLen + 1);
|
||||||
SName pName = {TSDB_TABLE_NAME_T, info->taos->acctId, {0}, {0}};
|
|
||||||
tstrncpy(pName.dbname, info->pRequest->pDb, sizeof(pName.dbname));
|
|
||||||
memcpy(pName.tname, tableData->childTableName, strlen(tableData->childTableName));
|
|
||||||
|
|
||||||
if (info->pRequest->tableList == NULL) {
|
if (info->pRequest->tableList == NULL) {
|
||||||
info->pRequest->tableList = taosArrayInit(1, sizeof(SName));
|
info->pRequest->tableList = taosArrayInit(1, sizeof(SName));
|
||||||
}
|
}
|
||||||
taosArrayPush(info->pRequest->tableList, &pName);
|
taosArrayPush(info->pRequest->tableList, &pName);
|
||||||
|
|
||||||
|
strcpy(pName.tname, tableData->childTableName);
|
||||||
|
|
||||||
SRequestConnInfo conn = {0};
|
SRequestConnInfo conn = {0};
|
||||||
conn.pTrans = info->taos->pAppInfo->pTransporter;
|
conn.pTrans = info->taos->pAppInfo->pTransporter;
|
||||||
conn.requestId = info->pRequest->requestId;
|
conn.requestId = info->pRequest->requestId;
|
||||||
|
@ -1423,6 +1444,7 @@ int32_t smlClearForRerun(SSmlHandle *info) {
|
||||||
|
|
||||||
taosHashClear(info->childTables);
|
taosHashClear(info->childTables);
|
||||||
taosHashClear(info->superTables);
|
taosHashClear(info->superTables);
|
||||||
|
taosHashClear(info->tableUids);
|
||||||
|
|
||||||
if (!info->dataFormat) {
|
if (!info->dataFormat) {
|
||||||
if (unlikely(info->lines != NULL)) {
|
if (unlikely(info->lines != NULL)) {
|
||||||
|
@ -1557,7 +1579,10 @@ static int smlProcess(SSmlHandle *info, char *lines[], char *rawLine, char *rawL
|
||||||
do {
|
do {
|
||||||
code = smlModifyDBSchemas(info);
|
code = smlModifyDBSchemas(info);
|
||||||
if (code == 0 || code == TSDB_CODE_SML_INVALID_DATA || code == TSDB_CODE_PAR_TOO_MANY_COLUMNS
|
if (code == 0 || code == TSDB_CODE_SML_INVALID_DATA || code == TSDB_CODE_PAR_TOO_MANY_COLUMNS
|
||||||
|| code == TSDB_CODE_PAR_INVALID_TAGS_NUM) break;
|
|| code == TSDB_CODE_PAR_INVALID_TAGS_NUM || code == TSDB_CODE_PAR_INVALID_TAGS_LENGTH
|
||||||
|
|| code == TSDB_CODE_PAR_INVALID_ROW_LENGTH || code == TSDB_CODE_MND_FIELD_VALUE_OVERFLOW) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
taosMsleep(100);
|
taosMsleep(100);
|
||||||
uInfo("SML:0x%" PRIx64 " smlModifyDBSchemas retry code:%s, times:%d", info->id, tstrerror(code), retryNum);
|
uInfo("SML:0x%" PRIx64 " smlModifyDBSchemas retry code:%s, times:%d", info->id, tstrerror(code), retryNum);
|
||||||
} while (retryNum++ < taosHashGetSize(info->superTables) * MAX_RETRY_TIMES);
|
} while (retryNum++ < taosHashGetSize(info->superTables) * MAX_RETRY_TIMES);
|
||||||
|
@ -1642,7 +1667,8 @@ TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine,
|
||||||
info->cost.endTime = taosGetTimestampUs();
|
info->cost.endTime = taosGetTimestampUs();
|
||||||
info->cost.code = code;
|
info->cost.code = code;
|
||||||
if (code == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || code == TSDB_CODE_SDB_OBJ_CREATING ||
|
if (code == TSDB_CODE_TDB_INVALID_TABLE_SCHEMA_VER || code == TSDB_CODE_SDB_OBJ_CREATING ||
|
||||||
code == TSDB_CODE_PAR_VALUE_TOO_LONG || code == TSDB_CODE_MND_TRANS_CONFLICT) {
|
code == TSDB_CODE_PAR_VALUE_TOO_LONG || code == TSDB_CODE_MND_TRANS_CONFLICT ||
|
||||||
|
code == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
|
||||||
if (cnt++ >= 10) {
|
if (cnt++ >= 10) {
|
||||||
uInfo("SML:%" PRIx64 " retry:%d/10 end code:%d, msg:%s", info->id, cnt, code, tstrerror(code));
|
uInfo("SML:%" PRIx64 " retry:%d/10 end code:%d, msg:%s", info->id, cnt, code, tstrerror(code));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -778,7 +778,7 @@ static int32_t smlParseTagsFromJSON(SSmlHandle *info, cJSON *tags, SSmlLineInfo
|
||||||
tinfo->tags = taosArrayDup(preLineKV, NULL);
|
tinfo->tags = taosArrayDup(preLineKV, NULL);
|
||||||
|
|
||||||
smlSetCTableName(tinfo);
|
smlSetCTableName(tinfo);
|
||||||
tinfo->uid = info->uid++;
|
getTableUid(info, elements, tinfo);
|
||||||
if (info->dataFormat) {
|
if (info->dataFormat) {
|
||||||
info->currSTableMeta->uid = tinfo->uid;
|
info->currSTableMeta->uid = tinfo->uid;
|
||||||
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
||||||
|
|
|
@ -312,7 +312,7 @@ static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLin
|
||||||
}
|
}
|
||||||
|
|
||||||
smlSetCTableName(tinfo);
|
smlSetCTableName(tinfo);
|
||||||
tinfo->uid = info->uid++;
|
getTableUid(info, currElement, tinfo);
|
||||||
if (info->dataFormat) {
|
if (info->dataFormat) {
|
||||||
info->currSTableMeta->uid = tinfo->uid;
|
info->currSTableMeta->uid = tinfo->uid;
|
||||||
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
||||||
|
|
|
@ -206,7 +206,7 @@ static int32_t smlParseTelnetTags(SSmlHandle *info, char *data, char *sqlEnd, SS
|
||||||
tinfo->tags = taosArrayDup(preLineKV, NULL);
|
tinfo->tags = taosArrayDup(preLineKV, NULL);
|
||||||
|
|
||||||
smlSetCTableName(tinfo);
|
smlSetCTableName(tinfo);
|
||||||
tinfo->uid = info->uid++;
|
getTableUid(info, elements, tinfo);
|
||||||
if (info->dataFormat) {
|
if (info->dataFormat) {
|
||||||
info->currSTableMeta->uid = tinfo->uid;
|
info->currSTableMeta->uid = tinfo->uid;
|
||||||
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
|
||||||
|
|
|
@ -325,7 +325,7 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool deepClean) {
|
||||||
taosHashCleanup(pStmt->exec.pBlockHash);
|
taosHashCleanup(pStmt->exec.pBlockHash);
|
||||||
pStmt->exec.pBlockHash = NULL;
|
pStmt->exec.pBlockHash = NULL;
|
||||||
|
|
||||||
tDestroySSubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFreeClear(pStmt->exec.pCurrTbData);
|
taosMemoryFreeClear(pStmt->exec.pCurrTbData);
|
||||||
|
|
||||||
STMT_ERR_RET(stmtCleanBindInfo(pStmt));
|
STMT_ERR_RET(stmtCleanBindInfo(pStmt));
|
||||||
|
@ -895,7 +895,7 @@ int stmtExec(TAOS_STMT* stmt) {
|
||||||
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
if (STMT_TYPE_QUERY == pStmt->sql.type) {
|
||||||
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, true, NULL);
|
launchQueryImpl(pStmt->exec.pRequest, pStmt->sql.pQuery, true, NULL);
|
||||||
} else {
|
} else {
|
||||||
tDestroySSubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(pStmt->exec.pCurrTbData, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFreeClear(pStmt->exec.pCurrTbData);
|
taosMemoryFreeClear(pStmt->exec.pCurrTbData);
|
||||||
|
|
||||||
STMT_ERR_RET(qCloneCurrentTbData(pStmt->exec.pCurrBlock, &pStmt->exec.pCurrTbData));
|
STMT_ERR_RET(qCloneCurrentTbData(pStmt->exec.pCurrBlock, &pStmt->exec.pCurrTbData));
|
||||||
|
|
|
@ -864,7 +864,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) {
|
||||||
taosArrayDestroyP(pRsp->dataRsp.blockData, taosMemoryFree);
|
taosArrayDestroyP(pRsp->dataRsp.blockData, taosMemoryFree);
|
||||||
taosArrayDestroy(pRsp->dataRsp.blockDataLen);
|
taosArrayDestroy(pRsp->dataRsp.blockDataLen);
|
||||||
taosArrayDestroyP(pRsp->dataRsp.blockTbName, taosMemoryFree);
|
taosArrayDestroyP(pRsp->dataRsp.blockTbName, taosMemoryFree);
|
||||||
taosArrayDestroyP(pRsp->dataRsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->dataRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
} else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
} else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||||
SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
|
SMqPollRspWrapper* pRsp = (SMqPollRspWrapper*)rspWrapper;
|
||||||
taosMemoryFreeClear(pRsp->pEpset);
|
taosMemoryFreeClear(pRsp->pEpset);
|
||||||
|
@ -877,7 +877,7 @@ static void* tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) {
|
||||||
taosArrayDestroyP(pRsp->taosxRsp.blockData, taosMemoryFree);
|
taosArrayDestroyP(pRsp->taosxRsp.blockData, taosMemoryFree);
|
||||||
taosArrayDestroy(pRsp->taosxRsp.blockDataLen);
|
taosArrayDestroy(pRsp->taosxRsp.blockDataLen);
|
||||||
taosArrayDestroyP(pRsp->taosxRsp.blockTbName, taosMemoryFree);
|
taosArrayDestroyP(pRsp->taosxRsp.blockTbName, taosMemoryFree);
|
||||||
taosArrayDestroyP(pRsp->taosxRsp.blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->taosxRsp.blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
// taosx
|
// taosx
|
||||||
taosArrayDestroy(pRsp->taosxRsp.createTableLen);
|
taosArrayDestroy(pRsp->taosxRsp.createTableLen);
|
||||||
taosArrayDestroyP(pRsp->taosxRsp.createTableReq, taosMemoryFree);
|
taosArrayDestroyP(pRsp->taosxRsp.createTableReq, taosMemoryFree);
|
||||||
|
@ -1377,7 +1377,7 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
||||||
tstrncpy(pTopic->topicName, pTopicEp->topic, TSDB_TOPIC_FNAME_LEN);
|
tstrncpy(pTopic->topicName, pTopicEp->topic, TSDB_TOPIC_FNAME_LEN);
|
||||||
tstrncpy(pTopic->db, pTopicEp->db, TSDB_DB_FNAME_LEN);
|
tstrncpy(pTopic->db, pTopicEp->db, TSDB_DB_FNAME_LEN);
|
||||||
|
|
||||||
tscDebug("consumer:0x%" PRIx64 ", update topic:%s, numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
|
tscDebug("consumer:0x%" PRIx64 ", update topic:%s, new numOfVgs:%d", tmq->consumerId, pTopic->topicName, vgNumGet);
|
||||||
pTopic->vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
|
pTopic->vgs = taosArrayInit(vgNumGet, sizeof(SMqClientVg));
|
||||||
|
|
||||||
for (int32_t j = 0; j < vgNumGet; j++) {
|
for (int32_t j = 0; j < vgNumGet; j++) {
|
||||||
|
@ -1447,14 +1447,14 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
||||||
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
SMqClientTopic* pTopicCur = taosArrayGet(tmq->clientTopics, i);
|
||||||
if (pTopicCur->vgs) {
|
if (pTopicCur->vgs) {
|
||||||
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
int32_t vgNumCur = taosArrayGetSize(pTopicCur->vgs);
|
||||||
tscDebug("consumer:0x%" PRIx64 ", new vg num: %d", tmq->consumerId, vgNumCur);
|
tscDebug("consumer:0x%" PRIx64 ", current vg num: %d", tmq->consumerId, vgNumCur);
|
||||||
for (int32_t j = 0; j < vgNumCur; j++) {
|
for (int32_t j = 0; j < vgNumCur; j++) {
|
||||||
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
SMqClientVg* pVgCur = taosArrayGet(pTopicCur->vgs, j);
|
||||||
makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
|
makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
|
||||||
|
|
||||||
char buf[80];
|
char buf[80];
|
||||||
tFormatOffset(buf, 80, &pVgCur->currentOffset);
|
tFormatOffset(buf, 80, &pVgCur->currentOffset);
|
||||||
tscDebug("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
|
tscDebug("consumer:0x%" PRIx64 ", doUpdateLocalEp current vg, epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, tmq->epoch, pVgCur->vgId,
|
||||||
vgKey, buf);
|
vgKey, buf);
|
||||||
|
|
||||||
SVgroupSaveInfo info = {.offset = pVgCur->currentOffset, .numOfRows = pVgCur->numOfRows};
|
SVgroupSaveInfo info = {.offset = pVgCur->currentOffset, .numOfRows = pVgCur->numOfRows};
|
||||||
|
@ -1790,8 +1790,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
pVg->epSet = *pollRspWrapper->pEpset;
|
pVg->epSet = *pollRspWrapper->pEpset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the local offset value only for the returned values.
|
if(pDataRsp->rspOffset.type != 0){ // if offset is validate
|
||||||
pVg->currentOffset = pDataRsp->rspOffset;
|
pVg->currentOffset = pDataRsp->rspOffset; // update the local offset value only for the returned values.
|
||||||
|
}
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
|
|
||||||
char buf[80];
|
char buf[80];
|
||||||
|
@ -1801,12 +1802,13 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
" total:%" PRId64 " reqId:0x%" PRIx64,
|
" total:%" PRId64 " reqId:0x%" PRIx64,
|
||||||
tmq->consumerId, pVg->vgId, buf, pVg->numOfRows, tmq->totalRows, pollRspWrapper->reqId);
|
tmq->consumerId, pVg->vgId, buf, pVg->numOfRows, tmq->totalRows, pollRspWrapper->reqId);
|
||||||
pRspWrapper = tmqFreeRspWrapper(pRspWrapper);
|
pRspWrapper = tmqFreeRspWrapper(pRspWrapper);
|
||||||
|
pVg->emptyBlockReceiveTs = taosGetTimestampMs();
|
||||||
taosFreeQitem(pollRspWrapper);
|
taosFreeQitem(pollRspWrapper);
|
||||||
} else { // build rsp
|
} else { // build rsp
|
||||||
int64_t numOfRows = 0;
|
int64_t numOfRows = 0;
|
||||||
SMqRspObj* pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
SMqRspObj* pRsp = tmqBuildRspFromWrapper(pollRspWrapper, pVg, &numOfRows);
|
||||||
tmq->totalRows += numOfRows;
|
tmq->totalRows += numOfRows;
|
||||||
|
pVg->emptyBlockReceiveTs = 0;
|
||||||
tscDebug("consumer:0x%" PRIx64 " process poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
|
tscDebug("consumer:0x%" PRIx64 " process poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
|
||||||
" vg total:%" PRId64 " total:%" PRId64 ", reqId:0x%" PRIx64,
|
" vg total:%" PRId64 " total:%" PRId64 ", reqId:0x%" PRIx64,
|
||||||
tmq->consumerId, pVg->vgId, buf, pDataRsp->blockNum, numOfRows, pVg->numOfRows, tmq->totalRows,
|
tmq->consumerId, pVg->vgId, buf, pDataRsp->blockNum, numOfRows, pVg->numOfRows, tmq->totalRows,
|
||||||
|
@ -1828,7 +1830,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
|
|
||||||
if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) {
|
if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) {
|
||||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||||
pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset;
|
if(pollRspWrapper->metaRsp.rspOffset.type != 0){ // if offset is validate
|
||||||
|
pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset;
|
||||||
|
}
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
// build rsp
|
// build rsp
|
||||||
SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
|
SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
|
||||||
|
@ -1846,7 +1850,9 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
||||||
|
|
||||||
if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) {
|
if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) {
|
||||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||||
pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
if(pollRspWrapper->taosxRsp.rspOffset.type != 0){ // if offset is validate
|
||||||
|
pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
||||||
|
}
|
||||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||||
|
|
||||||
if (pollRspWrapper->taosxRsp.blockNum == 0) {
|
if (pollRspWrapper->taosxRsp.blockNum == 0) {
|
||||||
|
|
|
@ -1053,9 +1053,9 @@ TEST(clientCase, sub_db_test) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(clientCase, sub_tb_test) {
|
TEST(clientCase, sub_tb_test) {
|
||||||
taos_options(TSDB_OPTION_CONFIGDIR, "/home/tests/dir/cfg/");
|
taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg");
|
||||||
|
|
||||||
TAOS* pConn = taos_connect("vm116", "root", "taosdata", NULL, 0);
|
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||||
ASSERT_NE(pConn, nullptr);
|
ASSERT_NE(pConn, nullptr);
|
||||||
|
|
||||||
tmq_conf_t* conf = tmq_conf_new();
|
tmq_conf_t* conf = tmq_conf_new();
|
||||||
|
@ -1091,7 +1091,7 @@ TEST(clientCase, sub_tb_test) {
|
||||||
int32_t precision = 0;
|
int32_t precision = 0;
|
||||||
int32_t totalRows = 0;
|
int32_t totalRows = 0;
|
||||||
int32_t msgCnt = 0;
|
int32_t msgCnt = 0;
|
||||||
int32_t timeout = 25000;
|
int32_t timeout = 2500000;
|
||||||
|
|
||||||
int32_t count = 0;
|
int32_t count = 0;
|
||||||
|
|
||||||
|
@ -1117,10 +1117,10 @@ TEST(clientCase, sub_tb_test) {
|
||||||
fields = taos_fetch_fields(pRes);
|
fields = taos_fetch_fields(pRes);
|
||||||
numOfFields = taos_field_count(pRes);
|
numOfFields = taos_field_count(pRes);
|
||||||
totalRows += 1;
|
totalRows += 1;
|
||||||
if (totalRows % 100000 == 0) {
|
// if (totalRows % 100000 == 0) {
|
||||||
taos_print_row(buf, row, fields, numOfFields);
|
taos_print_row(buf, row, fields, numOfFields);
|
||||||
printf("row content: %s\n", buf);
|
printf("row content: %s\n", buf);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
taos_free_result(pRes);
|
taos_free_result(pRes);
|
||||||
|
|
|
@ -120,6 +120,7 @@ int32_t colDataSetVal(SColumnInfoData* pColumnInfoData, uint32_t rowIndex, const
|
||||||
pColumnInfoData->varmeta.length += dataLen;
|
pColumnInfoData->varmeta.length += dataLen;
|
||||||
} else {
|
} else {
|
||||||
memcpy(pColumnInfoData->pData + pColumnInfoData->info.bytes * rowIndex, pData, pColumnInfoData->info.bytes);
|
memcpy(pColumnInfoData->pData + pColumnInfoData->info.bytes * rowIndex, pData, pColumnInfoData->info.bytes);
|
||||||
|
colDataClearNull_f(pColumnInfoData->nullbitmap, rowIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1949,12 +1950,11 @@ void blockDebugShowDataBlocks(const SArray* dataBlocks, const char* flag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// for debug
|
// for debug
|
||||||
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) {
|
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) {
|
||||||
int32_t size = 2048;
|
int32_t size = 2048*1024;
|
||||||
*pDataBuf = taosMemoryCalloc(size, 1);
|
*pDataBuf = taosMemoryCalloc(size, 1);
|
||||||
char* dumpBuf = *pDataBuf;
|
char* dumpBuf = *pDataBuf;
|
||||||
char pBuf[128] = {0};
|
char pBuf[128] = {0};
|
||||||
|
@ -1970,7 +1970,7 @@ char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf)
|
||||||
if (len >= size - 1) return dumpBuf;
|
if (len >= size - 1) return dumpBuf;
|
||||||
|
|
||||||
for (int32_t j = 0; j < rows; j++) {
|
for (int32_t j = 0; j < rows; j++) {
|
||||||
len += snprintf(dumpBuf + len, size - len, "%s |", flag);
|
len += snprintf(dumpBuf + len, size - len, "%s %d|", flag, j);
|
||||||
if (len >= size - 1) return dumpBuf;
|
if (len >= size - 1) return dumpBuf;
|
||||||
|
|
||||||
for (int32_t k = 0; k < colNum; k++) {
|
for (int32_t k = 0; k < colNum; k++) {
|
||||||
|
@ -2374,7 +2374,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat
|
||||||
}
|
}
|
||||||
SRow* pRow = NULL;
|
SRow* pRow = NULL;
|
||||||
if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
|
if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
|
||||||
tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
ASSERT(pRow);
|
ASSERT(pRow);
|
||||||
|
@ -2388,7 +2388,7 @@ _end:
|
||||||
if (terrno != 0) {
|
if (terrno != 0) {
|
||||||
*ppReq = NULL;
|
*ppReq = NULL;
|
||||||
if (pReq) {
|
if (pReq) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFreeClear(pReq);
|
taosMemoryFreeClear(pReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1509,7 +1509,9 @@ void tTagSetCid(const STag *pTag, int16_t iTag, int16_t cid) {
|
||||||
// STSchema ========================================
|
// STSchema ========================================
|
||||||
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
|
STSchema *tBuildTSchema(SSchema *aSchema, int32_t numOfCols, int32_t version) {
|
||||||
STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
|
STSchema *pTSchema = taosMemoryCalloc(1, sizeof(STSchema) + sizeof(STColumn) * numOfCols);
|
||||||
if (pTSchema == NULL) return NULL;
|
if (pTSchema == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pTSchema->numOfCols = numOfCols;
|
pTSchema->numOfCols = numOfCols;
|
||||||
pTSchema->version = version;
|
pTSchema->version = version;
|
||||||
|
|
|
@ -84,7 +84,7 @@ bool tsMonitorComp = false;
|
||||||
// telem
|
// telem
|
||||||
bool tsEnableTelem = true;
|
bool tsEnableTelem = true;
|
||||||
int32_t tsTelemInterval = 43200;
|
int32_t tsTelemInterval = 43200;
|
||||||
char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.taosdata.com";
|
char tsTelemServer[TSDB_FQDN_LEN] = "telemetry.tdengine.com";
|
||||||
uint16_t tsTelemPort = 80;
|
uint16_t tsTelemPort = 80;
|
||||||
char *tsTelemUri = "/report";
|
char *tsTelemUri = "/report";
|
||||||
|
|
||||||
|
|
|
@ -5329,9 +5329,9 @@ int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
||||||
int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) {
|
||||||
int32_t headLen = sizeof(SMsgHead);
|
int32_t headLen = sizeof(SMsgHead);
|
||||||
|
|
||||||
SMsgHead *pHead = buf;
|
// SMsgHead *pHead = buf;
|
||||||
pHead->vgId = pReq->head.vgId;
|
// pHead->vgId = pReq->head.vgId;
|
||||||
pHead->contLen = pReq->head.contLen;
|
// pHead->contLen = pReq->head.contLen;
|
||||||
|
|
||||||
SDecoder decoder = {0};
|
SDecoder decoder = {0};
|
||||||
tDecoderInit(&decoder, (char *)buf + headLen, bufLen - headLen);
|
tDecoderInit(&decoder, (char *)buf + headLen, bufLen - headLen);
|
||||||
|
@ -6839,10 +6839,8 @@ int32_t tEncodeSTqOffsetVal(SEncoder *pEncoder, const STqOffsetVal *pOffsetVal)
|
||||||
if (tEncodeI64(pEncoder, pOffsetVal->ts) < 0) return -1;
|
if (tEncodeI64(pEncoder, pOffsetVal->ts) < 0) return -1;
|
||||||
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
||||||
if (tEncodeI64(pEncoder, pOffsetVal->version) < 0) return -1;
|
if (tEncodeI64(pEncoder, pOffsetVal->version) < 0) return -1;
|
||||||
} else if (pOffsetVal->type < 0) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT(0);
|
// do nothing
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6854,10 +6852,8 @@ int32_t tDecodeSTqOffsetVal(SDecoder *pDecoder, STqOffsetVal *pOffsetVal) {
|
||||||
if (tDecodeI64(pDecoder, &pOffsetVal->ts) < 0) return -1;
|
if (tDecodeI64(pDecoder, &pOffsetVal->ts) < 0) return -1;
|
||||||
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
} else if (pOffsetVal->type == TMQ_OFFSET__LOG) {
|
||||||
if (tDecodeI64(pDecoder, &pOffsetVal->version) < 0) return -1;
|
if (tDecodeI64(pDecoder, &pOffsetVal->version) < 0) return -1;
|
||||||
} else if (pOffsetVal->type < 0) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT(0);
|
// do nothing
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -7062,7 +7058,7 @@ void tDeleteSMqDataRsp(SMqDataRsp *pRsp) {
|
||||||
pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
|
pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
|
||||||
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
||||||
pRsp->blockData = NULL;
|
pRsp->blockData = NULL;
|
||||||
taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
pRsp->blockSchema = NULL;
|
pRsp->blockSchema = NULL;
|
||||||
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
||||||
pRsp->blockTbName = NULL;
|
pRsp->blockTbName = NULL;
|
||||||
|
@ -7163,7 +7159,7 @@ void tDeleteSTaosxRsp(STaosxRsp *pRsp) {
|
||||||
pRsp->blockDataLen = NULL;
|
pRsp->blockDataLen = NULL;
|
||||||
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
||||||
pRsp->blockData = NULL;
|
pRsp->blockData = NULL;
|
||||||
taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper);
|
||||||
pRsp->blockSchema = NULL;
|
pRsp->blockSchema = NULL;
|
||||||
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
||||||
pRsp->blockTbName = NULL;
|
pRsp->blockTbName = NULL;
|
||||||
|
@ -7336,7 +7332,7 @@ _exit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tEncodeSSubmitReq2(SEncoder *pCoder, const SSubmitReq2 *pReq) {
|
int32_t tEncodeSubmitReq(SEncoder *pCoder, const SSubmitReq2 *pReq) {
|
||||||
if (tStartEncode(pCoder) < 0) return -1;
|
if (tStartEncode(pCoder) < 0) return -1;
|
||||||
|
|
||||||
if (tEncodeU64v(pCoder, taosArrayGetSize(pReq->aSubmitTbData)) < 0) return -1;
|
if (tEncodeU64v(pCoder, taosArrayGetSize(pReq->aSubmitTbData)) < 0) return -1;
|
||||||
|
@ -7348,7 +7344,7 @@ int32_t tEncodeSSubmitReq2(SEncoder *pCoder, const SSubmitReq2 *pReq) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tDecodeSSubmitReq2(SDecoder *pCoder, SSubmitReq2 *pReq) {
|
int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq) {
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
|
||||||
memset(pReq, 0, sizeof(*pReq));
|
memset(pReq, 0, sizeof(*pReq));
|
||||||
|
@ -7391,7 +7387,7 @@ _exit:
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tDestroySSubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
|
void tDestroySubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
|
||||||
if (NULL == pTbData) {
|
if (NULL == pTbData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -7437,14 +7433,14 @@ void tDestroySSubmitTbData(SSubmitTbData *pTbData, int32_t flag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tDestroySSubmitReq(SSubmitReq2 *pReq, int32_t flag) {
|
void tDestroySubmitReq(SSubmitReq2 *pReq, int32_t flag) {
|
||||||
if (pReq->aSubmitTbData == NULL) return;
|
if (pReq->aSubmitTbData == NULL) return;
|
||||||
|
|
||||||
int32_t nSubmitTbData = TARRAY_SIZE(pReq->aSubmitTbData);
|
int32_t nSubmitTbData = TARRAY_SIZE(pReq->aSubmitTbData);
|
||||||
SSubmitTbData *aSubmitTbData = (SSubmitTbData *)TARRAY_DATA(pReq->aSubmitTbData);
|
SSubmitTbData *aSubmitTbData = (SSubmitTbData *)TARRAY_DATA(pReq->aSubmitTbData);
|
||||||
|
|
||||||
for (int32_t i = 0; i < nSubmitTbData; i++) {
|
for (int32_t i = 0; i < nSubmitTbData; i++) {
|
||||||
tDestroySSubmitTbData(&aSubmitTbData[i], flag);
|
tDestroySubmitTbData(&aSubmitTbData[i], flag);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(pReq->aSubmitTbData);
|
taosArrayDestroy(pReq->aSubmitTbData);
|
||||||
pReq->aSubmitTbData = NULL;
|
pReq->aSubmitTbData = NULL;
|
||||||
|
|
|
@ -87,18 +87,6 @@ static void dmStopDnode(int signum, void *sigInfo, void *context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void dmLogCrash(int signum, void *sigInfo, void *context) {
|
void dmLogCrash(int signum, void *sigInfo, void *context) {
|
||||||
taosIgnSignal(SIGTERM);
|
|
||||||
taosIgnSignal(SIGHUP);
|
|
||||||
taosIgnSignal(SIGINT);
|
|
||||||
taosIgnSignal(SIGBREAK);
|
|
||||||
|
|
||||||
#ifndef WINDOWS
|
|
||||||
taosIgnSignal(SIGBUS);
|
|
||||||
#endif
|
|
||||||
taosIgnSignal(SIGABRT);
|
|
||||||
taosIgnSignal(SIGFPE);
|
|
||||||
taosIgnSignal(SIGSEGV);
|
|
||||||
|
|
||||||
char *pMsg = NULL;
|
char *pMsg = NULL;
|
||||||
const char *flags = "UTL FATAL ";
|
const char *flags = "UTL FATAL ";
|
||||||
ELogLevel level = DEBUG_FATAL;
|
ELogLevel level = DEBUG_FATAL;
|
||||||
|
|
|
@ -519,7 +519,7 @@ SArray *vmGetMsgHandles() {
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_COMMIT_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_COMMIT_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_ADD_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_ADD_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DEL_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DEL_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||||
|
|
|
@ -23,13 +23,12 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MQ_CONSUMER_STATUS__MODIFY = 1,
|
MQ_CONSUMER_STATUS_REBALANCE = 1,
|
||||||
// MQ_CONSUMER_STATUS__MODIFY_IN_REB, // this value is not used anymore
|
// MQ_CONSUMER_STATUS__MODIFY_IN_REB, // this value is not used anymore
|
||||||
MQ_CONSUMER_STATUS__READY,
|
MQ_CONSUMER_STATUS__READY,
|
||||||
MQ_CONSUMER_STATUS__LOST,
|
MQ_CONSUMER_STATUS__LOST,
|
||||||
// MQ_CONSUMER_STATUS__LOST_IN_REB, // this value is not used anymore
|
// MQ_CONSUMER_STATUS__LOST_IN_REB, // this value is not used anymore
|
||||||
MQ_CONSUMER_STATUS__LOST_REBD,
|
MQ_CONSUMER_STATUS__LOST_REBD,
|
||||||
MQ_CONSUMER_STATUS__REMOVED,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t mndInitConsumer(SMnode *pMnode);
|
int32_t mndInitConsumer(SMnode *pMnode);
|
||||||
|
|
|
@ -142,7 +142,7 @@ typedef enum {
|
||||||
CONSUMER_UPDATE__REMOVE,
|
CONSUMER_UPDATE__REMOVE,
|
||||||
CONSUMER_UPDATE__LOST,
|
CONSUMER_UPDATE__LOST,
|
||||||
CONSUMER_UPDATE__RECOVER,
|
CONSUMER_UPDATE__RECOVER,
|
||||||
CONSUMER_UPDATE__MODIFY, // subscribe req need change consume topic
|
CONSUMER_UPDATE__REBALANCE, // subscribe req need change consume topic
|
||||||
} ECsmUpdateType;
|
} ECsmUpdateType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -50,6 +50,8 @@ void *mndBuildCreateVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *p
|
||||||
void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
void *mndBuildDropVnodeReq(SMnode *, SDnodeObj *pDnode, SDbObj *pDb, SVgObj *pVgroup, int32_t *pContLen);
|
||||||
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid);
|
bool mndVgroupInDb(SVgObj *pVgroup, int64_t dbUid);
|
||||||
|
|
||||||
|
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -192,15 +192,18 @@ FAIL:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo check the clear process
|
||||||
static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
|
static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
|
||||||
SMnode *pMnode = pMsg->info.node;
|
SMnode *pMnode = pMsg->info.node;
|
||||||
SMqConsumerClearMsg *pClearMsg = pMsg->pCont;
|
SMqConsumerClearMsg *pClearMsg = pMsg->pCont;
|
||||||
SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pClearMsg->consumerId);
|
|
||||||
|
SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pClearMsg->consumerId);
|
||||||
if (pConsumer == NULL) {
|
if (pConsumer == NULL) {
|
||||||
|
mError("consumer:0x%"PRIx64" failed to be found to clear it", pClearMsg->consumerId);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInfo("receive consumer clear msg, consumer id %" PRId64 ", status %s", pClearMsg->consumerId,
|
mInfo("consumer:0x%" PRIx64 " needs to be cleared, status %s", pClearMsg->consumerId,
|
||||||
mndConsumerStatusName(pConsumer->status));
|
mndConsumerStatusName(pConsumer->status));
|
||||||
|
|
||||||
if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) {
|
if (pConsumer->status != MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||||
|
@ -215,6 +218,8 @@ static int32_t mndProcessConsumerClearMsg(SRpcMsg *pMsg) {
|
||||||
|
|
||||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "clear-csm");
|
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pMsg, "clear-csm");
|
||||||
if (pTrans == NULL) goto FAIL;
|
if (pTrans == NULL) goto FAIL;
|
||||||
|
|
||||||
|
// this is the drop action, not the update action
|
||||||
if (mndSetConsumerDropLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
|
if (mndSetConsumerDropLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
|
||||||
|
|
||||||
|
@ -299,28 +304,36 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
||||||
if (status == MQ_CONSUMER_STATUS__READY) {
|
if (status == MQ_CONSUMER_STATUS__READY) {
|
||||||
if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
|
if (hbStatus > MND_CONSUMER_LOST_HB_CNT) {
|
||||||
SMqConsumerLostMsg *pLostMsg = rpcMallocCont(sizeof(SMqConsumerLostMsg));
|
SMqConsumerLostMsg *pLostMsg = rpcMallocCont(sizeof(SMqConsumerLostMsg));
|
||||||
|
if (pLostMsg == NULL) {
|
||||||
|
mError("consumer:0x%"PRIx64" failed to transfer consumer status to lost due to out of memory. alloc size:%d",
|
||||||
|
pConsumer->consumerId, (int32_t)sizeof(SMqConsumerLostMsg));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
pLostMsg->consumerId = pConsumer->consumerId;
|
pLostMsg->consumerId = pConsumer->consumerId;
|
||||||
SRpcMsg rpcMsg = {
|
SRpcMsg rpcMsg = {
|
||||||
.msgType = TDMT_MND_TMQ_CONSUMER_LOST,
|
.msgType = TDMT_MND_TMQ_CONSUMER_LOST, .pCont = pLostMsg, .contLen = sizeof(SMqConsumerLostMsg)};
|
||||||
.pCont = pLostMsg,
|
|
||||||
.contLen = sizeof(SMqConsumerLostMsg),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
mDebug("consumer:0x%"PRIx64" hb not received beyond threshold %d, set to lost", pConsumer->consumerId,
|
||||||
|
MND_CONSUMER_LOST_HB_CNT);
|
||||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
||||||
}
|
}
|
||||||
} else if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
} else if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||||
// if the client is lost longer than one day, clear it. Otherwise, do nothing about the lost consumers.
|
// if the client is lost longer than one day, clear it. Otherwise, do nothing about the lost consumers.
|
||||||
if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) {
|
if (hbStatus > MND_CONSUMER_LOST_CLEAR_THRESHOLD) {
|
||||||
SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg));
|
SMqConsumerClearMsg *pClearMsg = rpcMallocCont(sizeof(SMqConsumerClearMsg));
|
||||||
|
if (pClearMsg == NULL) {
|
||||||
|
mError("consumer:0x%"PRIx64" failed to clear consumer due to out of memory. alloc size:%d",
|
||||||
|
pConsumer->consumerId, (int32_t)sizeof(SMqConsumerClearMsg));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
pClearMsg->consumerId = pConsumer->consumerId;
|
pClearMsg->consumerId = pConsumer->consumerId;
|
||||||
SRpcMsg rpcMsg = {
|
SRpcMsg rpcMsg = {
|
||||||
.msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR,
|
.msgType = TDMT_MND_TMQ_LOST_CONSUMER_CLEAR, .pCont = pClearMsg, .contLen = sizeof(SMqConsumerClearMsg)};
|
||||||
.pCont = pClearMsg,
|
|
||||||
.contLen = sizeof(SMqConsumerClearMsg),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
mDebug("consumer:0x%" PRIx64 " lost beyond threshold %d, clear it", pConsumer->consumerId,
|
||||||
|
MND_CONSUMER_LOST_CLEAR_THRESHOLD);
|
||||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &rpcMsg);
|
||||||
}
|
}
|
||||||
} else if (status == MQ_CONSUMER_STATUS__LOST) {
|
} else if (status == MQ_CONSUMER_STATUS__LOST) {
|
||||||
|
@ -334,7 +347,7 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
|
||||||
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
taosArrayPush(pRebSub->removedConsumers, &pConsumer->consumerId);
|
||||||
}
|
}
|
||||||
taosRUnLockLatch(&pConsumer->lock);
|
taosRUnLockLatch(&pConsumer->lock);
|
||||||
} else {
|
} else { // MQ_CONSUMER_STATUS_REBALANCE
|
||||||
taosRLockLatch(&pConsumer->lock);
|
taosRLockLatch(&pConsumer->lock);
|
||||||
|
|
||||||
int32_t newTopicNum = taosArrayGetSize(pConsumer->rebNewTopics);
|
int32_t newTopicNum = taosArrayGetSize(pConsumer->rebNewTopics);
|
||||||
|
@ -449,7 +462,6 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
||||||
// 1. check consumer status
|
// 1. check consumer status
|
||||||
int32_t status = atomic_load_32(&pConsumer->status);
|
int32_t status = atomic_load_32(&pConsumer->status);
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||||
mInfo("try to recover consumer:0x%" PRIx64, consumerId);
|
mInfo("try to recover consumer:0x%" PRIx64, consumerId);
|
||||||
SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
|
SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
|
||||||
|
@ -463,7 +475,6 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
||||||
|
|
||||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, &pRpcMsg);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (status != MQ_CONSUMER_STATUS__READY) {
|
if (status != MQ_CONSUMER_STATUS__READY) {
|
||||||
mInfo("consumer:0x%" PRIx64 " not ready, status: %s", consumerId, mndConsumerStatusName(status));
|
mInfo("consumer:0x%" PRIx64 " not ready, status: %s", consumerId, mndConsumerStatusName(status));
|
||||||
|
@ -660,7 +671,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
||||||
tstrncpy(pConsumerNew->clientId, subscribe.clientId, tListLen(pConsumerNew->clientId));
|
tstrncpy(pConsumerNew->clientId, subscribe.clientId, tListLen(pConsumerNew->clientId));
|
||||||
|
|
||||||
// set the update type
|
// set the update type
|
||||||
pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
|
pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
|
||||||
taosArrayDestroy(pConsumerNew->assignedTopics);
|
taosArrayDestroy(pConsumerNew->assignedTopics);
|
||||||
pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
|
pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
|
||||||
|
|
||||||
|
@ -673,7 +684,6 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto _over;
|
if (mndTransPrepare(pMnode, pTrans) != 0) goto _over;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*taosRLockLatch(&pExistedConsumer->lock);*/
|
|
||||||
int32_t status = atomic_load_32(&pExistedConsumer->status);
|
int32_t status = atomic_load_32(&pExistedConsumer->status);
|
||||||
|
|
||||||
mInfo("receive subscribe request from existed consumer:0x%" PRIx64
|
mInfo("receive subscribe request from existed consumer:0x%" PRIx64
|
||||||
|
@ -691,7 +701,7 @@ int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the update type
|
// set the update type
|
||||||
pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
|
pConsumerNew->updateType = CONSUMER_UPDATE__REBALANCE;
|
||||||
taosArrayDestroy(pConsumerNew->assignedTopics);
|
taosArrayDestroy(pConsumerNew->assignedTopics);
|
||||||
pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
|
pConsumerNew->assignedTopics = taosArrayDup(pTopicList, topicNameDup);
|
||||||
|
|
||||||
|
@ -870,9 +880,10 @@ static void updateConsumerStatus(SMqConsumerObj *pConsumer) {
|
||||||
int32_t status = pConsumer->status;
|
int32_t status = pConsumer->status;
|
||||||
|
|
||||||
if (taosArrayGetSize(pConsumer->rebNewTopics) == 0 && taosArrayGetSize(pConsumer->rebRemovedTopics) == 0) {
|
if (taosArrayGetSize(pConsumer->rebNewTopics) == 0 && taosArrayGetSize(pConsumer->rebRemovedTopics) == 0) {
|
||||||
if (status == MQ_CONSUMER_STATUS__MODIFY) {
|
if (status == MQ_CONSUMER_STATUS_REBALANCE) {
|
||||||
pConsumer->status = MQ_CONSUMER_STATUS__READY;
|
pConsumer->status = MQ_CONSUMER_STATUS__READY;
|
||||||
} else if (status == MQ_CONSUMER_STATUS__LOST) {
|
} else if (status == MQ_CONSUMER_STATUS__LOST) {
|
||||||
|
ASSERT(taosArrayGetSize(pConsumer->currentTopics) == 0);
|
||||||
pConsumer->status = MQ_CONSUMER_STATUS__LOST_REBD;
|
pConsumer->status = MQ_CONSUMER_STATUS__LOST_REBD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,7 +892,7 @@ static void updateConsumerStatus(SMqConsumerObj *pConsumer) {
|
||||||
// remove from new topic
|
// remove from new topic
|
||||||
static void removeFromNewTopicList(SMqConsumerObj *pConsumer, const char *pTopic) {
|
static void removeFromNewTopicList(SMqConsumerObj *pConsumer, const char *pTopic) {
|
||||||
int32_t size = taosArrayGetSize(pConsumer->rebNewTopics);
|
int32_t size = taosArrayGetSize(pConsumer->rebNewTopics);
|
||||||
for (int32_t i = 0; i < taosArrayGetSize(pConsumer->rebNewTopics); i++) {
|
for (int32_t i = 0; i < size; i++) {
|
||||||
char *p = taosArrayGetP(pConsumer->rebNewTopics, i);
|
char *p = taosArrayGetP(pConsumer->rebNewTopics, i);
|
||||||
if (strcmp(pTopic, p) == 0) {
|
if (strcmp(pTopic, p) == 0) {
|
||||||
taosArrayRemove(pConsumer->rebNewTopics, i);
|
taosArrayRemove(pConsumer->rebNewTopics, i);
|
||||||
|
@ -902,32 +913,57 @@ static void removeFromRemoveTopicList(SMqConsumerObj *pConsumer, const char *pTo
|
||||||
if (strcmp(pTopic, p) == 0) {
|
if (strcmp(pTopic, p) == 0) {
|
||||||
taosArrayRemove(pConsumer->rebRemovedTopics, i);
|
taosArrayRemove(pConsumer->rebRemovedTopics, i);
|
||||||
taosMemoryFree(p);
|
taosMemoryFree(p);
|
||||||
|
|
||||||
|
mDebug("consumer:0x%" PRIx64 " remove topic:%s in the removed topic list, remain removedTopics:%d",
|
||||||
|
pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->rebRemovedTopics));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void removeFromCurrentTopicList(SMqConsumerObj *pConsumer, const char *pTopic) {
|
||||||
|
int32_t sz = taosArrayGetSize(pConsumer->currentTopics);
|
||||||
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
|
char *topic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||||
|
if (strcmp(pTopic, topic) == 0) {
|
||||||
|
taosArrayRemove(pConsumer->currentTopics, i);
|
||||||
|
taosMemoryFree(topic);
|
||||||
|
|
||||||
|
mDebug("consumer:0x%" PRIx64 " remove topic:%s in the current topic list, remain currentTopics:%d",
|
||||||
|
pConsumer->consumerId, pTopic, (int)taosArrayGetSize(pConsumer->currentTopics));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool existInCurrentTopicList(const SMqConsumerObj* pConsumer, const char* pTopic) {
|
||||||
|
bool existing = false;
|
||||||
|
int32_t size = taosArrayGetSize(pConsumer->currentTopics);
|
||||||
|
for (int32_t i = 0; i < size; i++) {
|
||||||
|
char *topic = taosArrayGetP(pConsumer->currentTopics, i);
|
||||||
|
|
||||||
|
if (strcmp(topic, pTopic) == 0) {
|
||||||
|
existing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) {
|
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer, SMqConsumerObj *pNewConsumer) {
|
||||||
mDebug("consumer:0x%" PRIx64 " perform update action, update type:%d, subscribe-time:%" PRId64 ", uptime:%" PRId64,
|
mDebug("consumer:0x%" PRIx64 " perform update action, update type:%d, subscribe-time:%" PRId64 ", uptime:%" PRId64,
|
||||||
pOldConsumer->consumerId, pNewConsumer->updateType, pOldConsumer->subscribeTime, pOldConsumer->upTime);
|
pOldConsumer->consumerId, pNewConsumer->updateType, pOldConsumer->subscribeTime, pOldConsumer->upTime);
|
||||||
|
|
||||||
taosWLockLatch(&pOldConsumer->lock);
|
taosWLockLatch(&pOldConsumer->lock);
|
||||||
|
|
||||||
if (pNewConsumer->updateType == CONSUMER_UPDATE__MODIFY) {
|
if (pNewConsumer->updateType == CONSUMER_UPDATE__REBALANCE) {
|
||||||
SArray *tmp = pOldConsumer->rebNewTopics;
|
TSWAP(pOldConsumer->rebNewTopics, pNewConsumer->rebNewTopics);
|
||||||
pOldConsumer->rebNewTopics = pNewConsumer->rebNewTopics;
|
TSWAP(pOldConsumer->rebRemovedTopics, pNewConsumer->rebRemovedTopics);
|
||||||
pNewConsumer->rebNewTopics = tmp;
|
TSWAP(pOldConsumer->assignedTopics, pNewConsumer->assignedTopics);
|
||||||
|
|
||||||
tmp = pOldConsumer->rebRemovedTopics;
|
|
||||||
pOldConsumer->rebRemovedTopics = pNewConsumer->rebRemovedTopics;
|
|
||||||
pNewConsumer->rebRemovedTopics = tmp;
|
|
||||||
|
|
||||||
tmp = pOldConsumer->assignedTopics;
|
|
||||||
pOldConsumer->assignedTopics = pNewConsumer->assignedTopics;
|
|
||||||
pNewConsumer->assignedTopics = tmp;
|
|
||||||
|
|
||||||
pOldConsumer->subscribeTime = pNewConsumer->upTime;
|
pOldConsumer->subscribeTime = pNewConsumer->upTime;
|
||||||
pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
|
pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
|
||||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__LOST) {
|
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__LOST) {
|
||||||
int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
|
int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
|
@ -937,10 +973,10 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
|
|
||||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||||
|
|
||||||
int32_t status = pOldConsumer->status;
|
int32_t prevStatus = pOldConsumer->status;
|
||||||
pOldConsumer->status = MQ_CONSUMER_STATUS__LOST;
|
pOldConsumer->status = MQ_CONSUMER_STATUS__LOST;
|
||||||
mDebug("consumer:0x%" PRIx64 " state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d",
|
mDebug("consumer:0x%" PRIx64 " state %s -> %s, reb-time:%" PRId64 ", reb-removed-topics:%d",
|
||||||
pOldConsumer->consumerId, mndConsumerStatusName(status), mndConsumerStatusName(pOldConsumer->status),
|
pOldConsumer->consumerId, mndConsumerStatusName(prevStatus), mndConsumerStatusName(pOldConsumer->status),
|
||||||
pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics));
|
pOldConsumer->rebalanceTime, (int)taosArrayGetSize(pOldConsumer->rebRemovedTopics));
|
||||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__RECOVER) {
|
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__RECOVER) {
|
||||||
int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics);
|
int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics);
|
||||||
|
@ -950,8 +986,7 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
}
|
}
|
||||||
|
|
||||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||||
|
pOldConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
|
||||||
pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
|
|
||||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__TOUCH) {
|
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__TOUCH) {
|
||||||
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
||||||
|
|
||||||
|
@ -960,24 +995,16 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__ADD) {
|
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__ADD) {
|
||||||
char *pNewTopic = taosStrdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0));
|
char *pNewTopic = taosStrdup(taosArrayGetP(pNewConsumer->rebNewTopics, 0));
|
||||||
|
|
||||||
// not exist in current topic
|
// check if exist in current topic
|
||||||
bool existing = false;
|
|
||||||
int32_t numOfExistedTopics = taosArrayGetSize(pOldConsumer->currentTopics);
|
|
||||||
for (int32_t i = 0; i < numOfExistedTopics; i++) {
|
|
||||||
char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
|
|
||||||
if (strcmp(topic, pNewTopic) == 0) {
|
|
||||||
existing = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeFromNewTopicList(pOldConsumer, pNewTopic);
|
removeFromNewTopicList(pOldConsumer, pNewTopic);
|
||||||
|
|
||||||
// add to current topic
|
// add to current topic
|
||||||
if (!existing) {
|
bool existing = existInCurrentTopicList(pOldConsumer, pNewTopic);
|
||||||
|
if (existing) {
|
||||||
|
taosMemoryFree(pNewTopic);
|
||||||
|
} else { // added into current topic list
|
||||||
taosArrayPush(pOldConsumer->currentTopics, &pNewTopic);
|
taosArrayPush(pOldConsumer->currentTopics, &pNewTopic);
|
||||||
taosArraySort(pOldConsumer->currentTopics, taosArrayCompareString);
|
taosArraySort(pOldConsumer->currentTopics, taosArrayCompareString);
|
||||||
} else {
|
|
||||||
taosMemoryFree(pNewTopic);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set status
|
// set status
|
||||||
|
@ -1002,16 +1029,7 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
||||||
removeFromRemoveTopicList(pOldConsumer, removedTopic);
|
removeFromRemoveTopicList(pOldConsumer, removedTopic);
|
||||||
|
|
||||||
// remove from current topic
|
// remove from current topic
|
||||||
int32_t i = 0;
|
removeFromCurrentTopicList(pOldConsumer, removedTopic);
|
||||||
int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
|
|
||||||
for (i = 0; i < sz; i++) {
|
|
||||||
char *topic = taosArrayGetP(pOldConsumer->currentTopics, i);
|
|
||||||
if (strcmp(removedTopic, topic) == 0) {
|
|
||||||
taosArrayRemove(pOldConsumer->currentTopics, i);
|
|
||||||
taosMemoryFree(topic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set status
|
// set status
|
||||||
int32_t status = pOldConsumer->status;
|
int32_t status = pOldConsumer->status;
|
||||||
|
@ -1160,7 +1178,7 @@ static const char *mndConsumerStatusName(int status) {
|
||||||
case MQ_CONSUMER_STATUS__LOST:
|
case MQ_CONSUMER_STATUS__LOST:
|
||||||
case MQ_CONSUMER_STATUS__LOST_REBD:
|
case MQ_CONSUMER_STATUS__LOST_REBD:
|
||||||
return "lost";
|
return "lost";
|
||||||
case MQ_CONSUMER_STATUS__MODIFY:
|
case MQ_CONSUMER_STATUS_REBALANCE:
|
||||||
return "rebalancing";
|
return "rebalancing";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
|
@ -225,7 +225,7 @@ SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_L
|
||||||
memcpy(pConsumer->cgroup, cgroup, TSDB_CGROUP_LEN);
|
memcpy(pConsumer->cgroup, cgroup, TSDB_CGROUP_LEN);
|
||||||
|
|
||||||
pConsumer->epoch = 0;
|
pConsumer->epoch = 0;
|
||||||
pConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
|
pConsumer->status = MQ_CONSUMER_STATUS_REBALANCE;
|
||||||
pConsumer->hbStatus = 0;
|
pConsumer->hbStatus = 0;
|
||||||
|
|
||||||
taosInitRWLatch(&pConsumer->lock);
|
taosInitRWLatch(&pConsumer->lock);
|
||||||
|
|
|
@ -256,10 +256,13 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
||||||
snprintf(db, TSDB_DB_FNAME_LEN, "%d%s%s", pUser->acctId, TS_PATH_DELIMITER, connReq.db);
|
snprintf(db, TSDB_DB_FNAME_LEN, "%d%s%s", pUser->acctId, TS_PATH_DELIMITER, connReq.db);
|
||||||
pDb = mndAcquireDb(pMnode, db);
|
pDb = mndAcquireDb(pMnode, db);
|
||||||
if (pDb == NULL) {
|
if (pDb == NULL) {
|
||||||
terrno = TSDB_CODE_MND_INVALID_DB;
|
if (0 != strcmp(connReq.db, TSDB_INFORMATION_SCHEMA_DB) &&
|
||||||
mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db,
|
(0 != strcmp(connReq.db, TSDB_PERFORMANCE_SCHEMA_DB))) {
|
||||||
terrstr());
|
terrno = TSDB_CODE_MND_INVALID_DB;
|
||||||
goto _OVER;
|
mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db,
|
||||||
|
terrstr());
|
||||||
|
goto _OVER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_READ_OR_WRITE_DB, pDb) != 0) {
|
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_READ_OR_WRITE_DB, pDb) != 0) {
|
||||||
|
|
|
@ -797,6 +797,11 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){
|
||||||
|
terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
|
for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
|
||||||
SField *pField = taosArrayGet(pCreate->pColumns, i);
|
SField *pField = taosArrayGet(pCreate->pColumns, i);
|
||||||
SSchema *pSchema = &pDst->pColumns[i];
|
SSchema *pSchema = &pDst->pColumns[i];
|
||||||
|
@ -927,6 +932,11 @@ static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pDst->nextColId < 0 || pDst->nextColId >= 0x7fff - pDst->numOfColumns - pDst->numOfTags){
|
||||||
|
terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
|
for (int32_t i = 0; i < pDst->numOfColumns; ++i) {
|
||||||
SField *pField = taosArrayGet(createReq->pColumns, i);
|
SField *pField = taosArrayGet(createReq->pColumns, i);
|
||||||
SSchema *pSchema = &pDst->pColumns[i];
|
SSchema *pSchema = &pDst->pColumns[i];
|
||||||
|
@ -1153,6 +1163,11 @@ static int32_t mndAddSuperTableTag(const SStbObj *pOld, SStbObj *pNew, SArray *p
|
||||||
if (mndAllocStbSchemas(pOld, pNew) != 0) {
|
if (mndAllocStbSchemas(pOld, pNew) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ntags){
|
||||||
|
terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < ntags; i++) {
|
for (int32_t i = 0; i < ntags; i++) {
|
||||||
SField *pField = taosArrayGet(pFields, i);
|
SField *pField = taosArrayGet(pFields, i);
|
||||||
|
@ -1461,6 +1476,11 @@ static int32_t mndAddSuperTableColumn(const SStbObj *pOld, SStbObj *pNew, SArray
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(pNew->nextColId < 0 || pNew->nextColId >= 0x7fff - ncols){
|
||||||
|
terrno = TSDB_CODE_MND_FIELD_VALUE_OVERFLOW;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < ncols; i++) {
|
for (int32_t i = 0; i < ncols; i++) {
|
||||||
SField *pField = taosArrayGet(pFields, i);
|
SField *pField = taosArrayGet(pFields, i);
|
||||||
if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
|
if (mndFindSuperTableColumnIndex(pOld, pField->name) >= 0) {
|
||||||
|
@ -2524,6 +2544,9 @@ int32_t mndValidateStbInfo(SMnode *pMnode, SSTableVersion *pStbVersions, int32_t
|
||||||
if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
|
if (mndBuildStbSchema(pMnode, pStbVersion->dbFName, pStbVersion->stbName, &metaRsp, &smaVer) != 0) {
|
||||||
metaRsp.numOfColumns = -1;
|
metaRsp.numOfColumns = -1;
|
||||||
metaRsp.suid = pStbVersion->suid;
|
metaRsp.suid = pStbVersion->suid;
|
||||||
|
tstrncpy(metaRsp.dbFName, pStbVersion->dbFName, sizeof(metaRsp.dbFName));
|
||||||
|
tstrncpy(metaRsp.tbName, pStbVersion->stbName, sizeof(metaRsp.tbName));
|
||||||
|
tstrncpy(metaRsp.stbName, pStbVersion->stbName, sizeof(metaRsp.stbName));
|
||||||
taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
|
taosArrayPush(hbRsp.pMetaRsp, &metaRsp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,10 +133,10 @@ static int32_t mndBuildSubChangeReq(void **pBuf, int32_t *pLen, const SMqSubscri
|
||||||
|
|
||||||
static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SMqSubscribeObj *pSub,
|
static int32_t mndPersistSubChangeVgReq(SMnode *pMnode, STrans *pTrans, const SMqSubscribeObj *pSub,
|
||||||
const SMqRebOutputVg *pRebVg) {
|
const SMqRebOutputVg *pRebVg) {
|
||||||
if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
|
// if (pRebVg->oldConsumerId == pRebVg->newConsumerId) {
|
||||||
terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
|
// terrno = TSDB_CODE_MND_INVALID_SUB_OPTION;
|
||||||
return -1;
|
// return -1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
void *buf;
|
void *buf;
|
||||||
int32_t tlen;
|
int32_t tlen;
|
||||||
|
@ -197,7 +197,7 @@ static SMqRebInfo *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||||
return pRebSub;
|
return pRebSub;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doRemoveExistedConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, const SMqRebInputObj *pInput) {
|
static void doRemoveLostConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, const SMqRebInputObj *pInput) {
|
||||||
int32_t numOfRemoved = taosArrayGetSize(pInput->pRebInfo->removedConsumers);
|
int32_t numOfRemoved = taosArrayGetSize(pInput->pRebInfo->removedConsumers);
|
||||||
const char *pSubKey = pOutput->pSub->key;
|
const char *pSubKey = pOutput->pSub->key;
|
||||||
|
|
||||||
|
@ -213,13 +213,9 @@ static void doRemoveExistedConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash,
|
||||||
|
|
||||||
int32_t consumerVgNum = taosArrayGetSize(pConsumerEp->vgs);
|
int32_t consumerVgNum = taosArrayGetSize(pConsumerEp->vgs);
|
||||||
for (int32_t j = 0; j < consumerVgNum; j++) {
|
for (int32_t j = 0; j < consumerVgNum; j++) {
|
||||||
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
|
SMqVgEp *pVgEp = taosArrayGetP(pConsumerEp->vgs, j);
|
||||||
SMqRebOutputVg outputVg = {
|
|
||||||
.oldConsumerId = consumerId,
|
|
||||||
.newConsumerId = -1,
|
|
||||||
.pVgEp = pVgEp,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
SMqRebOutputVg outputVg = {.oldConsumerId = consumerId, .newConsumerId = -1, .pVgEp = pVgEp};
|
||||||
taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
|
taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
|
||||||
mInfo("sub:%s mq re-balance remove vgId:%d from consumer:%" PRIx64, pSubKey, pVgEp->vgId, consumerId);
|
mInfo("sub:%s mq re-balance remove vgId:%d from consumer:%" PRIx64, pSubKey, pVgEp->vgId, consumerId);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +269,18 @@ static void addUnassignedVgroups(SMqRebOutputObj *pOutput, SHashObj *pHash) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void putNoTransferToOutput(SMqRebOutputObj *pOutput, SMqConsumerEp *pConsumerEp){
|
||||||
|
for(int i = 0; i < taosArrayGetSize(pConsumerEp->vgs); i++){
|
||||||
|
SMqVgEp *pVgEp = (SMqVgEp *)taosArrayGetP(pConsumerEp->vgs, i);
|
||||||
|
SMqRebOutputVg outputVg = {
|
||||||
|
.oldConsumerId = pConsumerEp->consumerId,
|
||||||
|
.newConsumerId = pConsumerEp->consumerId,
|
||||||
|
.pVgEp = pVgEp,
|
||||||
|
};
|
||||||
|
taosArrayPush(pOutput->rebVgs, &outputVg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, int32_t minVgCnt,
|
static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHash, int32_t minVgCnt,
|
||||||
int32_t imbConsumerNum) {
|
int32_t imbConsumerNum) {
|
||||||
const char *pSubKey = pOutput->pSub->key;
|
const char *pSubKey = pOutput->pSub->key;
|
||||||
|
@ -294,24 +302,19 @@ static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHas
|
||||||
taosArrayPush(pOutput->modifyConsumers, &pConsumerEp->consumerId);
|
taosArrayPush(pOutput->modifyConsumers, &pConsumerEp->consumerId);
|
||||||
if (consumerVgNum > minVgCnt) {
|
if (consumerVgNum > minVgCnt) {
|
||||||
if (imbCnt < imbConsumerNum) {
|
if (imbCnt < imbConsumerNum) {
|
||||||
if (consumerVgNum == minVgCnt + 1) {
|
// pop until equal minVg + 1
|
||||||
imbCnt++;
|
while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt + 1) {
|
||||||
continue;
|
SMqVgEp *pVgEp = *(SMqVgEp **)taosArrayPop(pConsumerEp->vgs);
|
||||||
} else {
|
SMqRebOutputVg outputVg = {
|
||||||
// pop until equal minVg + 1
|
.oldConsumerId = pConsumerEp->consumerId,
|
||||||
while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt + 1) {
|
.newConsumerId = -1,
|
||||||
SMqVgEp *pVgEp = *(SMqVgEp **)taosArrayPop(pConsumerEp->vgs);
|
.pVgEp = pVgEp,
|
||||||
SMqRebOutputVg outputVg = {
|
};
|
||||||
.oldConsumerId = pConsumerEp->consumerId,
|
taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
|
||||||
.newConsumerId = -1,
|
mInfo("sub:%s mq rebalance remove vgId:%d from consumer:0x%" PRIx64 ",(first scan)", pSubKey, pVgEp->vgId,
|
||||||
.pVgEp = pVgEp,
|
pConsumerEp->consumerId);
|
||||||
};
|
|
||||||
taosHashPut(pHash, &pVgEp->vgId, sizeof(int32_t), &outputVg, sizeof(SMqRebOutputVg));
|
|
||||||
mInfo("sub:%s mq rebalance remove vgId:%d from consumer:0x%" PRIx64 ",(first scan)", pSubKey, pVgEp->vgId,
|
|
||||||
pConsumerEp->consumerId);
|
|
||||||
}
|
|
||||||
imbCnt++;
|
|
||||||
}
|
}
|
||||||
|
imbCnt++;
|
||||||
} else {
|
} else {
|
||||||
// all the remain consumers should only have the number of vgroups, which is equalled to the value of minVg
|
// all the remain consumers should only have the number of vgroups, which is equalled to the value of minVg
|
||||||
while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt) {
|
while (taosArrayGetSize(pConsumerEp->vgs) > minVgCnt) {
|
||||||
|
@ -327,6 +330,7 @@ static void transferVgroupsForConsumers(SMqRebOutputObj *pOutput, SHashObj *pHas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
putNoTransferToOutput(pOutput, pConsumerEp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +347,7 @@ static int32_t mndDoRebalance(SMnode *pMnode, const SMqRebInputObj *pInput, SMqR
|
||||||
SHashObj *pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
SHashObj *pHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||||
|
|
||||||
// 2. check and get actual removed consumers, put their vg into pHash
|
// 2. check and get actual removed consumers, put their vg into pHash
|
||||||
doRemoveExistedConsumers(pOutput, pHash, pInput);
|
doRemoveLostConsumers(pOutput, pHash, pInput);
|
||||||
|
|
||||||
// 3. if previously no consumer, there are vgs not assigned, put these vg into pHash
|
// 3. if previously no consumer, there are vgs not assigned, put these vg into pHash
|
||||||
addUnassignedVgroups(pOutput, pHash);
|
addUnassignedVgroups(pOutput, pHash);
|
||||||
|
@ -484,14 +488,16 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
for (int32_t i = 0; i < vgNum; i++) {
|
for (int32_t i = 0; i < vgNum; i++) {
|
||||||
SMqRebOutputVg *pRebVg = taosArrayGet(rebVgs, i);
|
SMqRebOutputVg *pRebVg = taosArrayGet(rebVgs, i);
|
||||||
if (mndPersistSubChangeVgReq(pMnode, pTrans, pOutput->pSub, pRebVg) < 0) {
|
if (mndPersistSubChangeVgReq(pMnode, pTrans, pOutput->pSub, pRebVg) < 0) {
|
||||||
goto REB_FAIL;
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. redo log: subscribe and vg assignment
|
// 2. redo log: subscribe and vg assignment
|
||||||
// subscribe
|
// subscribe
|
||||||
if (mndSetSubCommitLogs(pMnode, pTrans, pOutput->pSub) != 0) {
|
if (mndSetSubCommitLogs(pMnode, pTrans, pOutput->pSub) != 0) {
|
||||||
goto REB_FAIL;
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. commit log: consumer to update status and epoch
|
// 3. commit log: consumer to update status and epoch
|
||||||
|
@ -506,11 +512,15 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
goto REB_FAIL;
|
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.2 set new consumer
|
// 3.2 set new consumer
|
||||||
consumerNum = taosArrayGetSize(pOutput->newConsumers);
|
consumerNum = taosArrayGetSize(pOutput->newConsumers);
|
||||||
for (int32_t i = 0; i < consumerNum; i++) {
|
for (int32_t i = 0; i < consumerNum; i++) {
|
||||||
|
@ -527,8 +537,11 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
goto REB_FAIL;
|
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
}
|
}
|
||||||
|
@ -549,8 +562,11 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) {
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
goto REB_FAIL;
|
|
||||||
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDeleteSMqConsumerObj(pConsumerNew);
|
tDeleteSMqConsumerObj(pConsumerNew);
|
||||||
taosMemoryFree(pConsumerNew);
|
taosMemoryFree(pConsumerNew);
|
||||||
}
|
}
|
||||||
|
@ -563,15 +579,12 @@ static int32_t mndPersistRebResult(SMnode *pMnode, SRpcMsg *pMsg, const SMqRebOu
|
||||||
// 6. execution
|
// 6. execution
|
||||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||||
mError("failed to prepare trans rebalance since %s", terrstr());
|
mError("failed to prepare trans rebalance since %s", terrstr());
|
||||||
goto REB_FAIL;
|
mndTransDrop(pTrans);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mndTransDrop(pTrans);
|
mndTransDrop(pTrans);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
REB_FAIL:
|
|
||||||
mndTransDrop(pTrans);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||||
|
@ -584,16 +597,11 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||||
|
|
||||||
// here we only handle one topic rebalance requirement to ensure the atomic execution of this transaction.
|
// here we only handle one topic rebalance requirement to ensure the atomic execution of this transaction.
|
||||||
while (1) {
|
while (1) {
|
||||||
// if (rebalanceOnce) {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
pIter = taosHashIterate(pReq->rebSubHash, pIter);
|
pIter = taosHashIterate(pReq->rebSubHash, pIter);
|
||||||
if (pIter == NULL) {
|
if (pIter == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo handle the malloc failure
|
|
||||||
SMqRebInputObj rebInput = {0};
|
SMqRebInputObj rebInput = {0};
|
||||||
SMqRebOutputObj rebOutput = {0};
|
SMqRebOutputObj rebOutput = {0};
|
||||||
rebOutput.newConsumers = taosArrayInit(0, sizeof(int64_t));
|
rebOutput.newConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||||
|
@ -601,6 +609,20 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||||
rebOutput.modifyConsumers = taosArrayInit(0, sizeof(int64_t));
|
rebOutput.modifyConsumers = taosArrayInit(0, sizeof(int64_t));
|
||||||
rebOutput.rebVgs = taosArrayInit(0, sizeof(SMqRebOutputVg));
|
rebOutput.rebVgs = taosArrayInit(0, sizeof(SMqRebOutputVg));
|
||||||
|
|
||||||
|
if (rebOutput.newConsumers == NULL || rebOutput.removedConsumers == NULL || rebOutput.modifyConsumers == NULL ||
|
||||||
|
rebOutput.rebVgs == NULL) {
|
||||||
|
taosArrayDestroy(rebOutput.newConsumers);
|
||||||
|
taosArrayDestroy(rebOutput.removedConsumers);
|
||||||
|
taosArrayDestroy(rebOutput.modifyConsumers);
|
||||||
|
taosArrayDestroy(rebOutput.rebVgs);
|
||||||
|
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
mInfo("mq re-balance failed, due to out of memory");
|
||||||
|
taosHashCleanup(pReq->rebSubHash);
|
||||||
|
mndRebEnd();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
SMqRebInfo *pRebInfo = (SMqRebInfo *)pIter;
|
SMqRebInfo *pRebInfo = (SMqRebInfo *)pIter;
|
||||||
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebInfo->key);
|
SMqSubscribeObj *pSub = mndAcquireSubscribeByKey(pMnode, pRebInfo->key);
|
||||||
|
|
||||||
|
@ -640,6 +662,7 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||||
rebInput.oldConsumerNum = taosHashGetSize(pSub->consumerHash);
|
rebInput.oldConsumerNum = taosHashGetSize(pSub->consumerHash);
|
||||||
rebOutput.pSub = tCloneSubscribeObj(pSub);
|
rebOutput.pSub = tCloneSubscribeObj(pSub);
|
||||||
taosRUnLockLatch(&pSub->lock);
|
taosRUnLockLatch(&pSub->lock);
|
||||||
|
|
||||||
mInfo("sub topic:%s has %d consumers sub till now", pRebInfo->key, rebInput.oldConsumerNum);
|
mInfo("sub topic:%s has %d consumers sub till now", pRebInfo->key, rebInput.oldConsumerNum);
|
||||||
mndReleaseSubscribe(pMnode, pSub);
|
mndReleaseSubscribe(pMnode, pSub);
|
||||||
}
|
}
|
||||||
|
@ -661,9 +684,6 @@ static int32_t mndProcessRebalanceReq(SRpcMsg *pMsg) {
|
||||||
taosArrayDestroy(rebOutput.rebVgs);
|
taosArrayDestroy(rebOutput.rebVgs);
|
||||||
tDeleteSubscribeObj(rebOutput.pSub);
|
tDeleteSubscribeObj(rebOutput.pSub);
|
||||||
taosMemoryFree(rebOutput.pSub);
|
taosMemoryFree(rebOutput.pSub);
|
||||||
|
|
||||||
// taosSsleep(100);
|
|
||||||
// rebalanceOnce = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset flag
|
// reset flag
|
||||||
|
|
|
@ -236,7 +236,7 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
|
||||||
SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
|
SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER);
|
||||||
|
|
||||||
SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
|
SDB_SET_INT32(pRaw, dataPos, *useDb, _OVER)
|
||||||
useDb = taosHashIterate(pUser->writeTbs, useDb);
|
useDb = taosHashIterate(pUser->useDbs, useDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
|
SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
|
||||||
|
|
|
@ -2006,7 +2006,7 @@ static int32_t mndAddAdjustVnodeHashRangeAction(SMnode *pMnode, STrans *pTrans,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
|
int32_t mndSplitVgroup(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SVgObj *pVgroup) {
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
STrans *pTrans = NULL;
|
STrans *pTrans = NULL;
|
||||||
SSdbRaw *pRaw = NULL;
|
SSdbRaw *pRaw = NULL;
|
||||||
|
|
|
@ -153,11 +153,15 @@ int32_t sndProcessTaskDeployReq(SSnode *pSnode, char *msg, int32_t msgLen) {
|
||||||
ASSERT(pTask->taskLevel == TASK_LEVEL__AGG);
|
ASSERT(pTask->taskLevel == TASK_LEVEL__AGG);
|
||||||
|
|
||||||
// 2.save task
|
// 2.save task
|
||||||
|
taosWLockLatch(&pSnode->pMeta->lock);
|
||||||
code = streamMetaAddDeployedTask(pSnode->pMeta, -1, pTask);
|
code = streamMetaAddDeployedTask(pSnode->pMeta, -1, pTask);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
|
taosWUnLockLatch(&pSnode->pMeta->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosWUnLockLatch(&pSnode->pMeta->lock);
|
||||||
|
|
||||||
// 3.go through recover steps to fill history
|
// 3.go through recover steps to fill history
|
||||||
if (pTask->fillHistory) {
|
if (pTask->fillHistory) {
|
||||||
streamSetParamForRecover(pTask);
|
streamSetParamForRecover(pTask);
|
||||||
|
|
|
@ -231,7 +231,7 @@ typedef struct SSnapContext {
|
||||||
} SSnapContext;
|
} SSnapContext;
|
||||||
|
|
||||||
typedef struct STqReader {
|
typedef struct STqReader {
|
||||||
SPackedData msg2;
|
SPackedData msg;
|
||||||
SSubmitReq2 submit;
|
SSubmitReq2 submit;
|
||||||
int32_t nextBlk;
|
int32_t nextBlk;
|
||||||
int64_t lastBlkUid;
|
int64_t lastBlkUid;
|
||||||
|
@ -241,8 +241,9 @@ typedef struct STqReader {
|
||||||
SArray *pColIdList; // SArray<int16_t>
|
SArray *pColIdList; // SArray<int16_t>
|
||||||
int32_t cachedSchemaVer;
|
int32_t cachedSchemaVer;
|
||||||
int64_t cachedSchemaSuid;
|
int64_t cachedSchemaSuid;
|
||||||
|
int64_t cachedSchemaUid;
|
||||||
SSchemaWrapper *pSchemaWrapper;
|
SSchemaWrapper *pSchemaWrapper;
|
||||||
STSchema *pSchema;
|
SSDataBlock *pResBlock;
|
||||||
} STqReader;
|
} STqReader;
|
||||||
|
|
||||||
STqReader *tqReaderOpen(SVnode *pVnode);
|
STqReader *tqReaderOpen(SVnode *pVnode);
|
||||||
|
@ -254,13 +255,13 @@ int32_t tqReaderAddTbUidList(STqReader *pReader, const SArray *pTableUidList);
|
||||||
int32_t tqReaderRemoveTbUidList(STqReader *pReader, const SArray *tbUidList);
|
int32_t tqReaderRemoveTbUidList(STqReader *pReader, const SArray *tbUidList);
|
||||||
|
|
||||||
int32_t tqSeekVer(STqReader *pReader, int64_t ver, const char *id);
|
int32_t tqSeekVer(STqReader *pReader, int64_t ver, const char *id);
|
||||||
int32_t tqNextBlock(STqReader *pReader, SSDataBlock* pBlock);
|
int32_t tqNextBlockInWal(STqReader* pReader);
|
||||||
int32_t extractSubmitMsgFromWal(SWalReader *pReader, SPackedData *pPackedData);
|
|
||||||
|
|
||||||
int32_t tqReaderSetSubmitMsg(STqReader *pReader, void *msgStr, int32_t msgLen, int64_t ver);
|
|
||||||
bool tqNextBlockImpl(STqReader *pReader);
|
bool tqNextBlockImpl(STqReader *pReader);
|
||||||
|
|
||||||
|
int32_t extractSubmitMsgFromWal(SWalReader *pReader, SPackedData *pPackedData);
|
||||||
|
int32_t tqReaderSetSubmitMsg(STqReader *pReader, void *msgStr, int32_t msgLen, int64_t ver);
|
||||||
bool tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids);
|
bool tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids);
|
||||||
int32_t tqRetrieveDataBlock(SSDataBlock *pBlock, STqReader *pReader, SSubmitTbData **pSubmitTbDataRet);
|
int32_t tqRetrieveDataBlock(STqReader *pReader, SSubmitTbData **pSubmitTbDataRet);
|
||||||
int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet);
|
int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet);
|
||||||
|
|
||||||
int32_t vnodeEnqueueStreamMsg(SVnode *pVnode, SRpcMsg *pMsg);
|
int32_t vnodeEnqueueStreamMsg(SVnode *pVnode, SRpcMsg *pMsg);
|
||||||
|
|
|
@ -100,6 +100,8 @@ typedef struct {
|
||||||
SWalRef* pRef;
|
SWalRef* pRef;
|
||||||
STqPushHandle pushHandle; // push
|
STqPushHandle pushHandle; // push
|
||||||
STqExecHandle execHandle; // exec
|
STqExecHandle execHandle; // exec
|
||||||
|
SRpcMsg* msg;
|
||||||
|
int32_t noDataPollCnt;
|
||||||
} STqHandle;
|
} STqHandle;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -113,7 +115,7 @@ struct STQ {
|
||||||
char* path;
|
char* path;
|
||||||
int64_t walLogLastVer;
|
int64_t walLogLastVer;
|
||||||
SRWLatch lock;
|
SRWLatch lock;
|
||||||
SHashObj* pPushMgr; // consumerId -> STqPushEntry
|
SHashObj* pPushMgr; // subKey -> STqHandle
|
||||||
SHashObj* pHandle; // subKey -> STqHandle
|
SHashObj* pHandle; // subKey -> STqHandle
|
||||||
SHashObj* pCheckInfo; // topic -> SAlterCheckInfo
|
SHashObj* pCheckInfo; // topic -> SAlterCheckInfo
|
||||||
STqOffsetStore* pOffsetStore;
|
STqOffsetStore* pOffsetStore;
|
||||||
|
@ -146,7 +148,7 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea
|
||||||
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows);
|
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows);
|
||||||
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
|
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
|
||||||
int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type);
|
int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type);
|
||||||
int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry);
|
int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle);
|
||||||
|
|
||||||
// tqMeta
|
// tqMeta
|
||||||
int32_t tqMetaOpen(STQ* pTq);
|
int32_t tqMetaOpen(STQ* pTq);
|
||||||
|
|
|
@ -193,9 +193,8 @@ STQ* tqOpen(const char* path, SVnode* pVnode);
|
||||||
void tqNotifyClose(STQ*);
|
void tqNotifyClose(STQ*);
|
||||||
void tqClose(STQ*);
|
void tqClose(STQ*);
|
||||||
int tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
|
int tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
|
||||||
int tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest, SRpcMsg* pRpcMsg, SMqDataRsp* pDataRsp,
|
int tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg);
|
||||||
int32_t type);
|
int tqUnregisterPushHandle(STQ* pTq, void* pHandle);
|
||||||
int tqUnregisterPushHandle(STQ* pTq, const char* pKey, int32_t keyLen, uint64_t consumerId, bool rspConsumer);
|
|
||||||
int tqStartStreamTasks(STQ* pTq); // restore all stream tasks after vnode launching completed.
|
int tqStartStreamTasks(STQ* pTq); // restore all stream tasks after vnode launching completed.
|
||||||
|
|
||||||
int tqCommit(STQ*);
|
int tqCommit(STQ*);
|
||||||
|
@ -213,7 +212,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msg
|
||||||
int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||||
int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
int32_t tqProcessStreamTaskCheckRsp(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||||
int32_t tqProcessSubmitReq(STQ* pTq, SPackedData submit);
|
int32_t tqProcessSubmitReqForSubscribe(STQ* pTq);
|
||||||
int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver);
|
int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver);
|
||||||
int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg);
|
int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg);
|
||||||
int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec);
|
int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg, bool exec);
|
||||||
|
|
|
@ -639,7 +639,6 @@ tb_uid_t metaStbCursorNext(SMStbCursor *pStbCur) {
|
||||||
STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
|
STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) {
|
||||||
STSchema *pTSchema = NULL;
|
STSchema *pTSchema = NULL;
|
||||||
SSchemaWrapper *pSW = NULL;
|
SSchemaWrapper *pSW = NULL;
|
||||||
SSchema *pSchema = NULL;
|
|
||||||
|
|
||||||
pSW = metaGetTableSchema(pMeta, uid, sver, lock);
|
pSW = metaGetTableSchema(pMeta, uid, sver, lock);
|
||||||
if (!pSW) return NULL;
|
if (!pSW) return NULL;
|
||||||
|
|
|
@ -217,8 +217,8 @@ typedef struct STableInfoForChildTable {
|
||||||
static void destroySTableInfoForChildTable(void* data) {
|
static void destroySTableInfoForChildTable(void* data) {
|
||||||
STableInfoForChildTable* pData = (STableInfoForChildTable*)data;
|
STableInfoForChildTable* pData = (STableInfoForChildTable*)data;
|
||||||
taosMemoryFree(pData->tableName);
|
taosMemoryFree(pData->tableName);
|
||||||
tDeleteSSchemaWrapper(pData->schemaRow);
|
tDeleteSchemaWrapper(pData->schemaRow);
|
||||||
tDeleteSSchemaWrapper(pData->tagRow);
|
tDeleteSchemaWrapper(pData->tagRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MoveToSnapShotVersion(SSnapContext* ctx) {
|
static void MoveToSnapShotVersion(SSnapContext* ctx) {
|
||||||
|
|
|
@ -673,8 +673,8 @@ int metaDropIndexFromSTable(SMeta *pMeta, int64_t version, SDropIndexReq *pReq)
|
||||||
metaUpdateUidIdx(pMeta, &nStbEntry);
|
metaUpdateUidIdx(pMeta, &nStbEntry);
|
||||||
metaULock(pMeta);
|
metaULock(pMeta);
|
||||||
|
|
||||||
tDeleteSSchemaWrapper(tag);
|
tDeleteSchemaWrapper(tag);
|
||||||
tDeleteSSchemaWrapper(row);
|
tDeleteSchemaWrapper(row);
|
||||||
|
|
||||||
if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
|
if (oStbEntry.pBuf) taosMemoryFree(oStbEntry.pBuf);
|
||||||
tDecoderClear(&dc);
|
tDecoderClear(&dc);
|
||||||
|
|
|
@ -696,7 +696,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReq && tdProcessSubmitReq(sinkTsdb, output->info.version, pReq) < 0) {
|
if (pReq && tdProcessSubmitReq(sinkTsdb, output->info.version, pReq) < 0) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
smaError("vgId:%d, process submit req for rsma suid:%" PRIu64 ", uid:%" PRIu64 " level %" PRIi8
|
smaError("vgId:%d, process submit req for rsma suid:%" PRIu64 ", uid:%" PRIu64 " level %" PRIi8
|
||||||
" failed since %s",
|
" failed since %s",
|
||||||
|
@ -708,7 +708,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
|
||||||
SMA_VID(pSma), suid, output->info.id.groupId, pItem->level, output->info.version);
|
SMA_VID(pSma), suid, output->info.id.groupId, pItem->level, output->info.version);
|
||||||
|
|
||||||
if (pReq) {
|
if (pReq) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -303,7 +303,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode
|
// encode
|
||||||
tEncodeSize(tEncodeSSubmitReq2, pReq, len, code);
|
tEncodeSize(tEncodeSSubmitReq, pReq, len, code);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SEncoder encoder;
|
SEncoder encoder;
|
||||||
len += sizeof(SSubmitReq2Msg);
|
len += sizeof(SSubmitReq2Msg);
|
||||||
|
@ -316,7 +316,7 @@ int32_t smaBlockToSubmit(SVnode *pVnode, const SArray *pBlocks, const STSchema *
|
||||||
((SSubmitReq2Msg *)pBuf)->header.contLen = htonl(len);
|
((SSubmitReq2Msg *)pBuf)->header.contLen = htonl(len);
|
||||||
((SSubmitReq2Msg *)pBuf)->version = htobe64(1);
|
((SSubmitReq2Msg *)pBuf)->version = htobe64(1);
|
||||||
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
||||||
if (tEncodeSSubmitReq2(&encoder, pReq) < 0) {
|
if (tEncodeSSubmitReq(&encoder, pReq) < 0) {
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
TSDB_CHECK_CODE(code, lino, _exit);
|
TSDB_CHECK_CODE(code, lino, _exit);
|
||||||
|
@ -328,7 +328,7 @@ _exit:
|
||||||
taosArrayDestroy(tagArray);
|
taosArrayDestroy(tagArray);
|
||||||
taosArrayDestroy(pVals);
|
taosArrayDestroy(pVals);
|
||||||
if (pReq) {
|
if (pReq) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,18 +71,11 @@ static void destroyTqHandle(void* data) {
|
||||||
walCloseReader(pData->pWalReader);
|
walCloseReader(pData->pWalReader);
|
||||||
tqCloseReader(pData->execHandle.pTqReader);
|
tqCloseReader(pData->execHandle.pTqReader);
|
||||||
}
|
}
|
||||||
}
|
if(pData->msg != NULL) {
|
||||||
|
rpcFreeCont(pData->msg->pCont);
|
||||||
static void tqPushEntryFree(void* data) {
|
taosMemoryFree(pData->msg);
|
||||||
STqPushEntry* p = *(void**)data;
|
pData->msg = NULL;
|
||||||
if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__POLL_RSP) {
|
|
||||||
tDeleteSMqDataRsp(p->pDataRsp);
|
|
||||||
} else if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__TAOSX_RSP) {
|
|
||||||
tDeleteSTaosxRsp((STaosxRsp*)p->pDataRsp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(p->pDataRsp);
|
|
||||||
taosMemoryFree(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tqOffsetLessOrEqual(const STqOffset* pLeft, const STqOffset* pRight) {
|
static bool tqOffsetLessOrEqual(const STqOffset* pLeft, const STqOffset* pRight) {
|
||||||
|
@ -105,14 +98,18 @@ STQ* tqOpen(const char* path, SVnode* pVnode) {
|
||||||
taosHashSetFreeFp(pTq->pHandle, destroyTqHandle);
|
taosHashSetFreeFp(pTq->pHandle, destroyTqHandle);
|
||||||
|
|
||||||
taosInitRWLatch(&pTq->lock);
|
taosInitRWLatch(&pTq->lock);
|
||||||
pTq->pPushMgr = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
pTq->pPushMgr = taosHashInit(64, MurmurHash3_32, false, HASH_NO_LOCK);
|
||||||
taosHashSetFreeFp(pTq->pPushMgr, tqPushEntryFree);
|
|
||||||
|
|
||||||
pTq->pCheckInfo = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
pTq->pCheckInfo = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||||
taosHashSetFreeFp(pTq->pCheckInfo, (FDelete)tDeleteSTqCheckInfo);
|
taosHashSetFreeFp(pTq->pCheckInfo, (FDelete)tDeleteSTqCheckInfo);
|
||||||
|
|
||||||
tqInitialize(pTq);
|
int32_t code = tqInitialize(pTq);
|
||||||
return pTq;
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tqClose(pTq);
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
return pTq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqInitialize(STQ* pTq) {
|
int32_t tqInitialize(STQ* pTq) {
|
||||||
|
@ -228,17 +225,19 @@ static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqData
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry) {
|
int32_t tqPushDataRsp(STQ* pTq, STqHandle* pHandle) {
|
||||||
SMqDataRsp* pRsp = pPushEntry->pDataRsp;
|
SMqDataRsp dataRsp = {0};
|
||||||
SMqRspHead* pHeader = &pPushEntry->pDataRsp->head;
|
dataRsp.head.consumerId = pHandle->consumerId;
|
||||||
doSendDataRsp(&pPushEntry->info, pRsp, pHeader->epoch, pHeader->consumerId, pHeader->mqMsgType);
|
dataRsp.head.epoch = pHandle->epoch;
|
||||||
|
dataRsp.head.mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
|
||||||
|
doSendDataRsp(&pHandle->msg->info, &dataRsp, pHandle->epoch, pHandle->consumerId, TMQ_MSG_TYPE__POLL_RSP);
|
||||||
|
|
||||||
char buf1[80] = {0};
|
char buf1[80] = {0};
|
||||||
char buf2[80] = {0};
|
char buf2[80] = {0};
|
||||||
tFormatOffset(buf1, tListLen(buf1), &pRsp->reqOffset);
|
tFormatOffset(buf1, tListLen(buf1), &dataRsp.reqOffset);
|
||||||
tFormatOffset(buf2, tListLen(buf2), &pRsp->rspOffset);
|
tFormatOffset(buf2, tListLen(buf2), &dataRsp.rspOffset);
|
||||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s",
|
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s",
|
||||||
TD_VID(pTq->pVnode), pRsp->head.consumerId, pRsp->head.epoch, pRsp->blockNum, buf1, buf2);
|
TD_VID(pTq->pVnode), dataRsp.head.consumerId, dataRsp.head.epoch, dataRsp.blockNum, buf1, buf2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,13 +381,13 @@ int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
||||||
|
|
||||||
tqDebug("vgId:%d, tq process delete sub req %s", pTq->pVnode->config.vgId, pReq->subKey);
|
tqDebug("vgId:%d, tq process delete sub req %s", pTq->pVnode->config.vgId, pReq->subKey);
|
||||||
|
int32_t code = 0;
|
||||||
taosWLockLatch(&pTq->lock);
|
// taosWLockLatch(&pTq->lock);
|
||||||
int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
|
// int32_t code = taosHashRemove(pTq->pPushMgr, pReq->subKey, strlen(pReq->subKey));
|
||||||
if (code != 0) {
|
// if (code != 0) {
|
||||||
tqDebug("vgId:%d, tq remove push handle %s", pTq->pVnode->config.vgId, pReq->subKey);
|
// tqDebug("vgId:%d, tq remove push handle %s", pTq->pVnode->config.vgId, pReq->subKey);
|
||||||
}
|
// }
|
||||||
taosWUnLockLatch(&pTq->lock);
|
// taosWUnLockLatch(&pTq->lock);
|
||||||
|
|
||||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pReq->subKey, strlen(pReq->subKey));
|
STqHandle* pHandle = taosHashGet(pTq->pHandle, pReq->subKey, strlen(pReq->subKey));
|
||||||
if (pHandle) {
|
if (pHandle) {
|
||||||
|
@ -446,6 +445,7 @@ int32_t tqProcessDelCheckInfoReq(STQ* pTq, int64_t sversion, char* msg, int32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||||
|
int ret = 0;
|
||||||
SMqRebVgReq req = {0};
|
SMqRebVgReq req = {0};
|
||||||
tDecodeSMqRebVgReq(msg, &req);
|
tDecodeSMqRebVgReq(msg, &req);
|
||||||
|
|
||||||
|
@ -464,8 +464,7 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
|
|
||||||
if (req.newConsumerId == -1) {
|
if (req.newConsumerId == -1) {
|
||||||
tqError("vgId:%d, tq invalid re-balance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
|
tqError("vgId:%d, tq invalid re-balance request, new consumerId %" PRId64 "", req.vgId, req.newConsumerId);
|
||||||
taosMemoryFree(req.qmsg);
|
goto end;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STqHandle tqHandle = {0};
|
STqHandle tqHandle = {0};
|
||||||
|
@ -482,8 +481,8 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
// TODO version should be assigned and refed during preprocess
|
// TODO version should be assigned and refed during preprocess
|
||||||
SWalRef* pRef = walRefCommittedVer(pVnode->pWal);
|
SWalRef* pRef = walRefCommittedVer(pVnode->pWal);
|
||||||
if (pRef == NULL) {
|
if (pRef == NULL) {
|
||||||
taosMemoryFree(req.qmsg);
|
ret = -1;
|
||||||
return -1;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t ver = pRef->refVer;
|
int64_t ver = pRef->refVer;
|
||||||
|
@ -535,50 +534,42 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
||||||
taosHashPut(pTq->pHandle, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
|
taosHashPut(pTq->pHandle, req.subKey, strlen(req.subKey), pHandle, sizeof(STqHandle));
|
||||||
tqDebug("try to persist handle %s consumer:0x%" PRIx64 " , old consumer:0x%" PRIx64, req.subKey,
|
tqDebug("try to persist handle %s consumer:0x%" PRIx64 " , old consumer:0x%" PRIx64, req.subKey,
|
||||||
pHandle->consumerId, oldConsumerId);
|
pHandle->consumerId, oldConsumerId);
|
||||||
if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) {
|
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
||||||
taosMemoryFree(req.qmsg);
|
goto end;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (pHandle->consumerId == req.newConsumerId) { // do nothing
|
if (pHandle->consumerId == req.newConsumerId) { // do nothing
|
||||||
tqInfo("vgId:%d consumer:0x%" PRIx64 " remains, no switch occurs", req.vgId, req.newConsumerId);
|
tqInfo("vgId:%d consumer:0x%" PRIx64 " remains, no switch occurs", req.vgId, req.newConsumerId);
|
||||||
atomic_store_32(&pHandle->epoch, -1);
|
|
||||||
atomic_add_fetch_32(&pHandle->epoch, 1);
|
atomic_add_fetch_32(&pHandle->epoch, 1);
|
||||||
taosMemoryFree(req.qmsg);
|
|
||||||
return tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
|
||||||
} else {
|
} else {
|
||||||
tqInfo("vgId:%d switch consumer from Id:0x%" PRIx64 " to Id:0x%" PRIx64, req.vgId, pHandle->consumerId,
|
tqInfo("vgId:%d switch consumer from Id:0x%" PRIx64 " to Id:0x%" PRIx64, req.vgId, pHandle->consumerId,
|
||||||
req.newConsumerId);
|
req.newConsumerId);
|
||||||
|
|
||||||
// kill executing task
|
|
||||||
qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
|
|
||||||
if (pTaskInfo != NULL) {
|
|
||||||
qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWLockLatch(&pTq->lock);
|
|
||||||
atomic_store_32(&pHandle->epoch, -1);
|
|
||||||
|
|
||||||
// remove if it has been register in the push manager, and return one empty block to consumer
|
|
||||||
tqUnregisterPushHandle(pTq, req.subKey, (int32_t)strlen(req.subKey), pHandle->consumerId, true);
|
|
||||||
|
|
||||||
atomic_store_64(&pHandle->consumerId, req.newConsumerId);
|
atomic_store_64(&pHandle->consumerId, req.newConsumerId);
|
||||||
atomic_add_fetch_32(&pHandle->epoch, 1);
|
atomic_store_32(&pHandle->epoch, 0);
|
||||||
|
|
||||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
|
||||||
qStreamCloseTsdbReader(pTaskInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWUnLockLatch(&pTq->lock);
|
|
||||||
if (tqMetaSaveHandle(pTq, req.subKey, pHandle) < 0) {
|
|
||||||
taosMemoryFree(req.qmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// kill executing task
|
||||||
|
qTaskInfo_t pTaskInfo = pHandle->execHandle.task;
|
||||||
|
if (pTaskInfo != NULL) {
|
||||||
|
qKillTask(pTaskInfo, TSDB_CODE_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWLockLatch(&pTq->lock);
|
||||||
|
// remove if it has been register in the push manager, and return one empty block to consumer
|
||||||
|
tqUnregisterPushHandle(pTq, pHandle);
|
||||||
|
|
||||||
|
|
||||||
|
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||||
|
qStreamCloseTsdbReader(pTaskInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWUnLockLatch(&pTq->lock);
|
||||||
|
ret = tqMetaSaveHandle(pTq, req.subKey, pHandle);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
taosMemoryFree(req.qmsg);
|
taosMemoryFree(req.qmsg);
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
||||||
|
@ -601,11 +592,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
||||||
pTask->chkInfo.currentVer = ver;
|
pTask->chkInfo.currentVer = ver;
|
||||||
|
|
||||||
// expand executor
|
// expand executor
|
||||||
if (pTask->fillHistory) {
|
pTask->status.taskStatus = (pTask->fillHistory)? TASK_STATUS__WAIT_DOWNSTREAM:TASK_STATUS__NORMAL;
|
||||||
pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM;
|
|
||||||
} else {
|
|
||||||
pTask->status.taskStatus = TASK_STATUS__RESTORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
if (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
||||||
pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1);
|
pTask->pState = streamStateOpen(pTq->pStreamMeta->path, pTask, false, -1, -1);
|
||||||
|
@ -664,6 +651,7 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
||||||
}
|
}
|
||||||
|
|
||||||
streamSetupTrigger(pTask);
|
streamSetupTrigger(pTask);
|
||||||
|
|
||||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
|
tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
|
||||||
pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
|
pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
|
||||||
|
|
||||||
|
@ -693,8 +681,9 @@ int32_t tqProcessStreamTaskCheckReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
};
|
};
|
||||||
|
|
||||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
||||||
|
|
||||||
if (pTask) {
|
if (pTask) {
|
||||||
rsp.status = (atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL) ? 1 : 0;
|
rsp.status = streamTaskCheckStatus(pTask);
|
||||||
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
streamMetaReleaseTask(pTq->pStreamMeta, pTask);
|
||||||
|
|
||||||
tqDebug("tq recv task check req(reqId:0x%" PRIx64
|
tqDebug("tq recv task check req(reqId:0x%" PRIx64
|
||||||
|
@ -785,13 +774,17 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
|
|
||||||
// 2.save task, use the newest commit version as the initial start version of stream task.
|
// 2.save task, use the newest commit version as the initial start version of stream task.
|
||||||
|
taosWLockLatch(&pTq->pStreamMeta->lock);
|
||||||
code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask);
|
code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
tqError("vgId:%d failed to add s-task:%s, total:%d", TD_VID(pTq->pVnode), pTask->id.idStr,
|
tqError("vgId:%d failed to add s-task:%s, total:%d", TD_VID(pTq->pVnode), pTask->id.idStr,
|
||||||
streamMetaGetNumOfTasks(pTq->pStreamMeta));
|
streamMetaGetNumOfTasks(pTq->pStreamMeta));
|
||||||
|
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||||
|
|
||||||
// 3.go through recover steps to fill history
|
// 3.go through recover steps to fill history
|
||||||
if (pTask->fillHistory) {
|
if (pTask->fillHistory) {
|
||||||
streamTaskCheckDownstream(pTask, sversion);
|
streamTaskCheckDownstream(pTask, sversion);
|
||||||
|
@ -1069,67 +1062,36 @@ int32_t tqProcessDelReq(STQ* pTq, void* pReq, int32_t len, int64_t ver) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqProcessSubmitReq(STQ* pTq, SPackedData submit) {
|
int32_t tqProcessSubmitReqForSubscribe(STQ* pTq) {
|
||||||
#if 0
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
void* pIter = NULL;
|
|
||||||
SStreamDataSubmit2* pSubmit = streamDataSubmitNew(submit, STREAM_INPUT__DATA_SUBMIT);
|
|
||||||
if (pSubmit == NULL) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
tqError("failed to create data submit for stream since out of memory");
|
|
||||||
saveOffsetForAllTasks(pTq, submit.ver);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SArray* pInputQueueFullTasks = taosArrayInit(4, POINTER_BYTES);
|
taosWLockLatch(&pTq->lock);
|
||||||
|
|
||||||
while (1) {
|
if (taosHashGetSize(pTq->pPushMgr) > 0) {
|
||||||
pIter = taosHashIterate(pTq->pStreamMeta->pTasks, pIter);
|
void* pIter = taosHashIterate(pTq->pPushMgr, NULL);
|
||||||
if (pIter == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SStreamTask* pTask = *(SStreamTask**)pIter;
|
while (pIter) {
|
||||||
if (pTask->taskLevel != TASK_LEVEL__SOURCE) {
|
STqHandle* pHandle = *(STqHandle**)pIter;
|
||||||
continue;
|
tqDebug("vgId:%d start set submit for pHandle:%p, consumer:0x%" PRIx64, vgId, pHandle, pHandle->consumerId);
|
||||||
}
|
|
||||||
|
|
||||||
if (pTask->status.taskStatus == TASK_STATUS__RECOVER_PREPARE || pTask->status.taskStatus == TASK_STATUS__WAIT_DOWNSTREAM) {
|
if (ASSERT(pHandle->msg != NULL)) {
|
||||||
tqDebug("stream task:%d skip push data, not ready for processing, status %d", pTask->id.taskId,
|
tqError("pHandle->msg should not be null");
|
||||||
pTask->status.taskStatus);
|
break;
|
||||||
continue;
|
}else{
|
||||||
}
|
SRpcMsg msg = {.msgType = TDMT_VND_TMQ_CONSUME, .pCont = pHandle->msg->pCont, .contLen = pHandle->msg->contLen, .info = pHandle->msg->info};
|
||||||
|
tmsgPutToQueue(&pTq->pVnode->msgCb, QUERY_QUEUE, &msg);
|
||||||
// check if offset value exists
|
taosMemoryFree(pHandle->msg);
|
||||||
char key[128] = {0};
|
pHandle->msg = NULL;
|
||||||
createStreamTaskOffsetKey(key, pTask->id.streamId, pTask->id.taskId);
|
|
||||||
|
|
||||||
if (tInputQueueIsFull(pTask)) {
|
|
||||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, key);
|
|
||||||
|
|
||||||
int64_t ver = submit.ver;
|
|
||||||
if (pOffset == NULL) {
|
|
||||||
doSaveTaskOffset(pTq->pOffsetStore, key, submit.ver);
|
|
||||||
} else {
|
|
||||||
ver = pOffset->val.version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tqDebug("s-task:%s input queue is full, discard submit block, ver:%" PRId64, pTask->id.idStr, ver);
|
pIter = taosHashIterate(pTq->pPushMgr, pIter);
|
||||||
taosArrayPush(pInputQueueFullTasks, &pTask);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if offset value exists
|
taosHashClear(pTq->pPushMgr);
|
||||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, key);
|
|
||||||
ASSERT(pOffset == NULL);
|
|
||||||
|
|
||||||
addSubmitBlockNLaunchTask(pTq->pOffsetStore, pTask, pSubmit, key, submit.ver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
streamDataSubmitDestroy(pSubmit);
|
// unlock
|
||||||
taosFreeQitem(pSubmit);
|
taosWUnLockLatch(&pTq->lock);
|
||||||
#endif
|
|
||||||
|
|
||||||
tqStartStreamTasks(pTq);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1147,9 +1109,6 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||||
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
SStreamTask* pTask = streamMetaAcquireTask(pTq->pStreamMeta, taskId);
|
||||||
if (pTask != NULL) {
|
if (pTask != NULL) {
|
||||||
if (pTask->status.taskStatus == TASK_STATUS__NORMAL) {
|
if (pTask->status.taskStatus == TASK_STATUS__NORMAL) {
|
||||||
tqDebug("vgId:%d s-task:%s start to process run req", vgId, pTask->id.idStr);
|
|
||||||
streamProcessRunReq(pTask);
|
|
||||||
} else if (pTask->status.taskStatus == TASK_STATUS__RESTORE) {
|
|
||||||
tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId,
|
tqDebug("vgId:%d s-task:%s start to process block from wal, last chk point:%" PRId64, vgId,
|
||||||
pTask->id.idStr, pTask->chkInfo.version);
|
pTask->id.idStr, pTask->chkInfo.version);
|
||||||
streamProcessRunReq(pTask);
|
streamProcessRunReq(pTask);
|
||||||
|
@ -1302,21 +1261,22 @@ FAIL:
|
||||||
int32_t tqCheckLogInWal(STQ* pTq, int64_t sversion) { return sversion <= pTq->walLogLastVer; }
|
int32_t tqCheckLogInWal(STQ* pTq, int64_t sversion) { return sversion <= pTq->walLogLastVer; }
|
||||||
|
|
||||||
int32_t tqStartStreamTasks(STQ* pTq) {
|
int32_t tqStartStreamTasks(STQ* pTq) {
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
|
|
||||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||||
|
|
||||||
taosWLockLatch(&pMeta->lock);
|
taosWLockLatch(&pMeta->lock);
|
||||||
int32_t numOfTasks = taosHashGetSize(pTq->pStreamMeta->pTasks);
|
|
||||||
|
int32_t numOfTasks = taosArrayGetSize(pMeta->pTaskList);
|
||||||
if (numOfTasks == 0) {
|
if (numOfTasks == 0) {
|
||||||
tqInfo("vgId:%d no stream tasks exists", vgId);
|
tqInfo("vgId:%d no stream tasks exists", vgId);
|
||||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMeta->walScan += 1;
|
pMeta->walScanCounter += 1;
|
||||||
|
|
||||||
if (pMeta->walScan > 1) {
|
if (pMeta->walScanCounter > 1) {
|
||||||
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScan);
|
tqDebug("vgId:%d wal read task has been launched, remain scan times:%d", vgId, pMeta->walScanCounter);
|
||||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,57 +31,67 @@ char* tqOffsetBuildFName(const char* path, int32_t fVer) {
|
||||||
|
|
||||||
int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
|
int32_t tqOffsetRestoreFromFile(STqOffsetStore* pStore, const char* fname) {
|
||||||
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
|
TdFilePtr pFile = taosOpenFile(fname, TD_FILE_READ);
|
||||||
if (pFile != NULL) {
|
if (pFile == NULL) {
|
||||||
STqOffsetHead head = {0};
|
return TSDB_CODE_SUCCESS;
|
||||||
int64_t code;
|
}
|
||||||
|
|
||||||
while (1) {
|
int32_t vgId = TD_VID(pStore->pTq->pVnode);
|
||||||
if ((code = taosReadFile(pFile, &head, sizeof(STqOffsetHead))) != sizeof(STqOffsetHead)) {
|
int64_t code = 0;
|
||||||
if (code == 0) {
|
|
||||||
break;
|
STqOffsetHead head = {0};
|
||||||
} else {
|
|
||||||
return -1;
|
while (1) {
|
||||||
}
|
if ((code = taosReadFile(pFile, &head, sizeof(STqOffsetHead))) != sizeof(STqOffsetHead)) {
|
||||||
}
|
if (code == 0) {
|
||||||
int32_t size = htonl(head.size);
|
break;
|
||||||
void* memBuf = taosMemoryCalloc(1, size);
|
} else {
|
||||||
if (memBuf == NULL) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((code = taosReadFile(pFile, memBuf, size)) != size) {
|
|
||||||
taosMemoryFree(memBuf);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
STqOffset offset;
|
|
||||||
SDecoder decoder;
|
|
||||||
tDecoderInit(&decoder, memBuf, size);
|
|
||||||
if (tDecodeSTqOffset(&decoder, &offset) < 0) {
|
|
||||||
taosMemoryFree(memBuf);
|
|
||||||
tDecoderClear(&decoder);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tDecoderClear(&decoder);
|
|
||||||
if (taosHashPut(pStore->pHash, offset.subKey, strlen(offset.subKey), &offset, sizeof(STqOffset)) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (offset.val.type == TMQ_OFFSET__LOG) {
|
|
||||||
STqHandle* pHandle = taosHashGet(pStore->pTq->pHandle, offset.subKey, strlen(offset.subKey));
|
|
||||||
if (pHandle) {
|
|
||||||
if (walRefVer(pHandle->pRef, offset.val.version) < 0) {
|
|
||||||
tqError("vgId: %d, tq handle %s ref ver %" PRId64 "error", pStore->pTq->pVnode->config.vgId,
|
|
||||||
pHandle->subKey, offset.val.version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taosMemoryFree(memBuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taosCloseFile(&pFile);
|
int32_t size = htonl(head.size);
|
||||||
|
void* pMemBuf = taosMemoryCalloc(1, size);
|
||||||
|
if (pMemBuf == NULL) {
|
||||||
|
tqError("vgId:%d failed to restore offset from file, since out of memory, malloc size:%d", vgId, size);
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((code = taosReadFile(pFile, pMemBuf, size)) != size) {
|
||||||
|
taosMemoryFree(pMemBuf);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
STqOffset offset;
|
||||||
|
SDecoder decoder;
|
||||||
|
tDecoderInit(&decoder, pMemBuf, size);
|
||||||
|
if (tDecodeSTqOffset(&decoder, &offset) < 0) {
|
||||||
|
taosMemoryFree(pMemBuf);
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
if (taosHashPut(pStore->pHash, offset.subKey, strlen(offset.subKey), &offset, sizeof(STqOffset)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo remove this
|
||||||
|
if (offset.val.type == TMQ_OFFSET__LOG) {
|
||||||
|
STqHandle* pHandle = taosHashGet(pStore->pTq->pHandle, offset.subKey, strlen(offset.subKey));
|
||||||
|
if (pHandle) {
|
||||||
|
if (walRefVer(pHandle->pRef, offset.val.version) < 0) {
|
||||||
|
// tqError("vgId: %d, tq handle %s ref ver %" PRId64 "error", pStore->pTq->pVnode->config.vgId, pHandle->subKey,
|
||||||
|
// offset.val.version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taosMemoryFree(pMemBuf);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
taosCloseFile(&pFile);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
STqOffsetStore* tqOffsetOpen(STQ* pTq) {
|
STqOffsetStore* tqOffsetOpen(STQ* pTq) {
|
||||||
|
@ -89,6 +99,7 @@ STqOffsetStore* tqOffsetOpen(STQ* pTq) {
|
||||||
if (pStore == NULL) {
|
if (pStore == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStore->pTq = pTq;
|
pStore->pTq = pTq;
|
||||||
pStore->needCommit = 0;
|
pStore->needCommit = 0;
|
||||||
pTq->pOffsetStore = pStore;
|
pTq->pOffsetStore = pStore;
|
||||||
|
@ -98,12 +109,14 @@ STqOffsetStore* tqOffsetOpen(STQ* pTq) {
|
||||||
taosMemoryFree(pStore);
|
taosMemoryFree(pStore);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* fname = tqOffsetBuildFName(pStore->pTq->path, 0);
|
char* fname = tqOffsetBuildFName(pStore->pTq->path, 0);
|
||||||
if (tqOffsetRestoreFromFile(pStore, fname) < 0) {
|
if (tqOffsetRestoreFromFile(pStore, fname) < 0) {
|
||||||
taosMemoryFree(fname);
|
taosMemoryFree(fname);
|
||||||
taosMemoryFree(pStore);
|
taosMemoryFree(pStore);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosMemoryFree(fname);
|
taosMemoryFree(fname);
|
||||||
return pStore;
|
return pStore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,342 +16,26 @@
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
#include "vnd.h"
|
#include "vnd.h"
|
||||||
|
|
||||||
#if 0
|
|
||||||
void tqTmrRspFunc(void* param, void* tmrId) {
|
|
||||||
STqHandle* pHandle = (STqHandle*)param;
|
|
||||||
atomic_store_8(&pHandle->pushHandle.tmrStopped, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t tqLoopExecFromQueue(STQ* pTq, STqHandle* pHandle, SStreamDataSubmit** ppSubmit, SMqDataRsp* pRsp) {
|
|
||||||
SStreamDataSubmit* pSubmit = *ppSubmit;
|
|
||||||
while (pSubmit != NULL) {
|
|
||||||
if (tqLogScanExec(pTq, &pHandle->execHandle, pSubmit->data, pRsp, 0) < 0) {
|
|
||||||
}
|
|
||||||
// update processed
|
|
||||||
atomic_store_64(&pHandle->pushHandle.processedVer, pSubmit->ver);
|
|
||||||
streamQueueProcessSuccess(&pHandle->pushHandle.inputQ);
|
|
||||||
streamDataSubmitDestroy(pSubmit);
|
|
||||||
if (pRsp->blockNum > 0) {
|
|
||||||
*ppSubmit = pSubmit;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*ppSubmit = pSubmit;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqExecFromInputQ(STQ* pTq, STqHandle* pHandle) {
|
|
||||||
SMqDataRsp rsp = {0};
|
|
||||||
// 1. guard and set status executing
|
|
||||||
int8_t execStatus = atomic_val_compare_exchange_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE,
|
|
||||||
TASK_EXEC_STATUS__EXECUTING);
|
|
||||||
if (execStatus == TASK_EXEC_STATUS__IDLE) {
|
|
||||||
SStreamDataSubmit* pSubmit = NULL;
|
|
||||||
// 2. check processedVer
|
|
||||||
// 2.1. if not missed, get msg from queue
|
|
||||||
// 2.2. if missed, scan wal
|
|
||||||
pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
|
|
||||||
while (pHandle->pushHandle.processedVer <= pSubmit->ver) {
|
|
||||||
// read from wal
|
|
||||||
}
|
|
||||||
while (pHandle->pushHandle.processedVer > pSubmit->ver + 1) {
|
|
||||||
streamQueueProcessSuccess(&pHandle->pushHandle.inputQ);
|
|
||||||
streamDataSubmitDestroy(pSubmit);
|
|
||||||
pSubmit = streamQueueNextItem(&pHandle->pushHandle.inputQ);
|
|
||||||
if (pSubmit == NULL) break;
|
|
||||||
}
|
|
||||||
// 3. exec, after each success, update processed ver
|
|
||||||
// first run
|
|
||||||
if (tqLoopExecFromQueue(pTq, pHandle, &pSubmit, &rsp) == 0) {
|
|
||||||
goto SEND_RSP;
|
|
||||||
}
|
|
||||||
// set exec status closing
|
|
||||||
atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__CLOSING);
|
|
||||||
// second run
|
|
||||||
if (tqLoopExecFromQueue(pTq, pHandle, &pSubmit, &rsp) == 0) {
|
|
||||||
goto SEND_RSP;
|
|
||||||
}
|
|
||||||
// set exec status idle
|
|
||||||
atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE);
|
|
||||||
}
|
|
||||||
SEND_RSP:
|
|
||||||
// 4. if get result
|
|
||||||
// 4.1 set exec input status blocked and exec status idle
|
|
||||||
atomic_store_8(&pHandle->pushHandle.execStatus, TASK_EXEC_STATUS__IDLE);
|
|
||||||
// 4.2 rpc send
|
|
||||||
rsp.rspOffset = pHandle->pushHandle.processedVer;
|
|
||||||
/*if (tqSendPollRsp(pTq, pMsg, pReq, &rsp) < 0) {*/
|
|
||||||
/*return -1;*/
|
|
||||||
/*}*/
|
|
||||||
// 4.3 clear rpc info
|
|
||||||
memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqOpenPushHandle(STQ* pTq, STqHandle* pHandle) {
|
|
||||||
memset(&pHandle->pushHandle, 0, sizeof(STqPushHandle));
|
|
||||||
pHandle->pushHandle.inputQ.queue = taosOpenQueue();
|
|
||||||
pHandle->pushHandle.inputQ.qall = taosAllocateQall();
|
|
||||||
if (pHandle->pushHandle.inputQ.queue == NULL || pHandle->pushHandle.inputQ.qall == NULL) {
|
|
||||||
if (pHandle->pushHandle.inputQ.queue) {
|
|
||||||
taosCloseQueue(pHandle->pushHandle.inputQ.queue);
|
|
||||||
}
|
|
||||||
if (pHandle->pushHandle.inputQ.qall) {
|
|
||||||
taosFreeQall(pHandle->pushHandle.inputQ.qall);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqPreparePush(STQ* pTq, STqHandle* pHandle, int64_t reqId, const SRpcHandleInfo* pInfo, int64_t processedVer,
|
|
||||||
int64_t timeout) {
|
|
||||||
memcpy(&pHandle->pushHandle.rpcInfo, pInfo, sizeof(SRpcHandleInfo));
|
|
||||||
atomic_store_64(&pHandle->pushHandle.reqId, reqId);
|
|
||||||
atomic_store_64(&pHandle->pushHandle.processedVer, processedVer);
|
|
||||||
atomic_store_8(&pHandle->pushHandle.inputStatus, TASK_INPUT_STATUS__NORMAL);
|
|
||||||
atomic_store_8(&pHandle->pushHandle.tmrStopped, 0);
|
|
||||||
taosTmrReset(tqTmrRspFunc, (int32_t)timeout, pHandle, tqMgmt.timer, &pHandle->pushHandle.timerId);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqEnqueue(STqHandle* pHandle, SStreamDataSubmit* pSubmit) {
|
|
||||||
int8_t inputStatus = atomic_load_8(&pHandle->pushHandle.inputStatus);
|
|
||||||
if (inputStatus == TASK_INPUT_STATUS__NORMAL) {
|
|
||||||
SStreamDataSubmit* pSubmitClone = streamSubmitBlockClone(pSubmit);
|
|
||||||
if (pSubmitClone == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
taosWriteQitem(pHandle->pushHandle.inputQ.queue, pSubmitClone);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqSendExecReq(STQ* pTq, STqHandle* pHandle) {
|
|
||||||
//
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver, SRpcHandleInfo handleInfo) {
|
|
||||||
if (msgType != TDMT_VND_SUBMIT) return 0;
|
|
||||||
void* pIter = NULL;
|
|
||||||
STqHandle* pHandle = NULL;
|
|
||||||
SSubmitReq* pReq = (SSubmitReq*)msg;
|
|
||||||
int32_t workerId = 4;
|
|
||||||
int64_t fetchOffset = ver;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
pIter = taosHashIterate(pTq->pushMgr, pIter);
|
|
||||||
if (pIter == NULL) break;
|
|
||||||
pHandle = *(STqHandle**)pIter;
|
|
||||||
|
|
||||||
taosWLockLatch(&pHandle->pushHandle.lock);
|
|
||||||
|
|
||||||
SMqDataRsp rsp = {0};
|
|
||||||
rsp.reqOffset = pHandle->pushHandle.reqOffset;
|
|
||||||
rsp.blockData = taosArrayInit(0, sizeof(void*));
|
|
||||||
rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
|
|
||||||
|
|
||||||
if (msgType == TDMT_VND_SUBMIT) {
|
|
||||||
tqLogScanExec(pTq, &pHandle->execHandle, pReq, &rsp, workerId);
|
|
||||||
} else {
|
|
||||||
tqError("tq push unexpected msg type %d", msgType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rsp.blockNum == 0) {
|
|
||||||
taosWUnLockLatch(&pHandle->pushHandle.lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
rsp.rspOffset = fetchOffset;
|
|
||||||
|
|
||||||
int32_t tlen = sizeof(SMqRspHead) + tEncodeSMqDataBlkRsp(NULL, &rsp);
|
|
||||||
void* buf = rpcMallocCont(tlen);
|
|
||||||
if (buf == NULL) {
|
|
||||||
// todo free
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_RSP;
|
|
||||||
((SMqRspHead*)buf)->epoch = pHandle->pushHandle.epoch;
|
|
||||||
((SMqRspHead*)buf)->consumerId = pHandle->pushHandle.consumerId;
|
|
||||||
|
|
||||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
|
||||||
tEncodeSMqDataBlkRsp(&abuf, &rsp);
|
|
||||||
|
|
||||||
SRpcMsg resp = {
|
|
||||||
.info = pHandle->pushHandle.rpcInfo,
|
|
||||||
.pCont = buf,
|
|
||||||
.contLen = tlen,
|
|
||||||
.code = 0,
|
|
||||||
};
|
|
||||||
tmsgSendRsp(&resp);
|
|
||||||
|
|
||||||
memset(&pHandle->pushHandle.rpcInfo, 0, sizeof(SRpcHandleInfo));
|
|
||||||
taosWUnLockLatch(&pHandle->pushHandle.lock);
|
|
||||||
|
|
||||||
tqDebug("vgId:%d offset %" PRId64 " from consumer:%" PRId64 ", (epoch %d) send rsp, block num: %d, req:%" PRId64 ", rsp:%" PRId64,
|
|
||||||
TD_VID(pTq->pVnode), fetchOffset, pHandle->pushHandle.consumerId, pHandle->pushHandle.epoch, rsp.blockNum,
|
|
||||||
rsp.reqOffset, rsp.rspOffset);
|
|
||||||
|
|
||||||
// TODO destroy
|
|
||||||
taosArrayDestroy(rsp.blockData);
|
|
||||||
taosArrayDestroy(rsp.blockDataLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* pKey;
|
|
||||||
int64_t keyLen;
|
|
||||||
} SItem;
|
|
||||||
|
|
||||||
static void recordPushedEntry(SArray* cachedKey, void* pIter);
|
|
||||||
static void doRemovePushedEntry(SArray* pCachedKeys, STQ* pTq);
|
|
||||||
|
|
||||||
static void freeItem(void* param) {
|
|
||||||
SItem* p = (SItem*)param;
|
|
||||||
taosMemoryFree(p->pKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void doPushDataForEntry(void* pIter, STqExecHandle* pExec, STQ* pTq, int64_t ver, int32_t vgId, char* pData,
|
|
||||||
int32_t dataLen, SArray* pCachedKey) {
|
|
||||||
STqPushEntry* pPushEntry = *(STqPushEntry**)pIter;
|
|
||||||
|
|
||||||
SMqDataRsp* pRsp = pPushEntry->pDataRsp;
|
|
||||||
if (pRsp->reqOffset.version >= ver) {
|
|
||||||
tqDebug("vgId:%d, push entry req version %" PRId64 ", while push version %" PRId64 ", skip", vgId,
|
|
||||||
pRsp->reqOffset.version, ver);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qTaskInfo_t pTaskInfo = pExec->task;
|
|
||||||
|
|
||||||
// prepare scan mem data
|
|
||||||
SPackedData submit = {.msgStr = pData, .msgLen = dataLen, .ver = ver};
|
|
||||||
|
|
||||||
if (qStreamSetScanMemData(pTaskInfo, submit) != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qStreamSetOpen(pTaskInfo);
|
|
||||||
// here start to scan submit block to extract the subscribed data
|
|
||||||
int32_t totalRows = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
SSDataBlock* pDataBlock = NULL;
|
|
||||||
uint64_t ts = 0;
|
|
||||||
if (qExecTask(pTaskInfo, &pDataBlock, &ts) < 0) {
|
|
||||||
tqDebug("vgId:%d, tq exec error since %s", vgId, terrstr());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDataBlock == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tqAddBlockDataToRsp(pDataBlock, pRsp, pExec->numOfCols, pTq->pVnode->config.tsdbCfg.precision);
|
|
||||||
pRsp->blockNum++;
|
|
||||||
totalRows += pDataBlock->info.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
tqDebug("vgId:%d, tq handle push, subkey:%s, block num:%d, rows:%d", vgId, pPushEntry->subKey, pRsp->blockNum,
|
|
||||||
totalRows);
|
|
||||||
|
|
||||||
if (pRsp->blockNum > 0) {
|
|
||||||
tqOffsetResetToLog(&pRsp->rspOffset, ver);
|
|
||||||
tqPushDataRsp(pTq, pPushEntry);
|
|
||||||
recordPushedEntry(pCachedKey, pIter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
|
int32_t tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver) {
|
||||||
void* pReq = POINTER_SHIFT(msg, sizeof(SSubmitReq2Msg));
|
|
||||||
int32_t len = msgLen - sizeof(SSubmitReq2Msg);
|
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
|
||||||
|
|
||||||
if (msgType == TDMT_VND_SUBMIT) {
|
if (msgType == TDMT_VND_SUBMIT) {
|
||||||
// lock push mgr to avoid potential msg lost
|
tqProcessSubmitReqForSubscribe(pTq);
|
||||||
taosWLockLatch(&pTq->lock);
|
|
||||||
|
|
||||||
int32_t numOfRegisteredPush = taosHashGetSize(pTq->pPushMgr);
|
|
||||||
if (numOfRegisteredPush > 0) {
|
|
||||||
tqDebug("vgId:%d tq push msg version:%" PRId64 " type:%s, head:%p, body:%p len:%d, numOfPushed consumers:%d",
|
|
||||||
vgId, ver, TMSG_INFO(msgType), msg, pReq, len, numOfRegisteredPush);
|
|
||||||
|
|
||||||
void* data = taosMemoryMalloc(len);
|
|
||||||
if (data == NULL) {
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
tqError("failed to copy data for stream since out of memory, vgId:%d", vgId);
|
|
||||||
taosWUnLockLatch(&pTq->lock);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data, pReq, len);
|
|
||||||
|
|
||||||
SArray* cachedKey = taosArrayInit(0, sizeof(SItem));
|
|
||||||
void* pIter = NULL;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
pIter = taosHashIterate(pTq->pPushMgr, pIter);
|
|
||||||
if (pIter == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
STqPushEntry* pPushEntry = *(STqPushEntry**)pIter;
|
|
||||||
|
|
||||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pPushEntry->subKey, strlen(pPushEntry->subKey));
|
|
||||||
if (pHandle == NULL) {
|
|
||||||
tqDebug("vgId:%d, failed to find handle %s in pushing data to consumer, ignore", pTq->pVnode->config.vgId,
|
|
||||||
pPushEntry->subKey);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
STqExecHandle* pExec = &pHandle->execHandle;
|
|
||||||
doPushDataForEntry(pIter, pExec, pTq, ver, vgId, data, len, cachedKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
doRemovePushedEntry(cachedKey, pTq);
|
|
||||||
taosArrayDestroyEx(cachedKey, freeItem);
|
|
||||||
taosMemoryFree(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// unlock
|
|
||||||
taosWUnLockLatch(&pTq->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tqDebug("handle submit, restore:%d, size:%d", pTq->pVnode->restored, (int)taosHashGetSize(pTq->pStreamMeta->pTasks));
|
int32_t numOfTasks = streamMetaGetNumOfTasks(pTq->pStreamMeta);
|
||||||
|
tqDebug("handle submit, restore:%d, size:%d", pTq->pVnode->restored, numOfTasks);
|
||||||
|
|
||||||
// push data for stream processing:
|
// push data for stream processing:
|
||||||
// 1. the vnode has already been restored.
|
// 1. the vnode has already been restored.
|
||||||
// 2. the vnode should be the leader.
|
// 2. the vnode should be the leader.
|
||||||
// 3. the stream is not suspended yet.
|
// 3. the stream is not suspended yet.
|
||||||
if (!tsDisableStream && vnodeIsRoleLeader(pTq->pVnode) && pTq->pVnode->restored) {
|
if (!tsDisableStream && vnodeIsRoleLeader(pTq->pVnode) && pTq->pVnode->restored) {
|
||||||
if (taosHashGetSize(pTq->pStreamMeta->pTasks) == 0) {
|
if (numOfTasks == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgType == TDMT_VND_SUBMIT) {
|
if (msgType == TDMT_VND_SUBMIT) {
|
||||||
#if 0
|
tqStartStreamTasks(pTq);
|
||||||
void* data = taosMemoryMalloc(len);
|
|
||||||
if (data == NULL) {
|
|
||||||
// todo: for all stream in this vnode, keep this offset in the offset files, and wait for a moment, and then retry
|
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
tqError("vgId:%d, failed to copy submit data for stream processing, since out of memory", vgId);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(data, pReq, len);
|
|
||||||
SPackedData submit = {.msgStr = data, .msgLen = len, .ver = ver};
|
|
||||||
|
|
||||||
tqDebug("vgId:%d tq copy submit msg:%p len:%d ver:%" PRId64 " from %p for stream", vgId, data, len, ver, pReq);
|
|
||||||
tqProcessSubmitReq(pTq, submit);
|
|
||||||
#endif
|
|
||||||
SPackedData submit = {0};
|
|
||||||
tqProcessSubmitReq(pTq, submit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgType == TDMT_VND_DELETE) {
|
if (msgType == TDMT_VND_DELETE) {
|
||||||
|
@ -362,83 +46,42 @@ int32_t tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t v
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest, SRpcMsg* pRpcMsg, SMqDataRsp* pDataRsp,
|
int32_t tqRegisterPushHandle(STQ* pTq, void* handle, SRpcMsg* pMsg) {
|
||||||
int32_t type) {
|
|
||||||
uint64_t consumerId = pRequest->consumerId;
|
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
STqHandle* pTqHandle = pHandle;
|
STqHandle* pHandle = (STqHandle*)handle;
|
||||||
|
|
||||||
STqPushEntry* pPushEntry = taosMemoryCalloc(1, sizeof(STqPushEntry));
|
if (pHandle->msg == NULL) {
|
||||||
if (pPushEntry == NULL) {
|
pHandle->msg = taosMemoryCalloc(1, sizeof(SRpcMsg));
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", vgId:%d failed to malloc, size:%d", consumerId, vgId,
|
memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg));
|
||||||
(int32_t)sizeof(STqPushEntry));
|
pHandle->msg->pCont = rpcMallocCont(pMsg->contLen);
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
} else {
|
||||||
return -1;
|
void* tmp = pHandle->msg->pCont;
|
||||||
|
memcpy(pHandle->msg, pMsg, sizeof(SRpcMsg));
|
||||||
|
pHandle->msg->pCont = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPushEntry->info = pRpcMsg->info;
|
memcpy(pHandle->msg->pCont, pMsg->pCont, pMsg->contLen);
|
||||||
memcpy(pPushEntry->subKey, pTqHandle->subKey, TSDB_SUBSCRIBE_KEY_LEN);
|
pHandle->msg->contLen = pMsg->contLen;
|
||||||
|
int32_t ret = taosHashPut(pTq->pPushMgr, pHandle->subKey, strlen(pHandle->subKey), &pHandle, POINTER_BYTES);
|
||||||
if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
|
tqDebug("vgId:%d data is over, ret:%d, consumerId:0x%" PRIx64 ", register to pHandle:%p, pCont:%p, len:%d", vgId, ret,
|
||||||
pPushEntry->pDataRsp = taosMemoryCalloc(1, sizeof(STaosxRsp));
|
pHandle->consumerId, pHandle, pHandle->msg->pCont, pHandle->msg->contLen);
|
||||||
memcpy(pPushEntry->pDataRsp, pDataRsp, sizeof(STaosxRsp));
|
|
||||||
} else if (type == TMQ_MSG_TYPE__POLL_RSP) {
|
|
||||||
pPushEntry->pDataRsp = taosMemoryCalloc(1, sizeof(SMqDataRsp));
|
|
||||||
memcpy(pPushEntry->pDataRsp, pDataRsp, sizeof(SMqDataRsp));
|
|
||||||
}
|
|
||||||
|
|
||||||
SMqRspHead* pHead = &pPushEntry->pDataRsp->head;
|
|
||||||
pHead->consumerId = consumerId;
|
|
||||||
pHead->epoch = pRequest->epoch;
|
|
||||||
pHead->mqMsgType = type;
|
|
||||||
|
|
||||||
taosHashPut(pTq->pPushMgr, pTqHandle->subKey, strlen(pTqHandle->subKey), &pPushEntry, sizeof(void*));
|
|
||||||
|
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s offset:%" PRId64 ", vgId:%d save handle to push mgr, total:%d",
|
|
||||||
consumerId, pTqHandle->subKey, pDataRsp->reqOffset.version, vgId, taosHashGetSize(pTq->pPushMgr));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqUnregisterPushHandle(STQ* pTq, const char* pKey, int32_t keyLen, uint64_t consumerId, bool rspConsumer) {
|
int32_t tqUnregisterPushHandle(STQ* pTq, void *handle) {
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
STqHandle *pHandle = (STqHandle*)handle;
|
||||||
STqPushEntry** pEntry = taosHashGet(pTq->pPushMgr, pKey, keyLen);
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
|
|
||||||
if (pEntry != NULL) {
|
int32_t ret = taosHashRemove(pTq->pPushMgr, pHandle->subKey, strlen(pHandle->subKey));
|
||||||
uint64_t cId = (*pEntry)->pDataRsp->head.consumerId;
|
tqError("vgId:%d remove pHandle:%p,ret:%d consumer Id:0x%" PRIx64, vgId, pHandle, ret, pHandle->consumerId);
|
||||||
ASSERT(consumerId == cId);
|
|
||||||
|
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s vgId:%d remove from push mgr, remains:%d", consumerId,
|
if(pHandle->msg != NULL) {
|
||||||
(*pEntry)->subKey, vgId, taosHashGetSize(pTq->pPushMgr) - 1);
|
tqPushDataRsp(pTq, pHandle);
|
||||||
|
|
||||||
if (rspConsumer) { // rsp the old consumer with empty block.
|
rpcFreeCont(pHandle->msg->pCont);
|
||||||
tqPushDataRsp(pTq, *pEntry);
|
taosMemoryFree(pHandle->msg);
|
||||||
}
|
pHandle->msg = NULL;
|
||||||
|
|
||||||
taosHashRemove(pTq->pPushMgr, pKey, keyLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordPushedEntry(SArray* cachedKey, void* pIter) {
|
|
||||||
size_t kLen = 0;
|
|
||||||
void* key = taosHashGetKey(pIter, &kLen);
|
|
||||||
SItem item = {.pKey = strndup(key, kLen), .keyLen = kLen};
|
|
||||||
taosArrayPush(cachedKey, &item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doRemovePushedEntry(SArray* pCachedKeys, STQ* pTq) {
|
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
|
||||||
int32_t numOfKeys = (int32_t)taosArrayGetSize(pCachedKeys);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfKeys; i++) {
|
|
||||||
SItem* pItem = taosArrayGet(pCachedKeys, i);
|
|
||||||
if (taosHashRemove(pTq->pPushMgr, pItem->pKey, pItem->keyLen) != 0) {
|
|
||||||
tqError("vgId:%d, tq push hash remove key error, key: %s", vgId, (char*)pItem->pKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numOfKeys > 0) {
|
|
||||||
tqDebug("vgId:%d, pushed %d items and remain:%d", vgId, numOfKeys, (int32_t)taosHashGetSize(pTq->pPushMgr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "tmsg.h"
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
|
|
||||||
bool isValValidForTable(STqHandle* pHandle, SWalCont* pHead) {
|
bool isValValidForTable(STqHandle* pHandle, SWalCont* pHead) {
|
||||||
|
@ -265,9 +266,9 @@ STqReader* tqReaderOpen(SVnode* pVnode) {
|
||||||
pReader->pColIdList = NULL;
|
pReader->pColIdList = NULL;
|
||||||
pReader->cachedSchemaVer = 0;
|
pReader->cachedSchemaVer = 0;
|
||||||
pReader->cachedSchemaSuid = 0;
|
pReader->cachedSchemaSuid = 0;
|
||||||
pReader->pSchema = NULL;
|
|
||||||
pReader->pSchemaWrapper = NULL;
|
pReader->pSchemaWrapper = NULL;
|
||||||
pReader->tbIdHash = NULL;
|
pReader->tbIdHash = NULL;
|
||||||
|
pReader->pResBlock = createDataBlock();
|
||||||
return pReader;
|
return pReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,19 +277,19 @@ void tqCloseReader(STqReader* pReader) {
|
||||||
if (pReader->pWalReader) {
|
if (pReader->pWalReader) {
|
||||||
walCloseReader(pReader->pWalReader);
|
walCloseReader(pReader->pWalReader);
|
||||||
}
|
}
|
||||||
// free cached schema
|
|
||||||
if (pReader->pSchema) {
|
|
||||||
taosMemoryFree(pReader->pSchema);
|
|
||||||
}
|
|
||||||
if (pReader->pSchemaWrapper) {
|
if (pReader->pSchemaWrapper) {
|
||||||
tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
|
tDeleteSchemaWrapper(pReader->pSchemaWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReader->pColIdList) {
|
if (pReader->pColIdList) {
|
||||||
taosArrayDestroy(pReader->pColIdList);
|
taosArrayDestroy(pReader->pColIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free hash
|
// free hash
|
||||||
|
blockDataDestroy(pReader->pResBlock);
|
||||||
taosHashCleanup(pReader->tbIdHash);
|
taosHashCleanup(pReader->tbIdHash);
|
||||||
tDestroySSubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
||||||
taosMemoryFree(pReader);
|
taosMemoryFree(pReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,58 +323,111 @@ int32_t extractSubmitMsgFromWal(SWalReader* pReader, SPackedData* pPackedData) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqNextBlock(STqReader* pReader, SSDataBlock* pBlock) {
|
// todo ignore the error in wal?
|
||||||
while (1) {
|
int32_t tqNextBlockInWal(STqReader* pReader) {
|
||||||
if (pReader->msg2.msgStr == NULL) {
|
SWalReader* pWalReader = pReader->pWalReader;
|
||||||
if (walNextValidMsg(pReader->pWalReader) < 0) {
|
|
||||||
|
while(1) {
|
||||||
|
SArray* pBlockList = pReader->submit.aSubmitTbData;
|
||||||
|
if (pBlockList == NULL || pReader->nextBlk >= taosArrayGetSize(pBlockList)) {
|
||||||
|
|
||||||
|
// try next message in wal file
|
||||||
|
// todo always retry to avoid read failure caused by wal file deletion
|
||||||
|
if (walNextValidMsg(pWalReader) < 0) {
|
||||||
return FETCH_TYPE__NONE;
|
return FETCH_TYPE__NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* pBody = POINTER_SHIFT(pReader->pWalReader->pHead->head.body, sizeof(SSubmitReq2Msg));
|
void* pBody = POINTER_SHIFT(pWalReader->pHead->head.body, sizeof(SSubmitReq2Msg));
|
||||||
int32_t bodyLen = pReader->pWalReader->pHead->head.bodyLen - sizeof(SSubmitReq2Msg);
|
int32_t bodyLen = pWalReader->pHead->head.bodyLen - sizeof(SSubmitReq2Msg);
|
||||||
int64_t ver = pReader->pWalReader->pHead->head.version;
|
int64_t ver = pWalReader->pHead->head.version;
|
||||||
|
|
||||||
tqReaderSetSubmitMsg(pReader, pBody, bodyLen, ver);
|
SDecoder decoder = {0};
|
||||||
}
|
tDecoderInit(&decoder, pBody, bodyLen);
|
||||||
|
|
||||||
while (tqNextBlockImpl(pReader)) {
|
{
|
||||||
memset(pBlock, 0, sizeof(SSDataBlock));
|
int32_t nSubmitTbData = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||||
int32_t code = tqRetrieveDataBlock(pBlock, pReader, NULL);
|
for (int32_t i = 0; i < nSubmitTbData; i++) {
|
||||||
if (code != TSDB_CODE_SUCCESS || pBlock->info.rows == 0) {
|
SSubmitTbData* pData = taosArrayGet(pReader->submit.aSubmitTbData, i);
|
||||||
continue;
|
if (pData->pCreateTbReq != NULL) {
|
||||||
|
taosArrayDestroy(pData->pCreateTbReq->ctb.tagName);
|
||||||
|
taosMemoryFreeClear(pData->pCreateTbReq);
|
||||||
|
}
|
||||||
|
pData->aRowP = taosArrayDestroy(pData->aRowP);
|
||||||
|
}
|
||||||
|
pReader->submit.aSubmitTbData = taosArrayDestroy(pReader->submit.aSubmitTbData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FETCH_TYPE__DATA;
|
if (tDecodeSubmitReq(&decoder, &pReader->submit) < 0) {
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
tqError("decode wal file error, msgLen:%d, ver:%"PRId64, bodyLen, ver);
|
||||||
|
return FETCH_TYPE__NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tDecoderClear(&decoder);
|
||||||
|
pReader->nextBlk = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t numOfBlocks = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||||
|
while (pReader->nextBlk < numOfBlocks) {
|
||||||
|
tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg.msgStr, pReader->msg.msgLen,
|
||||||
|
pReader->msg.ver, pReader->nextBlk);
|
||||||
|
|
||||||
|
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||||
|
|
||||||
|
if (pReader->tbIdHash == NULL) {
|
||||||
|
int32_t code = tqRetrieveDataBlock(pReader, NULL);
|
||||||
|
if (code == TSDB_CODE_SUCCESS && pReader->pResBlock->info.rows > 0) {
|
||||||
|
return FETCH_TYPE__DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
|
||||||
|
if (ret != NULL) {
|
||||||
|
tqDebug("tq reader return submit block, uid:%"PRId64", ver:%"PRId64, pSubmitTbData->uid, pReader->msg.ver);
|
||||||
|
|
||||||
|
int32_t code = tqRetrieveDataBlock(pReader, NULL);
|
||||||
|
if (code == TSDB_CODE_SUCCESS && pReader->pResBlock->info.rows > 0) {
|
||||||
|
return FETCH_TYPE__DATA;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pReader->nextBlk += 1;
|
||||||
|
tqDebug("tq reader discard submit block, uid:%"PRId64", continue", pSubmitTbData->uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
||||||
|
pReader->msg.msgStr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, int64_t ver) {
|
int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, int64_t ver) {
|
||||||
pReader->msg2.msgStr = msgStr;
|
pReader->msg.msgStr = msgStr;
|
||||||
pReader->msg2.msgLen = msgLen;
|
pReader->msg.msgLen = msgLen;
|
||||||
pReader->msg2.ver = ver;
|
pReader->msg.ver = ver;
|
||||||
|
|
||||||
tqDebug("tq reader set msg %p %d", msgStr, msgLen);
|
tqDebug("tq reader set msg %p %d", msgStr, msgLen);
|
||||||
SDecoder decoder;
|
SDecoder decoder;
|
||||||
tDecoderInit(&decoder, pReader->msg2.msgStr, pReader->msg2.msgLen);
|
|
||||||
if (tDecodeSSubmitReq2(&decoder, &pReader->submit) < 0) {
|
tDecoderInit(&decoder, pReader->msg.msgStr, pReader->msg.msgLen);
|
||||||
|
if (tDecodeSubmitReq(&decoder, &pReader->submit) < 0) {
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
tqError("DecodeSSubmitReq2 error, msgLen:%d, ver:%"PRId64, msgLen, ver);
|
tqError("DecodeSSubmitReq2 error, msgLen:%d, ver:%"PRId64, msgLen, ver);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tqNextBlockImpl(STqReader* pReader) {
|
bool tqNextBlockImpl(STqReader* pReader) {
|
||||||
if (pReader->msg2.msgStr == NULL) {
|
if (pReader->msg.msgStr == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||||
while (pReader->nextBlk < blockSz) {
|
while (pReader->nextBlk < blockSz) {
|
||||||
tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg2.msgStr, pReader->msg2.msgLen,
|
tqDebug("tq reader next data block %p, %d %" PRId64 " %d", pReader->msg.msgStr, pReader->msg.msgLen,
|
||||||
pReader->msg2.ver, pReader->nextBlk);
|
pReader->msg.ver, pReader->nextBlk);
|
||||||
|
|
||||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||||
if (pReader->tbIdHash == NULL) {
|
if (pReader->tbIdHash == NULL) {
|
||||||
|
@ -382,7 +436,7 @@ bool tqNextBlockImpl(STqReader* pReader) {
|
||||||
|
|
||||||
void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
|
void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t));
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
tqDebug("tq reader block found, ver:%"PRId64", uid:%"PRId64, pReader->msg2.ver, pSubmitTbData->uid);
|
tqDebug("tq reader block found, ver:%"PRId64", uid:%"PRId64, pReader->msg.ver, pSubmitTbData->uid);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
tqDebug("tq reader discard submit block, uid:%"PRId64", continue", pSubmitTbData->uid);
|
tqDebug("tq reader discard submit block, uid:%"PRId64", continue", pSubmitTbData->uid);
|
||||||
|
@ -391,15 +445,15 @@ bool tqNextBlockImpl(STqReader* pReader) {
|
||||||
pReader->nextBlk++;
|
pReader->nextBlk++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDestroySSubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
||||||
pReader->nextBlk = 0;
|
pReader->nextBlk = 0;
|
||||||
pReader->msg2.msgStr = NULL;
|
pReader->msg.msgStr = NULL;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) {
|
bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) {
|
||||||
if (pReader->msg2.msgStr == NULL) return false;
|
if (pReader->msg.msgStr == NULL) return false;
|
||||||
|
|
||||||
int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData);
|
||||||
while (pReader->nextBlk < blockSz) {
|
while (pReader->nextBlk < blockSz) {
|
||||||
|
@ -413,9 +467,9 @@ bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) {
|
||||||
pReader->nextBlk++;
|
pReader->nextBlk++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDestroySSubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE);
|
||||||
pReader->nextBlk = 0;
|
pReader->nextBlk = 0;
|
||||||
pReader->msg2.msgStr = NULL;
|
pReader->msg.msgStr = NULL;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -449,212 +503,219 @@ int32_t tqMaskBlock(SSchemaWrapper* pDst, SSDataBlock* pBlock, const SSchemaWrap
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqRetrieveDataBlock(SSDataBlock* pBlock, STqReader* pReader, SSubmitTbData** pSubmitTbDataRet) {
|
int32_t tqRetrieveDataBlock(STqReader* pReader, SSubmitTbData** pSubmitTbDataRet) {
|
||||||
tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg2.msgStr, pReader->nextBlk);
|
tqDebug("tq reader retrieve data block %p, index:%d", pReader->msg.msgStr, pReader->nextBlk);
|
||||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
|
||||||
pReader->nextBlk++;
|
|
||||||
|
|
||||||
|
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk++);
|
||||||
if (pSubmitTbDataRet) {
|
if (pSubmitTbDataRet) {
|
||||||
*pSubmitTbDataRet = pSubmitTbData;
|
*pSubmitTbDataRet = pSubmitTbData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSDataBlock* pBlock = pReader->pResBlock;
|
||||||
|
blockDataCleanup(pBlock);
|
||||||
|
|
||||||
int32_t sversion = pSubmitTbData->sver;
|
int32_t sversion = pSubmitTbData->sver;
|
||||||
int64_t suid = pSubmitTbData->suid;
|
int64_t suid = pSubmitTbData->suid;
|
||||||
int64_t uid = pSubmitTbData->uid;
|
int64_t uid = pSubmitTbData->uid;
|
||||||
pReader->lastBlkUid = uid;
|
pReader->lastBlkUid = uid;
|
||||||
|
|
||||||
pBlock->info.id.uid = uid;
|
pBlock->info.id.uid = uid;
|
||||||
pBlock->info.version = pReader->msg2.ver;
|
pBlock->info.version = pReader->msg.ver;
|
||||||
|
|
||||||
if (pReader->cachedSchemaSuid == 0 || pReader->cachedSchemaVer != sversion || pReader->cachedSchemaSuid != suid) {
|
if ((suid != 0 && pReader->cachedSchemaSuid != suid) || (suid == 0 && pReader->cachedSchemaUid != uid) || (pReader->cachedSchemaVer != sversion)) {
|
||||||
taosMemoryFree(pReader->pSchema);
|
tDeleteSchemaWrapper(pReader->pSchemaWrapper);
|
||||||
pReader->pSchema = metaGetTbTSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
|
||||||
if (pReader->pSchema == NULL) {
|
|
||||||
tqWarn("vgId:%d, cannot found tsschema for table: uid:%" PRId64 " (suid:%" PRId64
|
|
||||||
"), version %d, possibly dropped table",
|
|
||||||
pReader->pWalReader->pWal->cfg.vgId, uid, suid, sversion);
|
|
||||||
pReader->cachedSchemaSuid = 0;
|
|
||||||
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
|
|
||||||
pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
||||||
if (pReader->pSchemaWrapper == NULL) {
|
if (pReader->pSchemaWrapper == NULL) {
|
||||||
tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table",
|
tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", uid:%" PRId64 "version %d, possibly dropped table",
|
||||||
pReader->pWalReader->pWal->cfg.vgId, uid, pReader->cachedSchemaVer);
|
pReader->pWalReader->pWal->cfg.vgId, suid, uid, pReader->cachedSchemaVer);
|
||||||
pReader->cachedSchemaSuid = 0;
|
pReader->cachedSchemaSuid = 0;
|
||||||
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
|
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STSchema* pTschema = pReader->pSchema;
|
pReader->cachedSchemaUid = uid;
|
||||||
|
pReader->cachedSchemaSuid = suid;
|
||||||
|
pReader->cachedSchemaVer = sversion;
|
||||||
|
|
||||||
SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
|
SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
|
||||||
|
if (blockDataGetNumOfCols(pBlock) > 0) {
|
||||||
|
blockDataDestroy(pReader->pResBlock);
|
||||||
|
pReader->pResBlock = createDataBlock();
|
||||||
|
pBlock = pReader->pResBlock;
|
||||||
|
|
||||||
int32_t colNumNeed = taosArrayGetSize(pReader->pColIdList);
|
pBlock->info.id.uid = uid;
|
||||||
|
pBlock->info.version = pReader->msg.ver;
|
||||||
|
}
|
||||||
|
|
||||||
if (colNumNeed == 0) {
|
int32_t numOfCols = taosArrayGetSize(pReader->pColIdList);
|
||||||
int32_t colMeta = 0;
|
if (numOfCols == 0) { // all columns are required
|
||||||
while (colMeta < pSchemaWrapper->nCols) {
|
for (int32_t i = 0; i < pSchemaWrapper->nCols; ++i) {
|
||||||
SSchema* pColSchema = &pSchemaWrapper->pSchema[colMeta];
|
SSchema* pColSchema = &pSchemaWrapper->pSchema[i];
|
||||||
SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
|
SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
|
||||||
int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
|
|
||||||
|
int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto FAIL;
|
blockDataFreeRes(pBlock);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
colMeta++;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (colNumNeed > pSchemaWrapper->nCols) {
|
if (numOfCols > pSchemaWrapper->nCols) {
|
||||||
colNumNeed = pSchemaWrapper->nCols;
|
numOfCols = pSchemaWrapper->nCols;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t colMeta = 0;
|
int32_t i = 0;
|
||||||
int32_t colNeed = 0;
|
int32_t j = 0;
|
||||||
while (colMeta < pSchemaWrapper->nCols && colNeed < colNumNeed) {
|
while (i < pSchemaWrapper->nCols && j < numOfCols) {
|
||||||
SSchema* pColSchema = &pSchemaWrapper->pSchema[colMeta];
|
SSchema* pColSchema = &pSchemaWrapper->pSchema[i];
|
||||||
col_id_t colIdSchema = pColSchema->colId;
|
col_id_t colIdSchema = pColSchema->colId;
|
||||||
col_id_t colIdNeed = *(col_id_t*)taosArrayGet(pReader->pColIdList, colNeed);
|
|
||||||
|
col_id_t colIdNeed = *(col_id_t*)taosArrayGet(pReader->pColIdList, j);
|
||||||
if (colIdSchema < colIdNeed) {
|
if (colIdSchema < colIdNeed) {
|
||||||
colMeta++;
|
i++;
|
||||||
} else if (colIdSchema > colIdNeed) {
|
} else if (colIdSchema > colIdNeed) {
|
||||||
colNeed++;
|
j++;
|
||||||
} else {
|
} else {
|
||||||
SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
|
SColumnInfoData colInfo = createColumnInfoData(pColSchema->type, pColSchema->bytes, pColSchema->colId);
|
||||||
int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
|
int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
goto FAIL;
|
return -1;
|
||||||
}
|
}
|
||||||
colMeta++;
|
i++;
|
||||||
colNeed++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t numOfRows = 0;
|
int32_t numOfRows = 0;
|
||||||
|
if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
|
||||||
|
SColData* pCol = taosArrayGet(pSubmitTbData->aCol, 0);
|
||||||
|
numOfRows = pCol->nVal;
|
||||||
|
} else {
|
||||||
|
numOfRows = taosArrayGetSize(pSubmitTbData->aRowP);
|
||||||
|
}
|
||||||
|
|
||||||
if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
|
if (blockDataEnsureCapacity(pBlock, numOfRows) < 0) {
|
||||||
SArray* pCols = pSubmitTbData->aCol;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
SColData* pCol = taosArrayGet(pCols, 0);
|
return -1;
|
||||||
numOfRows = pCol->nVal;
|
}
|
||||||
} else {
|
|
||||||
SArray* pRows = pSubmitTbData->aRowP;
|
pBlock->info.rows = numOfRows;
|
||||||
numOfRows = taosArrayGetSize(pRows);
|
|
||||||
|
int32_t colActual = blockDataGetNumOfCols(pBlock);
|
||||||
|
|
||||||
|
// convert and scan one block
|
||||||
|
if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
|
||||||
|
SArray* pCols = pSubmitTbData->aCol;
|
||||||
|
int32_t numOfCols = taosArrayGetSize(pCols);
|
||||||
|
int32_t targetIdx = 0;
|
||||||
|
int32_t sourceIdx = 0;
|
||||||
|
while (targetIdx < colActual) {
|
||||||
|
if (sourceIdx >= numOfCols) {
|
||||||
|
tqError("tqRetrieveDataBlock sourceIdx:%d >= numOfCols:%d", sourceIdx, numOfCols);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SColData* pCol = taosArrayGet(pCols, sourceIdx);
|
||||||
|
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
|
||||||
|
SColVal colVal;
|
||||||
|
|
||||||
|
if (pCol->nVal != numOfRows) {
|
||||||
|
tqError("tqRetrieveDataBlock pCol->nVal:%d != numOfRows:%d", pCol->nVal, numOfRows);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCol->cid < pColData->info.colId) {
|
||||||
|
sourceIdx++;
|
||||||
|
} else if (pCol->cid == pColData->info.colId) {
|
||||||
|
for (int32_t i = 0; i < pCol->nVal; i++) {
|
||||||
|
tColDataGetValue(pCol, i, &colVal);
|
||||||
|
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||||
|
if (colVal.value.pData != NULL) {
|
||||||
|
char val[65535 + 2] = {0};
|
||||||
|
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||||
|
varDataSetLen(val, colVal.value.nData);
|
||||||
|
if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
colDataSetNULL(pColData, i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceIdx++;
|
||||||
|
targetIdx++;
|
||||||
|
} else {
|
||||||
|
for (int32_t i = 0; i < pCol->nVal; i++) {
|
||||||
|
colDataSetNULL(pColData, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
targetIdx++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SArray* pRows = pSubmitTbData->aRowP;
|
||||||
|
SSchemaWrapper* pWrapper = pReader->pSchemaWrapper;
|
||||||
|
STSchema* pTSchema = tBuildTSchema(pWrapper->pSchema, pWrapper->nCols, pWrapper->version);
|
||||||
|
|
||||||
if (blockDataEnsureCapacity(pBlock, numOfRows) < 0) {
|
for (int32_t i = 0; i < numOfRows; i++) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
SRow* pRow = taosArrayGetP(pRows, i);
|
||||||
goto FAIL;
|
|
||||||
}
|
|
||||||
pBlock->info.rows = numOfRows;
|
|
||||||
|
|
||||||
int32_t colActual = blockDataGetNumOfCols(pBlock);
|
|
||||||
|
|
||||||
// convert and scan one block
|
|
||||||
if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
|
|
||||||
SArray* pCols = pSubmitTbData->aCol;
|
|
||||||
int32_t numOfCols = taosArrayGetSize(pCols);
|
|
||||||
int32_t targetIdx = 0;
|
|
||||||
int32_t sourceIdx = 0;
|
int32_t sourceIdx = 0;
|
||||||
while (targetIdx < colActual) {
|
|
||||||
if(sourceIdx >= numOfCols){
|
|
||||||
tqError("tqRetrieveDataBlock sourceIdx:%d >= numOfCols:%d", sourceIdx, numOfCols);
|
|
||||||
goto FAIL;
|
|
||||||
}
|
|
||||||
SColData* pCol = taosArrayGet(pCols, sourceIdx);
|
|
||||||
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
|
|
||||||
SColVal colVal;
|
|
||||||
|
|
||||||
if(pCol->nVal != numOfRows){
|
for (int32_t j = 0; j < colActual; j++) {
|
||||||
tqError("tqRetrieveDataBlock pCol->nVal:%d != numOfRows:%d", pCol->nVal, numOfRows);
|
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j);
|
||||||
goto FAIL;
|
while (1) {
|
||||||
}
|
SColVal colVal;
|
||||||
|
tqDebug("start to extract column id:%d, index:%d", pColData->info.colId, sourceIdx);
|
||||||
|
|
||||||
if (pCol->cid < pColData->info.colId) {
|
tRowGet(pRow, pTSchema, sourceIdx, &colVal);
|
||||||
sourceIdx++;
|
if (colVal.cid < pColData->info.colId) {
|
||||||
} else if (pCol->cid == pColData->info.colId) {
|
tqDebug("colIndex:%d column id:%d in row, ignore, the required colId:%d, total cols in schema:%d",
|
||||||
for (int32_t i = 0; i < pCol->nVal; i++) {
|
sourceIdx, colVal.cid, pColData->info.colId, pTSchema->numOfCols);
|
||||||
tColDataGetValue(pCol, i, &colVal);
|
sourceIdx++;
|
||||||
|
continue;
|
||||||
|
} else if (colVal.cid == pColData->info.colId) {
|
||||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
if (IS_STR_DATA_TYPE(colVal.type)) {
|
||||||
if (colVal.value.pData != NULL) {
|
if (colVal.value.pData != NULL) {
|
||||||
char val[65535 + 2] = {0};
|
char val[65535 + 2] = {0};
|
||||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
||||||
varDataSetLen(val, colVal.value.nData);
|
varDataSetLen(val, colVal.value.nData);
|
||||||
if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||||
goto FAIL;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
colDataSetNULL(pColData, i);
|
colDataSetNULL(pColData, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
||||||
goto FAIL;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
sourceIdx++;
|
sourceIdx++;
|
||||||
targetIdx++;
|
break;
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 0; i < pCol->nVal; i++) {
|
|
||||||
colDataSetNULL(pColData, i);
|
colDataSetNULL(pColData, i);
|
||||||
}
|
break;
|
||||||
targetIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SArray* pRows = pSubmitTbData->aRowP;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfRows; i++) {
|
|
||||||
SRow* pRow = taosArrayGetP(pRows, i);
|
|
||||||
int32_t sourceIdx = 0;
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < colActual; j++) {
|
|
||||||
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, j);
|
|
||||||
while (1) {
|
|
||||||
SColVal colVal;
|
|
||||||
tRowGet(pRow, pTschema, sourceIdx, &colVal);
|
|
||||||
if (colVal.cid < pColData->info.colId) {
|
|
||||||
sourceIdx++;
|
|
||||||
continue;
|
|
||||||
} else if (colVal.cid == pColData->info.colId) {
|
|
||||||
if (IS_STR_DATA_TYPE(colVal.type)) {
|
|
||||||
if (colVal.value.pData != NULL) {
|
|
||||||
char val[65535 + 2] = {0};
|
|
||||||
memcpy(varDataVal(val), colVal.value.pData, colVal.value.nData);
|
|
||||||
varDataSetLen(val, colVal.value.nData);
|
|
||||||
if (colDataAppend(pColData, i, val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
|
||||||
goto FAIL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
colDataSetNULL(pColData, i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (colDataAppend(pColData, i, (void*)&colVal.value.val, !COL_VAL_IS_VALUE(&colVal)) < 0) {
|
|
||||||
goto FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceIdx++;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
colDataSetNULL(pColData, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosMemoryFreeClear(pTSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
FAIL:
|
|
||||||
blockDataFreeRes(pBlock);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet) {
|
int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet) {
|
||||||
tqDebug("tq reader retrieve data block %p, %d", pReader->msg2.msgStr, pReader->nextBlk);
|
tqDebug("tq reader retrieve data block %p, %d", pReader->msg.msgStr, pReader->nextBlk);
|
||||||
|
|
||||||
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk);
|
||||||
pReader->nextBlk++;
|
pReader->nextBlk++;
|
||||||
|
@ -665,18 +726,7 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
int64_t uid = pSubmitTbData->uid;
|
int64_t uid = pSubmitTbData->uid;
|
||||||
pReader->lastBlkUid = uid;
|
pReader->lastBlkUid = uid;
|
||||||
|
|
||||||
taosMemoryFree(pReader->pSchema);
|
tDeleteSchemaWrapper(pReader->pSchemaWrapper);
|
||||||
pReader->pSchema = metaGetTbTSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
|
||||||
if (pReader->pSchema == NULL) {
|
|
||||||
tqWarn("vgId:%d, cannot found tsschema for table: uid:%" PRId64 " (suid:%" PRId64
|
|
||||||
"), version %d, possibly dropped table",
|
|
||||||
pReader->pWalReader->pWal->cfg.vgId, uid, suid, sversion);
|
|
||||||
pReader->cachedSchemaSuid = 0;
|
|
||||||
terrno = TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tDeleteSSchemaWrapper(pReader->pSchemaWrapper);
|
|
||||||
pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1);
|
||||||
if (pReader->pSchemaWrapper == NULL) {
|
if (pReader->pSchemaWrapper == NULL) {
|
||||||
tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table",
|
tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table",
|
||||||
|
@ -686,7 +736,6 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STSchema* pTschema = pReader->pSchema;
|
|
||||||
SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
|
SSchemaWrapper* pSchemaWrapper = pReader->pSchemaWrapper;
|
||||||
int32_t numOfRows = 0;
|
int32_t numOfRows = 0;
|
||||||
|
|
||||||
|
@ -743,18 +792,18 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
|
|
||||||
if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
|
if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
|
||||||
blockDataFreeRes(&block);
|
blockDataFreeRes(&block);
|
||||||
tDeleteSSchemaWrapper(pSW);
|
tDeleteSchemaWrapper(pSW);
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
|
tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
|
||||||
(int32_t)taosArrayGetSize(block.pDataBlock));
|
(int32_t)taosArrayGetSize(block.pDataBlock));
|
||||||
|
|
||||||
block.info.id.uid = uid;
|
block.info.id.uid = uid;
|
||||||
block.info.version = pReader->msg2.ver;
|
block.info.version = pReader->msg.ver;
|
||||||
if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
|
if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
blockDataFreeRes(&block);
|
blockDataFreeRes(&block);
|
||||||
tDeleteSSchemaWrapper(pSW);
|
tDeleteSchemaWrapper(pSW);
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
taosArrayPush(blocks, &block);
|
taosArrayPush(blocks, &block);
|
||||||
|
@ -803,14 +852,17 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
curRow++;
|
curRow++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
SSchemaWrapper* pWrapper = pReader->pSchemaWrapper;
|
||||||
|
STSchema* pTSchema = tBuildTSchema(pWrapper->pSchema, pWrapper->nCols, pWrapper->version);
|
||||||
SArray* pRows = pSubmitTbData->aRowP;
|
SArray* pRows = pSubmitTbData->aRowP;
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfRows; i++) {
|
for (int32_t i = 0; i < numOfRows; i++) {
|
||||||
SRow* pRow = taosArrayGetP(pRows, i);
|
SRow* pRow = taosArrayGetP(pRows, i);
|
||||||
bool buildNew = false;
|
bool buildNew = false;
|
||||||
|
|
||||||
for (int32_t j = 0; j < pTschema->numOfCols; j++) {
|
for (int32_t j = 0; j < pTSchema->numOfCols; j++) {
|
||||||
SColVal colVal;
|
SColVal colVal;
|
||||||
tRowGet(pRow, pTschema, j, &colVal);
|
tRowGet(pRow, pTSchema, j, &colVal);
|
||||||
if (curRow == 0) {
|
if (curRow == 0) {
|
||||||
assigned[j] = !COL_VAL_IS_NONE(&colVal);
|
assigned[j] = !COL_VAL_IS_NONE(&colVal);
|
||||||
buildNew = true;
|
buildNew = true;
|
||||||
|
@ -839,18 +891,18 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
|
|
||||||
if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
|
if (tqMaskBlock(pSW, &block, pSchemaWrapper, assigned) < 0) {
|
||||||
blockDataFreeRes(&block);
|
blockDataFreeRes(&block);
|
||||||
tDeleteSSchemaWrapper(pSW);
|
tDeleteSchemaWrapper(pSW);
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
|
tqDebug("vgId:%d, build new block, col %d", pReader->pWalReader->pWal->cfg.vgId,
|
||||||
(int32_t)taosArrayGetSize(block.pDataBlock));
|
(int32_t)taosArrayGetSize(block.pDataBlock));
|
||||||
|
|
||||||
block.info.id.uid = uid;
|
block.info.id.uid = uid;
|
||||||
block.info.version = pReader->msg2.ver;
|
block.info.version = pReader->msg.ver;
|
||||||
if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
|
if (blockDataEnsureCapacity(&block, numOfRows - curRow) < 0) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
blockDataFreeRes(&block);
|
blockDataFreeRes(&block);
|
||||||
tDeleteSSchemaWrapper(pSW);
|
tDeleteSchemaWrapper(pSW);
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
taosArrayPush(blocks, &block);
|
taosArrayPush(blocks, &block);
|
||||||
|
@ -868,7 +920,7 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
while (targetIdx < colActual) {
|
while (targetIdx < colActual) {
|
||||||
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
|
SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, targetIdx);
|
||||||
SColVal colVal;
|
SColVal colVal;
|
||||||
tRowGet(pRow, pTschema, sourceIdx, &colVal);
|
tRowGet(pRow, pTSchema, sourceIdx, &colVal);
|
||||||
|
|
||||||
if (colVal.cid < pColData->info.colId) {
|
if (colVal.cid < pColData->info.colId) {
|
||||||
sourceIdx++;
|
sourceIdx++;
|
||||||
|
@ -895,6 +947,8 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas
|
||||||
}
|
}
|
||||||
curRow++;
|
curRow++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosMemoryFreeClear(pTSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSDataBlock* pLastBlock = taosArrayGetLast(blocks);
|
SSDataBlock* pLastBlock = taosArrayGetLast(blocks);
|
||||||
|
@ -1039,6 +1093,5 @@ int32_t tqUpdateTbUidList(STQ* pTq, const SArray* tbUidList, bool isAdd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,16 +18,15 @@
|
||||||
static int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle);
|
static int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle);
|
||||||
|
|
||||||
// this function should be executed by stream threads.
|
// this function should be executed by stream threads.
|
||||||
// there is a case that the WAL increases more fast than the restore procedure, and this restore procedure
|
// extract submit block from WAL, and add them into the input queue for the sources tasks.
|
||||||
// will not stop eventually.
|
|
||||||
int32_t tqStreamTasksScanWal(STQ* pTq) {
|
int32_t tqStreamTasksScanWal(STQ* pTq) {
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||||
int64_t st = taosGetTimestampMs();
|
int64_t st = taosGetTimestampMs();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int32_t scan = pMeta->walScan;
|
int32_t scan = pMeta->walScanCounter;
|
||||||
tqDebug("vgId:%d continue check if data in wal are available, scan:%d", vgId, scan);
|
tqDebug("vgId:%d continue check if data in wal are available, walScanCounter:%d", vgId, scan);
|
||||||
|
|
||||||
// check all restore tasks
|
// check all restore tasks
|
||||||
bool shouldIdle = true;
|
bool shouldIdle = true;
|
||||||
|
@ -37,12 +36,13 @@ int32_t tqStreamTasksScanWal(STQ* pTq) {
|
||||||
|
|
||||||
if (shouldIdle) {
|
if (shouldIdle) {
|
||||||
taosWLockLatch(&pMeta->lock);
|
taosWLockLatch(&pMeta->lock);
|
||||||
pMeta->walScan -= 1;
|
|
||||||
times = pMeta->walScan;
|
|
||||||
|
|
||||||
ASSERT(pMeta->walScan >= 0);
|
pMeta->walScanCounter -= 1;
|
||||||
|
times = pMeta->walScanCounter;
|
||||||
|
|
||||||
if (pMeta->walScan <= 0) {
|
ASSERT(pMeta->walScanCounter >= 0);
|
||||||
|
|
||||||
|
if (pMeta->walScanCounter <= 0) {
|
||||||
taosWUnLockLatch(&pMeta->lock);
|
taosWUnLockLatch(&pMeta->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -57,42 +57,28 @@ int32_t tqStreamTasksScanWal(STQ* pTq) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SArray* extractTaskIdList(SStreamMeta* pStreamMeta, int32_t numOfTasks) {
|
|
||||||
SArray* pTaskIdList = taosArrayInit(numOfTasks, sizeof(int32_t));
|
|
||||||
void* pIter = NULL;
|
|
||||||
|
|
||||||
taosWLockLatch(&pStreamMeta->lock);
|
|
||||||
while(1) {
|
|
||||||
pIter = taosHashIterate(pStreamMeta->pTasks, pIter);
|
|
||||||
if (pIter == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SStreamTask* pTask = *(SStreamTask**)pIter;
|
|
||||||
taosArrayPush(pTaskIdList, &pTask->id.taskId);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosWUnLockLatch(&pStreamMeta->lock);
|
|
||||||
return pTaskIdList;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
||||||
*pScanIdle = true;
|
*pScanIdle = true;
|
||||||
bool noNewDataInWal = true;
|
bool noNewDataInWal = true;
|
||||||
int32_t vgId = pStreamMeta->vgId;
|
int32_t vgId = pStreamMeta->vgId;
|
||||||
|
|
||||||
int32_t numOfTasks = taosHashGetSize(pStreamMeta->pTasks);
|
int32_t numOfTasks = taosArrayGetSize(pStreamMeta->pTaskList);
|
||||||
if (numOfTasks == 0) {
|
if (numOfTasks == 0) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SArray* pTaskList = NULL;
|
||||||
|
taosWLockLatch(&pStreamMeta->lock);
|
||||||
|
pTaskList = taosArrayDup(pStreamMeta->pTaskList, NULL);
|
||||||
|
taosWUnLockLatch(&pStreamMeta->lock);
|
||||||
|
|
||||||
tqDebug("vgId:%d start to check wal to extract new submit block for %d tasks", vgId, numOfTasks);
|
tqDebug("vgId:%d start to check wal to extract new submit block for %d tasks", vgId, numOfTasks);
|
||||||
SArray* pTaskIdList = extractTaskIdList(pStreamMeta, numOfTasks);
|
|
||||||
|
|
||||||
// update the new task number
|
// update the new task number
|
||||||
numOfTasks = taosArrayGetSize(pTaskIdList);
|
numOfTasks = taosArrayGetSize(pTaskList);
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfTasks; ++i) {
|
for (int32_t i = 0; i < numOfTasks; ++i) {
|
||||||
int32_t* pTaskId = taosArrayGet(pTaskIdList, i);
|
int32_t* pTaskId = taosArrayGet(pTaskList, i);
|
||||||
SStreamTask* pTask = streamMetaAcquireTask(pStreamMeta, *pTaskId);
|
SStreamTask* pTask = streamMetaAcquireTask(pStreamMeta, *pTaskId);
|
||||||
if (pTask == NULL) {
|
if (pTask == NULL) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -123,6 +109,15 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
||||||
// seek the stored version and extract data from WAL
|
// seek the stored version and extract data from WAL
|
||||||
int32_t code = walReadSeekVer(pTask->exec.pWalReader, pTask->chkInfo.currentVer);
|
int32_t code = walReadSeekVer(pTask->exec.pWalReader, pTask->chkInfo.currentVer);
|
||||||
if (code != TSDB_CODE_SUCCESS) { // no data in wal, quit
|
if (code != TSDB_CODE_SUCCESS) { // no data in wal, quit
|
||||||
|
SWal *pWal = pTask->exec.pWalReader->pWal;
|
||||||
|
if (pTask->chkInfo.currentVer < pWal->vers.firstVer ) {
|
||||||
|
pTask->chkInfo.currentVer = pWal->vers.firstVer;
|
||||||
|
code = walReadSeekVer(pTask->exec.pWalReader, pTask->chkInfo.currentVer);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
streamMetaReleaseTask(pStreamMeta, pTask);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
streamMetaReleaseTask(pStreamMeta, pTask);
|
streamMetaReleaseTask(pStreamMeta, pTask);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +161,7 @@ int32_t createStreamRunReq(SStreamMeta* pStreamMeta, bool* pScanIdle) {
|
||||||
*pScanIdle = true;
|
*pScanIdle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayDestroy(pTaskIdList);
|
taosArrayDestroy(pTaskList);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,10 @@ static int32_t tqAddTbNameToRsp(const STQ* pTq, int64_t uid, STaosxRsp* pRsp, in
|
||||||
|
|
||||||
int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset) {
|
int32_t tqScanData(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* pOffset) {
|
||||||
const int32_t MAX_ROWS_TO_RETURN = 4096;
|
const int32_t MAX_ROWS_TO_RETURN = 4096;
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
|
||||||
int32_t code = 0;
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
int32_t totalRows = 0;
|
int32_t code = 0;
|
||||||
|
int32_t totalRows = 0;
|
||||||
|
|
||||||
const STqExecHandle* pExec = &pHandle->execHandle;
|
const STqExecHandle* pExec = &pHandle->execHandle;
|
||||||
qTaskInfo_t task = pExec->task;
|
qTaskInfo_t task = pExec->task;
|
||||||
|
@ -215,7 +216,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR
|
||||||
int64_t uid = pExec->pTqReader->lastBlkUid;
|
int64_t uid = pExec->pTqReader->lastBlkUid;
|
||||||
if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
|
if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
|
||||||
taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
|
taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
|
||||||
taosArrayDestroyP(pSchemas, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper);
|
||||||
pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
|
pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
|
||||||
pSchemas = taosArrayInit(0, sizeof(void*));
|
pSchemas = taosArrayInit(0, sizeof(void*));
|
||||||
continue;
|
continue;
|
||||||
|
@ -274,7 +275,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxR
|
||||||
int64_t uid = pExec->pTqReader->lastBlkUid;
|
int64_t uid = pExec->pTqReader->lastBlkUid;
|
||||||
if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
|
if (tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)) < 0) {
|
||||||
taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
|
taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes);
|
||||||
taosArrayDestroyP(pSchemas, (FDelete)tDeleteSSchemaWrapper);
|
taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper);
|
||||||
pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
|
pBlocks = taosArrayInit(0, sizeof(SSDataBlock));
|
||||||
pSchemas = taosArrayInit(0, sizeof(void*));
|
pSchemas = taosArrayInit(0, sizeof(void*));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -672,7 +672,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
||||||
}
|
}
|
||||||
SRow* pRow = NULL;
|
SRow* pRow = NULL;
|
||||||
if ((terrno = tRowBuild(pVals, (STSchema*)pTSchema, &pRow)) < 0) {
|
if ((terrno = tRowBuild(pVals, (STSchema*)pTSchema, &pRow)) < 0) {
|
||||||
tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
ASSERT(pRow);
|
ASSERT(pRow);
|
||||||
|
@ -681,7 +681,7 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
||||||
|
|
||||||
SSubmitReq2 submitReq = {0};
|
SSubmitReq2 submitReq = {0};
|
||||||
if (!(submitReq.aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData)))) {
|
if (!(submitReq.aSubmitTbData = taosArrayInit(1, sizeof(SSubmitTbData)))) {
|
||||||
tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,28 +690,28 @@ void tqSinkToTablePipeline2(SStreamTask* pTask, void* vnode, int64_t ver, void*
|
||||||
// encode
|
// encode
|
||||||
int32_t len;
|
int32_t len;
|
||||||
int32_t code;
|
int32_t code;
|
||||||
tEncodeSize(tEncodeSSubmitReq2, &submitReq, len, code);
|
tEncodeSize(tEncodeSubmitReq, &submitReq, len, code);
|
||||||
SEncoder encoder;
|
SEncoder encoder;
|
||||||
len += sizeof(SSubmitReq2Msg);
|
len += sizeof(SSubmitReq2Msg);
|
||||||
pBuf = rpcMallocCont(len);
|
pBuf = rpcMallocCont(len);
|
||||||
if (NULL == pBuf) {
|
if (NULL == pBuf) {
|
||||||
tDestroySSubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
((SSubmitReq2Msg*)pBuf)->header.vgId = TD_VID(pVnode);
|
((SSubmitReq2Msg*)pBuf)->header.vgId = TD_VID(pVnode);
|
||||||
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
||||||
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
||||||
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
||||||
if (tEncodeSSubmitReq2(&encoder, &submitReq) < 0) {
|
if (tEncodeSubmitReq(&encoder, &submitReq) < 0) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
tqError("failed to encode submit req since %s", terrstr());
|
tqError("failed to encode submit req since %s", terrstr());
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
rpcFreeCont(pBuf);
|
rpcFreeCont(pBuf);
|
||||||
tDestroySSubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
tDestroySSubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(&submitReq, TSDB_MSG_FLG_ENCODE);
|
||||||
|
|
||||||
SRpcMsg msg = {
|
SRpcMsg msg = {
|
||||||
.msgType = TDMT_VND_SUBMIT,
|
.msgType = TDMT_VND_SUBMIT,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
|
|
||||||
#define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0)
|
#define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0)
|
||||||
|
#define NO_POLL_CNT 5
|
||||||
|
|
||||||
static int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp);
|
static int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp);
|
||||||
|
|
||||||
|
@ -165,25 +166,38 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
|
||||||
SRpcMsg* pMsg, STqOffsetVal* pOffset) {
|
SRpcMsg* pMsg, STqOffsetVal* pOffset) {
|
||||||
uint64_t consumerId = pRequest->consumerId;
|
uint64_t consumerId = pRequest->consumerId;
|
||||||
int32_t vgId = TD_VID(pTq->pVnode);
|
int32_t vgId = TD_VID(pTq->pVnode);
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
SMqDataRsp dataRsp = {0};
|
SMqDataRsp dataRsp = {0};
|
||||||
tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType);
|
tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType);
|
||||||
|
qTaskInfo_t task = pHandle->execHandle.task;
|
||||||
// lock
|
if(qTaskIsExecuting(task)){
|
||||||
taosWLockLatch(&pTq->lock);
|
code = tqSendDataRsp(pTq, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
||||||
|
tDeleteSMqDataRsp(&dataRsp);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId);
|
qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId);
|
||||||
int code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
|
code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
|
||||||
if(code != 0) {
|
if(code != 0) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// till now, all data has been transferred to consumer, new data needs to push client once arrived.
|
// till now, all data has been transferred to consumer, new data needs to push client once arrived.
|
||||||
if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
|
if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
|
||||||
dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
|
dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
|
||||||
code = tqRegisterPushHandle(pTq, pHandle, pRequest, pMsg, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
if(pHandle->noDataPollCnt >= NO_POLL_CNT){ // send poll result to client if no data 5 times to avoid lost data
|
||||||
taosWUnLockLatch(&pTq->lock);
|
pHandle->noDataPollCnt = 0;
|
||||||
return code;
|
// lock
|
||||||
|
taosWLockLatch(&pTq->lock);
|
||||||
|
code = tqRegisterPushHandle(pTq, pHandle, pMsg);
|
||||||
|
taosWUnLockLatch(&pTq->lock);
|
||||||
|
tDeleteSMqDataRsp(&dataRsp);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pHandle->noDataPollCnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,7 +211,7 @@ static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle,
|
||||||
tFormatOffset(buf, 80, &dataRsp.rspOffset);
|
tFormatOffset(buf, 80, &dataRsp.rspOffset);
|
||||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64 " code:%d",
|
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64 " code:%d",
|
||||||
consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
|
consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
|
||||||
taosWUnLockLatch(&pTq->lock);
|
// taosWUnLockLatch(&pTq->lock);
|
||||||
tDeleteSMqDataRsp(&dataRsp);
|
tDeleteSMqDataRsp(&dataRsp);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
|
@ -211,6 +225,12 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
||||||
SMqMetaRsp metaRsp = {0};
|
SMqMetaRsp metaRsp = {0};
|
||||||
STaosxRsp taosxRsp = {0};
|
STaosxRsp taosxRsp = {0};
|
||||||
tqInitTaosxRsp(&taosxRsp, pRequest);
|
tqInitTaosxRsp(&taosxRsp, pRequest);
|
||||||
|
qTaskInfo_t task = pHandle->execHandle.task;
|
||||||
|
if(qTaskIsExecuting(task)){
|
||||||
|
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||||
|
tDeleteSTaosxRsp(&taosxRsp);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset->type != TMQ_OFFSET__LOG) {
|
if (offset->type != TMQ_OFFSET__LOG) {
|
||||||
if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) {
|
if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) {
|
||||||
|
@ -240,6 +260,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
||||||
|
|
||||||
|
|
||||||
if (offset->type == TMQ_OFFSET__LOG) {
|
if (offset->type == TMQ_OFFSET__LOG) {
|
||||||
|
verifyOffset(pHandle->pWalReader, offset);
|
||||||
int64_t fetchVer = offset->version + 1;
|
int64_t fetchVer = offset->version + 1;
|
||||||
pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048);
|
pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048);
|
||||||
if (pCkHead == NULL) {
|
if (pCkHead == NULL) {
|
||||||
|
@ -355,11 +376,10 @@ int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequ
|
||||||
// this is a normal subscribe requirement
|
// this is a normal subscribe requirement
|
||||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||||
return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
|
return extractDataAndRspForNormalSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
|
||||||
|
} else { // todo handle the case where re-balance occurs.
|
||||||
|
// for taosx
|
||||||
|
return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo handle the case where re-balance occurs.
|
|
||||||
// for taosx
|
|
||||||
return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) {
|
int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) {
|
||||||
|
|
|
@ -21,10 +21,9 @@
|
||||||
#define getCurrentKeyInLastBlock(_r) ((_r)->currentKey)
|
#define getCurrentKeyInLastBlock(_r) ((_r)->currentKey)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
READER_STATUS_SUSPEND = 0x1,
|
READER_STATUS_SUSPEND = 0x1,
|
||||||
READER_STATUS_SHOULD_STOP = 0x2,
|
READER_STATUS_NORMAL = 0x2,
|
||||||
READER_STATUS_NORMAL = 0x3,
|
} EReaderStatus;
|
||||||
} EReaderExecStatus;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EXTERNAL_ROWS_PREV = 0x1,
|
EXTERNAL_ROWS_PREV = 0x1,
|
||||||
|
@ -184,6 +183,7 @@ typedef struct STsdbReaderAttr {
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
bool freeBlock;
|
bool freeBlock;
|
||||||
SVersionRange verRange;
|
SVersionRange verRange;
|
||||||
|
int16_t order;
|
||||||
} STsdbReaderAttr;
|
} STsdbReaderAttr;
|
||||||
|
|
||||||
typedef struct SResultBlockInfo {
|
typedef struct SResultBlockInfo {
|
||||||
|
@ -196,7 +196,8 @@ struct STsdbReader {
|
||||||
STsdb* pTsdb;
|
STsdb* pTsdb;
|
||||||
SVersionRange verRange;
|
SVersionRange verRange;
|
||||||
TdThreadMutex readerMutex;
|
TdThreadMutex readerMutex;
|
||||||
EReaderExecStatus flag;
|
EReaderStatus flag;
|
||||||
|
int32_t code;
|
||||||
uint64_t suid;
|
uint64_t suid;
|
||||||
int16_t order;
|
int16_t order;
|
||||||
EReadMode readMode;
|
EReadMode readMode;
|
||||||
|
@ -2995,9 +2996,9 @@ static int32_t moveToNextFile(STsdbReader* pReader, SBlockNumber* pBlockNum, SAr
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// only check here, since the iterate data in memory is very fast.
|
// only check here, since the iterate data in memory is very fast.
|
||||||
if (pReader->flag == READER_STATUS_SHOULD_STOP) {
|
if (pReader->code != TSDB_CODE_SUCCESS) {
|
||||||
tsdbWarn("tsdb reader is stopped ASAP, %s", pReader->idStr);
|
tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
|
||||||
return TSDB_CODE_SUCCESS;
|
return pReader->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasNext = false;
|
bool hasNext = false;
|
||||||
|
@ -3093,9 +3094,9 @@ static int32_t doLoadLastBlockSequentially(STsdbReader* pReader) {
|
||||||
SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
|
SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (pReader->flag == READER_STATUS_SHOULD_STOP) {
|
if (pReader->code != TSDB_CODE_SUCCESS) {
|
||||||
tsdbWarn("tsdb reader is stopped ASAP, %s", pReader->idStr);
|
tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
|
||||||
return TSDB_CODE_SUCCESS;
|
return pReader->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the last data block of current table
|
// load the last data block of current table
|
||||||
|
@ -3246,7 +3247,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return (pReader->code != TSDB_CODE_SUCCESS)? pReader->code:code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doSumFileBlockRows(STsdbReader* pReader, SDataFReader* pFileReader) {
|
static int32_t doSumFileBlockRows(STsdbReader* pReader, SDataFReader* pFileReader) {
|
||||||
|
@ -3395,6 +3396,11 @@ static int32_t buildBlockFromBufferSequentially(STsdbReader* pReader) {
|
||||||
STableUidList* pUidList = &pStatus->uidList;
|
STableUidList* pUidList = &pStatus->uidList;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
if (pReader->code != TSDB_CODE_SUCCESS) {
|
||||||
|
tsdbWarn("tsdb reader is stopped ASAP, code:%s, %s", strerror(pReader->code), pReader->idStr);
|
||||||
|
return pReader->code;
|
||||||
|
}
|
||||||
|
|
||||||
STableBlockScanInfo** pBlockScanInfo = pStatus->pTableIter;
|
STableBlockScanInfo** pBlockScanInfo = pStatus->pTableIter;
|
||||||
initMemDataIterator(*pBlockScanInfo, pReader);
|
initMemDataIterator(*pBlockScanInfo, pReader);
|
||||||
|
|
||||||
|
@ -3474,47 +3480,65 @@ static bool fileBlockPartiallyRead(SFileBlockDumpInfo* pDumpInfo, bool asc) {
|
||||||
((pDumpInfo->rowIndex > 0 && asc) || (pDumpInfo->rowIndex < (pDumpInfo->totalRows - 1) && (!asc)));
|
((pDumpInfo->rowIndex > 0 && asc) || (pDumpInfo->rowIndex < (pDumpInfo->totalRows - 1) && (!asc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TSDB_READ_RETURN = 0x1,
|
||||||
|
TSDB_READ_CONTINUE = 0x2,
|
||||||
|
} ERetrieveType;
|
||||||
|
|
||||||
|
static ERetrieveType doReadDataFromLastFiles(STsdbReader* pReader) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
|
||||||
|
SDataBlockIter* pBlockIter = &pReader->status.blockIter;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
terrno = 0;
|
||||||
|
|
||||||
|
code = doLoadLastBlockSequentially(pReader);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
terrno = code;
|
||||||
|
return TSDB_READ_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pResBlock->info.rows > 0) {
|
||||||
|
return TSDB_READ_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all data blocks are checked in this last block file, now let's try the next file
|
||||||
|
ASSERT(pReader->status.pTableIter == NULL);
|
||||||
|
code = initForFirstBlockInFile(pReader, pBlockIter);
|
||||||
|
|
||||||
|
// error happens or all the data files are completely checked
|
||||||
|
if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
|
||||||
|
terrno = code;
|
||||||
|
return TSDB_READ_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBlockIter->numOfBlocks > 0) { // there are data blocks existed.
|
||||||
|
return TSDB_READ_CONTINUE;
|
||||||
|
} else { // all blocks in data file are checked, let's check the data in last files
|
||||||
|
resetTableListIndex(&pReader->status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
bool asc = ASCENDING_TRAVERSE(pReader->order);
|
bool asc = ASCENDING_TRAVERSE(pReader->order);
|
||||||
|
|
||||||
SDataBlockIter* pBlockIter = &pReader->status.blockIter;
|
SDataBlockIter* pBlockIter = &pReader->status.blockIter;
|
||||||
|
SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
|
||||||
|
|
||||||
if (pBlockIter->numOfBlocks == 0) {
|
if (pBlockIter->numOfBlocks == 0) {
|
||||||
_begin:
|
// let's try to extract data from stt files.
|
||||||
code = doLoadLastBlockSequentially(pReader);
|
ERetrieveType type = doReadDataFromLastFiles(pReader);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (type == TSDB_READ_RETURN) {
|
||||||
return code;
|
return terrno;
|
||||||
}
|
|
||||||
|
|
||||||
if (pReader->resBlockInfo.pResBlock->info.rows > 0) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// all data blocks are checked in this last block file, now let's try the next file
|
|
||||||
if (pReader->status.pTableIter == NULL) {
|
|
||||||
code = initForFirstBlockInFile(pReader, pBlockIter);
|
|
||||||
|
|
||||||
// error happens or all the data files are completely checked
|
|
||||||
if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this file does not have data files, let's start check the last block file if exists
|
|
||||||
if (pBlockIter->numOfBlocks == 0) {
|
|
||||||
resetTableListIndex(&pReader->status);
|
|
||||||
goto _begin;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
code = doBuildDataBlock(pReader);
|
code = doBuildDataBlock(pReader);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS || pResBlock->info.rows > 0) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReader->resBlockInfo.pResBlock->info.rows > 0) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -3530,30 +3554,22 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
if (hasNext) { // check for the next block in the block accessed order list
|
if (hasNext) { // check for the next block in the block accessed order list
|
||||||
initBlockDumpInfo(pReader, pBlockIter);
|
initBlockDumpInfo(pReader, pBlockIter);
|
||||||
} else {
|
} else {
|
||||||
if (pReader->status.pCurrentFileset->nSttF > 0) {
|
// all data blocks in files are checked, let's check the data in last files.
|
||||||
// data blocks in current file are exhausted, let's try the next file now
|
ASSERT(pReader->status.pCurrentFileset->nSttF > 0);
|
||||||
SBlockData* pBlockData = &pReader->status.fileBlockData;
|
|
||||||
if (pBlockData->uid != 0) {
|
|
||||||
tBlockDataClear(pBlockData);
|
|
||||||
}
|
|
||||||
|
|
||||||
tBlockDataReset(pBlockData);
|
// data blocks in current file are exhausted, let's try the next file now
|
||||||
resetDataBlockIterator(pBlockIter, pReader->order);
|
SBlockData* pBlockData = &pReader->status.fileBlockData;
|
||||||
resetTableListIndex(&pReader->status);
|
if (pBlockData->uid != 0) {
|
||||||
goto _begin;
|
tBlockDataClear(pBlockData);
|
||||||
} else {
|
}
|
||||||
code = initForFirstBlockInFile(pReader, pBlockIter);
|
|
||||||
|
|
||||||
// error happens or all the data files are completely checked
|
tBlockDataReset(pBlockData);
|
||||||
if ((code != TSDB_CODE_SUCCESS) || (pReader->status.loadFromFile == false)) {
|
resetDataBlockIterator(pBlockIter, pReader->order);
|
||||||
return code;
|
resetTableListIndex(&pReader->status);
|
||||||
}
|
|
||||||
|
|
||||||
// this file does not have blocks, let's start check the last block file
|
ERetrieveType type = doReadDataFromLastFiles(pReader);
|
||||||
if (pBlockIter->numOfBlocks == 0) {
|
if (type == TSDB_READ_RETURN) {
|
||||||
resetTableListIndex(&pReader->status);
|
return terrno;
|
||||||
goto _begin;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3561,13 +3577,9 @@ static int32_t buildBlockFromFiles(STsdbReader* pReader) {
|
||||||
code = doBuildDataBlock(pReader);
|
code = doBuildDataBlock(pReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS || pResBlock->info.rows > 0) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReader->resBlockInfo.pResBlock->info.rows > 0) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4829,8 +4841,8 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
|
||||||
|
|
||||||
*hasNext = false;
|
*hasNext = false;
|
||||||
|
|
||||||
if (isEmptyQueryTimeWindow(&pReader->window) || pReader->step == EXTERNAL_ROWS_NEXT) {
|
if (isEmptyQueryTimeWindow(&pReader->window) || pReader->step == EXTERNAL_ROWS_NEXT || pReader->code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return (pReader->code != TSDB_CODE_SUCCESS)? pReader->code:code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SReaderStatus* pStatus = &pReader->status;
|
SReaderStatus* pStatus = &pReader->status;
|
||||||
|
@ -4839,7 +4851,11 @@ int32_t tsdbNextDataBlock(STsdbReader* pReader, bool* hasNext) {
|
||||||
qTrace("tsdb/read: %p, take read mutex, code: %d", pReader, code);
|
qTrace("tsdb/read: %p, take read mutex, code: %d", pReader, code);
|
||||||
|
|
||||||
if (pReader->flag == READER_STATUS_SUSPEND) {
|
if (pReader->flag == READER_STATUS_SUSPEND) {
|
||||||
tsdbReaderResume(pReader);
|
code = tsdbReaderResume(pReader);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tsdbReleaseReader(pReader);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pReader->innerReader[0] != NULL && pReader->step == 0) {
|
if (pReader->innerReader[0] != NULL && pReader->step == 0) {
|
||||||
|
@ -5112,11 +5128,17 @@ SSDataBlock* tsdbRetrieveDataBlock(STsdbReader* pReader, SArray* pIdList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
qTrace("tsdb/reader-reset: %p, take read mutex", pReader);
|
qTrace("tsdb/reader-reset: %p, take read mutex", pReader);
|
||||||
tsdbAcquireReader(pReader);
|
tsdbAcquireReader(pReader);
|
||||||
|
|
||||||
if (pReader->flag == READER_STATUS_SUSPEND) {
|
if (pReader->flag == READER_STATUS_SUSPEND) {
|
||||||
tsdbReaderResume(pReader);
|
code = tsdbReaderResume(pReader);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tsdbReleaseReader(pReader);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEmptyQueryTimeWindow(&pReader->window) || pReader->pReadSnap == NULL) {
|
if (isEmptyQueryTimeWindow(&pReader->window) || pReader->pReadSnap == NULL) {
|
||||||
|
@ -5151,8 +5173,6 @@ int32_t tsdbReaderReset(STsdbReader* pReader, SQueryTableDataCond* pCond) {
|
||||||
int64_t ts = asc ? pReader->window.skey - 1 : pReader->window.ekey + 1;
|
int64_t ts = asc ? pReader->window.skey - 1 : pReader->window.ekey + 1;
|
||||||
resetAllDataBlockScanInfo(pStatus->pTableMap, ts, step);
|
resetAllDataBlockScanInfo(pStatus->pTableMap, ts, step);
|
||||||
|
|
||||||
int32_t code = 0;
|
|
||||||
|
|
||||||
// no data in files, let's try buffer in memory
|
// no data in files, let's try buffer in memory
|
||||||
if (pStatus->fileIter.numOfFiles == 0) {
|
if (pStatus->fileIter.numOfFiles == 0) {
|
||||||
pStatus->loadFromFile = false;
|
pStatus->loadFromFile = false;
|
||||||
|
@ -5197,7 +5217,11 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa
|
||||||
// find the start data block in file
|
// find the start data block in file
|
||||||
tsdbAcquireReader(pReader);
|
tsdbAcquireReader(pReader);
|
||||||
if (pReader->flag == READER_STATUS_SUSPEND) {
|
if (pReader->flag == READER_STATUS_SUSPEND) {
|
||||||
tsdbReaderResume(pReader);
|
code = tsdbReaderResume(pReader);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tsdbReleaseReader(pReader);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SReaderStatus* pStatus = &pReader->status;
|
SReaderStatus* pStatus = &pReader->status;
|
||||||
|
|
||||||
|
@ -5265,12 +5289,17 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
int64_t rows = 0;
|
int64_t rows = 0;
|
||||||
|
|
||||||
SReaderStatus* pStatus = &pReader->status;
|
SReaderStatus* pStatus = &pReader->status;
|
||||||
tsdbAcquireReader(pReader);
|
tsdbAcquireReader(pReader);
|
||||||
if (pReader->flag == READER_STATUS_SUSPEND) {
|
if (pReader->flag == READER_STATUS_SUSPEND) {
|
||||||
tsdbReaderResume(pReader);
|
code = tsdbReaderResume(pReader);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tsdbReleaseReader(pReader);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t iter = 0;
|
int32_t iter = 0;
|
||||||
|
@ -5436,4 +5465,4 @@ void tsdbReaderSetId(STsdbReader* pReader, const char* idstr) {
|
||||||
pReader->idStr = taosStrdup(idstr);
|
pReader->idStr = taosStrdup(idstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tsdbReaderSetCloseFlag(STsdbReader* pReader) { pReader->flag = READER_STATUS_SHOULD_STOP; }
|
void tsdbReaderSetCloseFlag(STsdbReader* pReader) { pReader->code = TSDB_CODE_TSC_QUERY_CANCELLED; }
|
||||||
|
|
|
@ -448,7 +448,6 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
||||||
walApplyVer(pVnode->pWal, version);
|
walApplyVer(pVnode->pWal, version);
|
||||||
|
|
||||||
if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) {
|
if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) {
|
||||||
/*vInfo("vgId:%d, push msg end", pVnode->config.vgId);*/
|
|
||||||
vError("vgId:%d, failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno));
|
vError("vgId:%d, failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -487,11 +486,16 @@ int32_t vnodePreprocessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||||
|
|
||||||
int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||||
vTrace("message in vnode query queue is processing");
|
vTrace("message in vnode query queue is processing");
|
||||||
if ((pMsg->msgType == TDMT_SCH_QUERY) && !syncIsReadyForRead(pVnode->sync)) {
|
if ((pMsg->msgType == TDMT_SCH_QUERY || pMsg->msgType == TDMT_VND_TMQ_CONSUME) && !syncIsReadyForRead(pVnode->sync)) {
|
||||||
vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
|
vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pMsg->msgType == TDMT_VND_TMQ_CONSUME && !pVnode->restored) {
|
||||||
|
vnodeRedirectRpcMsg(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SReadHandle handle = {.meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode, .pMsgCb = &pVnode->msgCb};
|
SReadHandle handle = {.meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode, .pMsgCb = &pVnode->msgCb};
|
||||||
switch (pMsg->msgType) {
|
switch (pMsg->msgType) {
|
||||||
case TDMT_SCH_QUERY:
|
case TDMT_SCH_QUERY:
|
||||||
|
@ -499,6 +503,8 @@ int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||||
return qWorkerProcessQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
|
return qWorkerProcessQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
|
||||||
case TDMT_SCH_QUERY_CONTINUE:
|
case TDMT_SCH_QUERY_CONTINUE:
|
||||||
return qWorkerProcessCQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
|
return qWorkerProcessCQueryMsg(&handle, pVnode->pQuery, pMsg, 0);
|
||||||
|
case TDMT_VND_TMQ_CONSUME:
|
||||||
|
return tqProcessPollReq(pVnode->pTq, pMsg);
|
||||||
default:
|
default:
|
||||||
vError("unknown msg type:%d in query queue", pMsg->msgType);
|
vError("unknown msg type:%d in query queue", pMsg->msgType);
|
||||||
return TSDB_CODE_APP_ERROR;
|
return TSDB_CODE_APP_ERROR;
|
||||||
|
@ -508,17 +514,12 @@ int32_t vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||||
int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
|
int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
|
||||||
vTrace("vgId:%d, msg:%p in fetch queue is processing", pVnode->config.vgId, pMsg);
|
vTrace("vgId:%d, msg:%p in fetch queue is processing", pVnode->config.vgId, pMsg);
|
||||||
if ((pMsg->msgType == TDMT_SCH_FETCH || pMsg->msgType == TDMT_VND_TABLE_META || pMsg->msgType == TDMT_VND_TABLE_CFG ||
|
if ((pMsg->msgType == TDMT_SCH_FETCH || pMsg->msgType == TDMT_VND_TABLE_META || pMsg->msgType == TDMT_VND_TABLE_CFG ||
|
||||||
pMsg->msgType == TDMT_VND_BATCH_META || pMsg->msgType == TDMT_VND_TMQ_CONSUME) &&
|
pMsg->msgType == TDMT_VND_BATCH_META) &&
|
||||||
!syncIsReadyForRead(pVnode->sync)) {
|
!syncIsReadyForRead(pVnode->sync)) {
|
||||||
vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
|
vnodeRedirectRpcMsg(pVnode, pMsg, terrno);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMsg->msgType == TDMT_VND_TMQ_CONSUME && !pVnode->restored) {
|
|
||||||
vnodeRedirectRpcMsg(pVnode, pMsg, TSDB_CODE_SYN_RESTORING);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (pMsg->msgType) {
|
switch (pMsg->msgType) {
|
||||||
case TDMT_SCH_FETCH:
|
case TDMT_SCH_FETCH:
|
||||||
case TDMT_SCH_MERGE_FETCH:
|
case TDMT_SCH_MERGE_FETCH:
|
||||||
|
@ -537,8 +538,6 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
|
||||||
return vnodeGetTableCfg(pVnode, pMsg, true);
|
return vnodeGetTableCfg(pVnode, pMsg, true);
|
||||||
case TDMT_VND_BATCH_META:
|
case TDMT_VND_BATCH_META:
|
||||||
return vnodeGetBatchMeta(pVnode, pMsg);
|
return vnodeGetBatchMeta(pVnode, pMsg);
|
||||||
case TDMT_VND_TMQ_CONSUME:
|
|
||||||
return tqProcessPollReq(pVnode->pTq, pMsg);
|
|
||||||
case TDMT_STREAM_TASK_RUN:
|
case TDMT_STREAM_TASK_RUN:
|
||||||
return tqProcessTaskRunReq(pVnode->pTq, pMsg);
|
return tqProcessTaskRunReq(pVnode->pTq, pMsg);
|
||||||
case TDMT_STREAM_TASK_DISPATCH:
|
case TDMT_STREAM_TASK_DISPATCH:
|
||||||
|
@ -1007,7 +1006,7 @@ static int32_t vnodeResetTableCxt(SMeta *pMeta, SSubmitReqConvertCxt *pCxt) {
|
||||||
}
|
}
|
||||||
tdSTSRowIterInit(&pCxt->rowIter, pCxt->pTbSchema);
|
tdSTSRowIterInit(&pCxt->rowIter, pCxt->pTbSchema);
|
||||||
|
|
||||||
tDestroySSubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
|
||||||
if (NULL == pCxt->pTbData) {
|
if (NULL == pCxt->pTbData) {
|
||||||
pCxt->pTbData = taosMemoryCalloc(1, sizeof(SSubmitTbData));
|
pCxt->pTbData = taosMemoryCalloc(1, sizeof(SSubmitTbData));
|
||||||
if (NULL == pCxt->pTbData) {
|
if (NULL == pCxt->pTbData) {
|
||||||
|
@ -1039,7 +1038,7 @@ static int32_t vnodeResetTableCxt(SMeta *pMeta, SSubmitReqConvertCxt *pCxt) {
|
||||||
|
|
||||||
static void vnodeDestroySubmitReqConvertCxt(SSubmitReqConvertCxt *pCxt) {
|
static void vnodeDestroySubmitReqConvertCxt(SSubmitReqConvertCxt *pCxt) {
|
||||||
taosMemoryFreeClear(pCxt->pTbSchema);
|
taosMemoryFreeClear(pCxt->pTbSchema);
|
||||||
tDestroySSubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(pCxt->pTbData, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFreeClear(pCxt->pTbData);
|
taosMemoryFreeClear(pCxt->pTbData);
|
||||||
taosArrayDestroy(pCxt->pColValues);
|
taosArrayDestroy(pCxt->pColValues);
|
||||||
}
|
}
|
||||||
|
@ -1149,7 +1148,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
char *pMsg = NULL;
|
char *pMsg = NULL;
|
||||||
uint32_t msglen = 0;
|
uint32_t msglen = 0;
|
||||||
tEncodeSize(tEncodeSSubmitReq2, pSubmitReq, msglen, code);
|
tEncodeSize(tEncodeSubmitReq, pSubmitReq, msglen, code);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pMsg = taosMemoryMalloc(msglen);
|
pMsg = taosMemoryMalloc(msglen);
|
||||||
if (NULL == pMsg) {
|
if (NULL == pMsg) {
|
||||||
|
@ -1159,7 +1158,7 @@ static int32_t vnodeRebuildSubmitReqMsg(SSubmitReq2 *pSubmitReq, void **ppMsg) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SEncoder encoder;
|
SEncoder encoder;
|
||||||
tEncoderInit(&encoder, pMsg, msglen);
|
tEncoderInit(&encoder, pMsg, msglen);
|
||||||
code = tEncodeSSubmitReq2(&encoder, pSubmitReq);
|
code = tEncodeSubmitReq(&encoder, pSubmitReq);
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -1199,7 +1198,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq
|
||||||
len -= sizeof(SSubmitReq2Msg);
|
len -= sizeof(SSubmitReq2Msg);
|
||||||
SDecoder dc = {0};
|
SDecoder dc = {0};
|
||||||
tDecoderInit(&dc, pReq, len);
|
tDecoderInit(&dc, pReq, len);
|
||||||
if (tDecodeSSubmitReq2(&dc, pSubmitReq) < 0) {
|
if (tDecodeSubmitReq(&dc, pSubmitReq) < 0) {
|
||||||
code = TSDB_CODE_INVALID_MSG;
|
code = TSDB_CODE_INVALID_MSG;
|
||||||
goto _exit;
|
goto _exit;
|
||||||
}
|
}
|
||||||
|
@ -1388,7 +1387,7 @@ _exit:
|
||||||
|
|
||||||
// clear
|
// clear
|
||||||
taosArrayDestroy(newTbUids);
|
taosArrayDestroy(newTbUids);
|
||||||
tDestroySSubmitReq(pSubmitReq, 0 == pMsg->version ? TSDB_MSG_FLG_CMPT : TSDB_MSG_FLG_DECODE);
|
tDestroySubmitReq(pSubmitReq, 0 == pMsg->version ? TSDB_MSG_FLG_CMPT : TSDB_MSG_FLG_DECODE);
|
||||||
tDestroySSubmitRsp2(pSubmitRsp, TSDB_MSG_FLG_ENCODE);
|
tDestroySSubmitRsp2(pSubmitRsp, TSDB_MSG_FLG_ENCODE);
|
||||||
|
|
||||||
if (code) terrno = code;
|
if (code) terrno = code;
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct {
|
||||||
STqOffsetVal currentOffset; // for tmq
|
STqOffsetVal currentOffset; // for tmq
|
||||||
SMqMetaRsp metaRsp; // for tmq fetching meta
|
SMqMetaRsp metaRsp; // for tmq fetching meta
|
||||||
int64_t snapshotVer;
|
int64_t snapshotVer;
|
||||||
SPackedData submit; // todo remove it
|
// SPackedData submit; // todo remove it
|
||||||
SSchemaWrapper* schema;
|
SSchemaWrapper* schema;
|
||||||
char tbName[TSDB_TABLE_NAME_LEN]; // this is the current scan table: todo refactor
|
char tbName[TSDB_TABLE_NAME_LEN]; // this is the current scan table: todo refactor
|
||||||
int8_t recoverStep;
|
int8_t recoverStep;
|
||||||
|
|
|
@ -126,7 +126,7 @@ static int32_t submitReqToMsg(int32_t vgId, SSubmitReq2* pReq, void** pData, int
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
int32_t len = 0;
|
int32_t len = 0;
|
||||||
void* pBuf = NULL;
|
void* pBuf = NULL;
|
||||||
tEncodeSize(tEncodeSSubmitReq2, pReq, len, code);
|
tEncodeSize(tEncodeSubmitReq, pReq, len, code);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SEncoder encoder;
|
SEncoder encoder;
|
||||||
len += sizeof(SSubmitReq2Msg);
|
len += sizeof(SSubmitReq2Msg);
|
||||||
|
@ -138,7 +138,7 @@ static int32_t submitReqToMsg(int32_t vgId, SSubmitReq2* pReq, void** pData, int
|
||||||
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
||||||
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
||||||
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
||||||
code = tEncodeSSubmitReq2(&encoder, pReq);
|
code = tEncodeSubmitReq(&encoder, pReq);
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp
|
||||||
|
|
||||||
SRow* pRow = NULL;
|
SRow* pRow = NULL;
|
||||||
if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
|
if ((terrno = tRowBuild(pVals, pTSchema, &pRow)) < 0) {
|
||||||
tDestroySSubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(&tbData, TSDB_MSG_FLG_ENCODE);
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
taosArrayPush(tbData.aRowP, &pRow);
|
taosArrayPush(tbData.aRowP, &pRow);
|
||||||
|
@ -301,7 +301,7 @@ _end:
|
||||||
if (terrno != 0) {
|
if (terrno != 0) {
|
||||||
*ppReq = NULL;
|
*ppReq = NULL;
|
||||||
if (pReq) {
|
if (pReq) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
}
|
}
|
||||||
return terrno;
|
return terrno;
|
||||||
|
@ -326,7 +326,7 @@ int32_t dataBlocksToSubmitReq(SDataInserterHandle* pInserter, void** pMsg, int32
|
||||||
code = buildSubmitReqFromBlock(pInserter, &pReq, pDataBlock, pTSchema, uid, vgId, suid);
|
code = buildSubmitReqFromBlock(pInserter, &pReq, pDataBlock, pTSchema, uid, vgId, suid);
|
||||||
if (code) {
|
if (code) {
|
||||||
if (pReq) {
|
if (pReq) {
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ int32_t dataBlocksToSubmitReq(SDataInserterHandle* pInserter, void** pMsg, int32
|
||||||
}
|
}
|
||||||
|
|
||||||
code = submitReqToMsg(vgId, pReq, pMsg, msgLen);
|
code = submitReqToMsg(vgId, pReq, pMsg, msgLen);
|
||||||
tDestroySSubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pReq, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pReq);
|
taosMemoryFree(pReq);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
|
@ -1052,25 +1052,20 @@ int32_t initQueryTableDataCondForTmq(SQueryTableDataCond* pCond, SSnapContext* s
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qStreamSetScanMemData(qTaskInfo_t tinfo, SPackedData submit) {
|
|
||||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
|
||||||
if ((pTaskInfo->execModel != OPTR_EXEC_MODEL_QUEUE) || (pTaskInfo->streamInfo.submit.msgStr != NULL)) {
|
|
||||||
qError("qStreamSetScanMemData err:%d,%p", pTaskInfo->execModel, pTaskInfo->streamInfo.submit.msgStr);
|
|
||||||
terrno = TSDB_CODE_PAR_INTERNAL_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
qDebug("set the submit block for future scan");
|
|
||||||
|
|
||||||
pTaskInfo->streamInfo.submit = submit;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void qStreamSetOpen(qTaskInfo_t tinfo) {
|
void qStreamSetOpen(qTaskInfo_t tinfo) {
|
||||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||||
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
||||||
pOperator->status = OP_NOT_OPENED;
|
pOperator->status = OP_NOT_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void verifyOffset(void *pWalReader, STqOffsetVal* pOffset){
|
||||||
|
// if offset version is small than first version , let's seek to first version
|
||||||
|
int64_t firstVer = walGetFirstVer(((SWalReader*)pWalReader)->pWal);
|
||||||
|
if (pOffset->version + 1 < firstVer){
|
||||||
|
pOffset->version = firstVer - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType) {
|
int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subType) {
|
||||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||||
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
SOperatorInfo* pOperator = pTaskInfo->pRoot;
|
||||||
|
@ -1086,21 +1081,18 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
||||||
if (pOperator == NULL) {
|
if (pOperator == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStreamScanInfo* pInfo = pOperator->info;
|
SStreamScanInfo* pInfo = pOperator->info;
|
||||||
STableScanInfo* pScanInfo = pInfo->pTableScanOp->info;
|
STableScanInfo* pScanInfo = pInfo->pTableScanOp->info;
|
||||||
STableScanBase* pScanBaseInfo = &pScanInfo->base;
|
STableScanBase* pScanBaseInfo = &pScanInfo->base;
|
||||||
STableListInfo* pTableListInfo = pScanBaseInfo->pTableListInfo;
|
STableListInfo* pTableListInfo = pScanBaseInfo->pTableListInfo;
|
||||||
|
|
||||||
if (pOffset->type == TMQ_OFFSET__LOG) {
|
if (pOffset->type == TMQ_OFFSET__LOG) {
|
||||||
|
// todo refactor: move away
|
||||||
tsdbReaderClose(pScanBaseInfo->dataReader);
|
tsdbReaderClose(pScanBaseInfo->dataReader);
|
||||||
pScanBaseInfo->dataReader = NULL;
|
pScanBaseInfo->dataReader = NULL;
|
||||||
|
|
||||||
// let's seek to the next version in wal file
|
verifyOffset(pInfo->tqReader->pWalReader, pOffset);
|
||||||
int64_t firstVer = walGetFirstVer(pInfo->tqReader->pWalReader->pWal);
|
|
||||||
if (pOffset->version + 1 < firstVer){
|
|
||||||
pOffset->version = firstVer - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tqSeekVer(pInfo->tqReader, pOffset->version + 1, id) < 0) {
|
if (tqSeekVer(pInfo->tqReader, pOffset->version + 1, id) < 0) {
|
||||||
qError("tqSeekVer failed ver:%" PRId64 ", %s", pOffset->version + 1, id);
|
qError("tqSeekVer failed ver:%" PRId64 ", %s", pOffset->version + 1, id);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1221,7 +1213,7 @@ int32_t qStreamPrepareScan(qTaskInfo_t tinfo, STqOffsetVal* pOffset, int8_t subT
|
||||||
|
|
||||||
cleanupQueryTableDataCond(&pTaskInfo->streamInfo.tableCond);
|
cleanupQueryTableDataCond(&pTaskInfo->streamInfo.tableCond);
|
||||||
strcpy(pTaskInfo->streamInfo.tbName, mtInfo.tbName);
|
strcpy(pTaskInfo->streamInfo.tbName, mtInfo.tbName);
|
||||||
tDeleteSSchemaWrapper(pTaskInfo->streamInfo.schema);
|
tDeleteSchemaWrapper(pTaskInfo->streamInfo.schema);
|
||||||
pTaskInfo->streamInfo.schema = mtInfo.schema;
|
pTaskInfo->streamInfo.schema = mtInfo.schema;
|
||||||
|
|
||||||
qDebug("tmqsnap qStreamPrepareScan snapshot data uid:%" PRId64 " ts %" PRId64 " %s", mtInfo.uid, pOffset->ts, id);
|
qDebug("tmqsnap qStreamPrepareScan snapshot data uid:%" PRId64 " ts %" PRId64 " %s", mtInfo.uid, pOffset->ts, id);
|
||||||
|
|
|
@ -82,7 +82,7 @@ static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SC
|
||||||
static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t order, int32_t scanFlag,
|
static int32_t doSetInputDataBlock(SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t order, int32_t scanFlag,
|
||||||
bool createDummyCol);
|
bool createDummyCol);
|
||||||
static int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
static int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
||||||
SGroupResInfo* pGroupResInfo);
|
SGroupResInfo* pGroupResInfo, int32_t threshold);
|
||||||
|
|
||||||
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize) {
|
SResultRow* getNewResultRow(SDiskbasedBuf* pResultBuf, int32_t* currentPageId, int32_t interBufSize) {
|
||||||
SFilePage* pData = NULL;
|
SFilePage* pData = NULL;
|
||||||
|
@ -776,7 +776,7 @@ int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPos
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprSupp* pSup, SDiskbasedBuf* pBuf,
|
||||||
SGroupResInfo* pGroupResInfo) {
|
SGroupResInfo* pGroupResInfo, int32_t threshold) {
|
||||||
SExprInfo* pExprInfo = pSup->pExprInfo;
|
SExprInfo* pExprInfo = pSup->pExprInfo;
|
||||||
int32_t numOfExprs = pSup->numOfExprs;
|
int32_t numOfExprs = pSup->numOfExprs;
|
||||||
int32_t* rowEntryOffset = pSup->rowEntryInfoOffset;
|
int32_t* rowEntryOffset = pSup->rowEntryInfoOffset;
|
||||||
|
@ -825,6 +825,9 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprS
|
||||||
|
|
||||||
releaseBufPage(pBuf, page);
|
releaseBufPage(pBuf, page);
|
||||||
pBlock->info.rows += pRow->numOfRows;
|
pBlock->info.rows += pRow->numOfRows;
|
||||||
|
if (pBlock->info.rows >= threshold) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("%s result generated, rows:%" PRId64 ", groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
qDebug("%s result generated, rows:%" PRId64 ", groupId:%" PRIu64, GET_TASKID(pTaskInfo), pBlock->info.rows,
|
||||||
|
@ -850,7 +853,7 @@ void doBuildStreamResBlock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGr
|
||||||
// clear the existed group id
|
// clear the existed group id
|
||||||
pBlock->info.id.groupId = 0;
|
pBlock->info.id.groupId = 0;
|
||||||
ASSERT(!pbInfo->mergeResultBlock);
|
ASSERT(!pbInfo->mergeResultBlock);
|
||||||
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
|
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
|
||||||
|
|
||||||
void* tbname = NULL;
|
void* tbname = NULL;
|
||||||
if (streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) {
|
if (streamStateGetParName(pTaskInfo->streamInfo.pState, pBlock->info.id.groupId, &tbname) < 0) {
|
||||||
|
@ -877,10 +880,10 @@ void doBuildResultDatablock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SG
|
||||||
// clear the existed group id
|
// clear the existed group id
|
||||||
pBlock->info.id.groupId = 0;
|
pBlock->info.id.groupId = 0;
|
||||||
if (!pbInfo->mergeResultBlock) {
|
if (!pbInfo->mergeResultBlock) {
|
||||||
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
|
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
|
||||||
} else {
|
} else {
|
||||||
while (hasRemainResults(pGroupResInfo)) {
|
while (hasRemainResults(pGroupResInfo)) {
|
||||||
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo);
|
doCopyToSDataBlock(pTaskInfo, pBlock, &pOperator->exprSupp, pBuf, pGroupResInfo, pOperator->resultInfo.threshold);
|
||||||
if (pBlock->info.rows >= pOperator->resultInfo.threshold) {
|
if (pBlock->info.rows >= pOperator->resultInfo.threshold) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,8 +109,8 @@ int32_t createExecTaskInfo(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHand
|
||||||
void cleanupQueriedTableScanInfo(SSchemaInfo* pSchemaInfo) {
|
void cleanupQueriedTableScanInfo(SSchemaInfo* pSchemaInfo) {
|
||||||
taosMemoryFreeClear(pSchemaInfo->dbname);
|
taosMemoryFreeClear(pSchemaInfo->dbname);
|
||||||
taosMemoryFreeClear(pSchemaInfo->tablename);
|
taosMemoryFreeClear(pSchemaInfo->tablename);
|
||||||
tDeleteSSchemaWrapper(pSchemaInfo->sw);
|
tDeleteSchemaWrapper(pSchemaInfo->sw);
|
||||||
tDeleteSSchemaWrapper(pSchemaInfo->qsw);
|
tDeleteSchemaWrapper(pSchemaInfo->qsw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, const char* dbName, SExecTaskInfo* pTaskInfo) {
|
int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNode, const char* dbName, SExecTaskInfo* pTaskInfo) {
|
||||||
|
@ -197,7 +197,7 @@ SSchemaWrapper* extractQueriedColumnSchema(SScanPhysiNode* pScanNode) {
|
||||||
return pqSw;
|
return pqSw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSSchemaWrapper(pStreamInfo->schema); }
|
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSchemaWrapper(pStreamInfo->schema); }
|
||||||
|
|
||||||
static void freeBlock(void* pParam) {
|
static void freeBlock(void* pParam) {
|
||||||
SSDataBlock* pBlock = *(SSDataBlock**)pParam;
|
SSDataBlock* pBlock = *(SSDataBlock**)pParam;
|
||||||
|
|
|
@ -1623,7 +1623,7 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock
|
||||||
|
|
||||||
pInfo->pRes->info.dataLoad = 1;
|
pInfo->pRes->info.dataLoad = 1;
|
||||||
blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
|
blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex);
|
||||||
blockDataFreeRes((SSDataBlock*)pBlock);
|
// blockDataFreeRes((SSDataBlock*)pBlock);
|
||||||
|
|
||||||
calBlockTbName(pInfo, pInfo->pRes);
|
calBlockTbName(pInfo, pInfo->pRes);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1636,8 +1636,9 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
|
||||||
|
|
||||||
qDebug("start to exec queue scan, %s", id);
|
qDebug("start to exec queue scan, %s", id);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (pTaskInfo->streamInfo.submit.msgStr != NULL) {
|
if (pTaskInfo->streamInfo.submit.msgStr != NULL) {
|
||||||
if (pInfo->tqReader->msg2.msgStr == NULL) {
|
if (pInfo->tqReader->msg.msgStr == NULL) {
|
||||||
SPackedData submit = pTaskInfo->streamInfo.submit;
|
SPackedData submit = pTaskInfo->streamInfo.submit;
|
||||||
if (tqReaderSetSubmitMsg(pInfo->tqReader, submit.msgStr, submit.msgLen, submit.ver) < 0) {
|
if (tqReaderSetSubmitMsg(pInfo->tqReader, submit.msgStr, submit.msgLen, submit.ver) < 0) {
|
||||||
qError("submit msg messed up when initing stream submit block %p", submit.msgStr);
|
qError("submit msg messed up when initing stream submit block %p", submit.msgStr);
|
||||||
|
@ -1649,24 +1650,23 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
|
||||||
SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
|
SDataBlockInfo* pBlockInfo = &pInfo->pRes->info;
|
||||||
|
|
||||||
while (tqNextBlockImpl(pInfo->tqReader)) {
|
while (tqNextBlockImpl(pInfo->tqReader)) {
|
||||||
SSDataBlock block = {0};
|
int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL);
|
||||||
|
if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) {
|
||||||
int32_t code = tqRetrieveDataBlock(&block, pInfo->tqReader, NULL);
|
|
||||||
if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setBlockIntoRes(pInfo, &block, true);
|
setBlockIntoRes(pInfo, pInfo->tqReader->pResBlock, true);
|
||||||
|
|
||||||
if (pBlockInfo->rows > 0) {
|
if (pBlockInfo->rows > 0) {
|
||||||
return pInfo->pRes;
|
return pInfo->pRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->tqReader->msg2 = (SPackedData){0};
|
pInfo->tqReader->msg = (SPackedData){0};
|
||||||
pTaskInfo->streamInfo.submit = (SPackedData){0};
|
pTaskInfo->streamInfo.submit = (SPackedData){0};
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_DATA) {
|
||||||
SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
|
SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp);
|
||||||
|
@ -1684,25 +1684,25 @@ static SSDataBlock* doQueueScan(SOperatorInfo* pOperator) {
|
||||||
if (tqSeekVer(pInfo->tqReader, pTaskInfo->streamInfo.snapshotVer + 1, pTaskInfo->id.str) < 0) {
|
if (tqSeekVer(pInfo->tqReader, pTaskInfo->streamInfo.snapshotVer + 1, pTaskInfo->id.str) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pTaskInfo->streamInfo.snapshotVer);
|
tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pTaskInfo->streamInfo.snapshotVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__LOG) {
|
if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__LOG) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
SSDataBlock block = {0};
|
int32_t type = tqNextBlockInWal(pInfo->tqReader);
|
||||||
int32_t type = tqNextBlock(pInfo->tqReader, &block);
|
SSDataBlock* pRes = pInfo->tqReader->pResBlock;
|
||||||
|
|
||||||
// curVersion move to next, so currentOffset = curVersion - 1
|
// curVersion move to next, so currentOffset = curVersion - 1
|
||||||
tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pInfo->tqReader->pWalReader->curVersion - 1);
|
tqOffsetResetToLog(&pTaskInfo->streamInfo.currentOffset, pInfo->tqReader->pWalReader->curVersion - 1);
|
||||||
|
|
||||||
if (type == FETCH_TYPE__DATA) {
|
if (type == FETCH_TYPE__DATA) {
|
||||||
qDebug("doQueueScan get data from log %" PRId64 " rows, version:%" PRId64, block.info.rows,
|
qDebug("doQueueScan get data from log %" PRId64 " rows, version:%" PRId64, pRes->info.rows,
|
||||||
pTaskInfo->streamInfo.currentOffset.version);
|
pTaskInfo->streamInfo.currentOffset.version);
|
||||||
blockDataCleanup(pInfo->pRes);
|
blockDataCleanup(pInfo->pRes);
|
||||||
setBlockIntoRes(pInfo, &block, true);
|
setBlockIntoRes(pInfo, pRes, true);
|
||||||
if (pInfo->pRes->info.rows > 0) {
|
if (pInfo->pRes->info.rows > 0) {
|
||||||
qDebug("doQueueScan get data from log %" PRId64 " rows, return, version:%" PRId64, pInfo->pRes->info.rows,
|
|
||||||
pTaskInfo->streamInfo.currentOffset.version);
|
|
||||||
return pInfo->pRes;
|
return pInfo->pRes;
|
||||||
}
|
}
|
||||||
} else if (type == FETCH_TYPE__NONE) {
|
} else if (type == FETCH_TYPE__NONE) {
|
||||||
|
@ -2055,7 +2055,7 @@ FETCH_NEXT_BLOCK:
|
||||||
|
|
||||||
NEXT_SUBMIT_BLK:
|
NEXT_SUBMIT_BLK:
|
||||||
while (1) {
|
while (1) {
|
||||||
if (pInfo->tqReader->msg2.msgStr == NULL) {
|
if (pInfo->tqReader->msg.msgStr == NULL) {
|
||||||
if (pInfo->validBlockIndex >= totBlockNum) {
|
if (pInfo->validBlockIndex >= totBlockNum) {
|
||||||
updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
|
updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
|
||||||
doClearBufferedBlocks(pInfo);
|
doClearBufferedBlocks(pInfo);
|
||||||
|
@ -2075,14 +2075,12 @@ FETCH_NEXT_BLOCK:
|
||||||
blockDataCleanup(pInfo->pRes);
|
blockDataCleanup(pInfo->pRes);
|
||||||
|
|
||||||
while (tqNextBlockImpl(pInfo->tqReader)) {
|
while (tqNextBlockImpl(pInfo->tqReader)) {
|
||||||
SSDataBlock block = {0};
|
int32_t code = tqRetrieveDataBlock(pInfo->tqReader, NULL);
|
||||||
|
if (code != TSDB_CODE_SUCCESS || pInfo->tqReader->pResBlock->info.rows == 0) {
|
||||||
int32_t code = tqRetrieveDataBlock(&block, pInfo->tqReader, NULL);
|
|
||||||
if (code != TSDB_CODE_SUCCESS || block.info.rows == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
setBlockIntoRes(pInfo, &block, false);
|
setBlockIntoRes(pInfo, pInfo->tqReader->pResBlock, false);
|
||||||
|
|
||||||
if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.id.groupId,
|
if (updateInfoIgnore(pInfo->pUpdateInfo, &pInfo->pRes->info.window, pInfo->pRes->info.id.groupId,
|
||||||
pInfo->pRes->info.version)) {
|
pInfo->pRes->info.version)) {
|
||||||
|
@ -2115,7 +2113,6 @@ FETCH_NEXT_BLOCK:
|
||||||
// record the scan action.
|
// record the scan action.
|
||||||
pInfo->numOfExec++;
|
pInfo->numOfExec++;
|
||||||
pOperator->resultInfo.totalRows += pBlockInfo->rows;
|
pOperator->resultInfo.totalRows += pBlockInfo->rows;
|
||||||
// printDataBlock(pInfo->pRes, "stream scan");
|
|
||||||
|
|
||||||
qDebug("scan rows: %" PRId64, pBlockInfo->rows);
|
qDebug("scan rows: %" PRId64, pBlockInfo->rows);
|
||||||
if (pBlockInfo->rows > 0) {
|
if (pBlockInfo->rows > 0) {
|
||||||
|
@ -2191,7 +2188,7 @@ static SSDataBlock* doRawScan(SOperatorInfo* pOperator) {
|
||||||
qDebug("tmqsnap change get data uid:%" PRId64 "", mtInfo.uid);
|
qDebug("tmqsnap change get data uid:%" PRId64 "", mtInfo.uid);
|
||||||
}
|
}
|
||||||
qStreamPrepareScan(pTaskInfo, &offset, pInfo->sContext->subType);
|
qStreamPrepareScan(pTaskInfo, &offset, pInfo->sContext->subType);
|
||||||
tDeleteSSchemaWrapper(mtInfo.schema);
|
tDeleteSchemaWrapper(mtInfo.schema);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
} else if (pTaskInfo->streamInfo.currentOffset.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||||
SSnapContext* sContext = pInfo->sContext;
|
SSnapContext* sContext = pInfo->sContext;
|
||||||
|
|
|
@ -5572,7 +5572,7 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t len = sprintf(st + VARSTR_HEADER_SIZE,
|
int32_t len = sprintf(st + VARSTR_HEADER_SIZE,
|
||||||
"Total_Blocks=[%d] Total_Size=[%.2f Kb] Average_size=[%.2f Kb] Compression_Ratio=[%.2f %c]",
|
"Total_Blocks=[%d] Total_Size=[%.2f KB] Average_size=[%.2f KB] Compression_Ratio=[%.2f %c]",
|
||||||
pData->numOfBlocks, pData->totalSize / 1024.0, averageSize / 1024.0, compRatio, '%');
|
pData->numOfBlocks, pData->totalSize / 1024.0, averageSize / 1024.0, compRatio, '%');
|
||||||
|
|
||||||
varDataSetLen(st, len);
|
varDataSetLen(st, len);
|
||||||
|
|
|
@ -313,7 +313,7 @@ void insDestroyTableDataCxt(STableDataCxt* pTableCxt) {
|
||||||
insDestroyBoundColInfo(&pTableCxt->boundColsInfo);
|
insDestroyBoundColInfo(&pTableCxt->boundColsInfo);
|
||||||
taosArrayDestroyEx(pTableCxt->pValues, destroyColVal);
|
taosArrayDestroyEx(pTableCxt->pValues, destroyColVal);
|
||||||
if (pTableCxt->pData) {
|
if (pTableCxt->pData) {
|
||||||
tDestroySSubmitTbData(pTableCxt->pData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitTbData(pTableCxt->pData, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pTableCxt->pData);
|
taosMemoryFree(pTableCxt->pData);
|
||||||
}
|
}
|
||||||
taosMemoryFree(pTableCxt);
|
taosMemoryFree(pTableCxt);
|
||||||
|
@ -324,7 +324,7 @@ void insDestroyVgroupDataCxt(SVgroupDataCxt* pVgCxt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDestroySSubmitReq(pVgCxt->pData, TSDB_MSG_FLG_ENCODE);
|
tDestroySubmitReq(pVgCxt->pData, TSDB_MSG_FLG_ENCODE);
|
||||||
taosMemoryFree(pVgCxt->pData);
|
taosMemoryFree(pVgCxt->pData);
|
||||||
taosMemoryFree(pVgCxt);
|
taosMemoryFree(pVgCxt);
|
||||||
}
|
}
|
||||||
|
@ -499,7 +499,7 @@ static int32_t buildSubmitReq(int32_t vgId, SSubmitReq2* pReq, void** pData, uin
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
void* pBuf = NULL;
|
void* pBuf = NULL;
|
||||||
tEncodeSize(tEncodeSSubmitReq2, pReq, len, code);
|
tEncodeSize(tEncodeSubmitReq, pReq, len, code);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SEncoder encoder;
|
SEncoder encoder;
|
||||||
len += sizeof(SSubmitReq2Msg);
|
len += sizeof(SSubmitReq2Msg);
|
||||||
|
@ -511,7 +511,7 @@ static int32_t buildSubmitReq(int32_t vgId, SSubmitReq2* pReq, void** pData, uin
|
||||||
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
((SSubmitReq2Msg*)pBuf)->header.contLen = htonl(len);
|
||||||
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
((SSubmitReq2Msg*)pBuf)->version = htobe64(1);
|
||||||
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
tEncoderInit(&encoder, POINTER_SHIFT(pBuf, sizeof(SSubmitReq2Msg)), len - sizeof(SSubmitReq2Msg));
|
||||||
code = tEncodeSSubmitReq2(&encoder, pReq);
|
code = tEncodeSubmitReq(&encoder, pReq);
|
||||||
tEncoderClear(&encoder);
|
tEncoderClear(&encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6118,17 +6118,50 @@ static bool isEventWindowQuery(SSelectStmt* pSelect) {
|
||||||
return NULL != pSelect->pWindow && QUERY_NODE_EVENT_WINDOW == nodeType(pSelect->pWindow);
|
return NULL != pSelect->pWindow && QUERY_NODE_EVENT_WINDOW == nodeType(pSelect->pWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasJsonTypeProjection(SSelectStmt* pSelect) {
|
||||||
|
SNode* pProj = NULL;
|
||||||
|
FOREACH(pProj, pSelect->pProjectionList) {
|
||||||
|
if (TSDB_DATA_TYPE_JSON == ((SExprNode*)pProj)->resType.type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EDealRes hasColumnOrPseudoColumn(SNode* pNode, void* pContext) {
|
||||||
|
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
|
*(bool*)pContext = true;
|
||||||
|
return DEAL_RES_END;
|
||||||
|
}
|
||||||
|
if (QUERY_NODE_FUNCTION == nodeType(pNode) && fmIsPseudoColumnFunc(((SFunctionNode*)pNode)->funcId)) {
|
||||||
|
*(bool*)pContext = true;
|
||||||
|
return DEAL_RES_END;
|
||||||
|
}
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t subtableExprHasColumnOrPseudoColumn(SNode* pNode) {
|
||||||
|
bool hasColumn = false;
|
||||||
|
nodesWalkExprPostOrder(pNode, hasColumnOrPseudoColumn, &hasColumn);
|
||||||
|
return hasColumn;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
|
static int32_t checkStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
|
||||||
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
|
||||||
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
|
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
|
||||||
!pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
|
!pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
|
||||||
crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect)) {
|
crossTableWithUdaf(pSelect) || isEventWindowQuery(pSelect) || hasJsonTypeProjection(pSelect)) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
|
||||||
}
|
}
|
||||||
if (NULL != pSelect->pSubtable && TSDB_DATA_TYPE_VARCHAR != ((SExprNode*)pSelect->pSubtable)->resType.type) {
|
if (NULL != pSelect->pSubtable && TSDB_DATA_TYPE_VARCHAR != ((SExprNode*)pSelect->pSubtable)->resType.type) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||||
"SUBTABLE expression must be of VARCHAR type");
|
"SUBTABLE expression must be of VARCHAR type");
|
||||||
}
|
}
|
||||||
|
if (NULL != pSelect->pSubtable && 0 == LIST_LENGTH(pSelect->pPartitionByList) && subtableExprHasColumnOrPseudoColumn(pSelect->pSubtable)) {
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||||
|
"SUBTABLE expression must not has column when no partition by clause");
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == pSelect->pWindow && STREAM_TRIGGER_AT_ONCE != pStmt->pOptions->triggerType) {
|
if (NULL == pSelect->pWindow && STREAM_TRIGGER_AT_ONCE != pStmt->pOptions->triggerType) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY,
|
||||||
"The trigger mode of non window query can only be AT_ONCE");
|
"The trigger mode of non window query can only be AT_ONCE");
|
||||||
|
@ -6666,22 +6699,40 @@ static int32_t createRealTableForGrantTable(SGrantStmt* pStmt, SRealTableNode**
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, SAlterUserReq* pReq) {
|
static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, SAlterUserReq* pReq) {
|
||||||
if (NULL == pStmt->pTagCond) {
|
SRealTableNode* pTable = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
if ('\0' == pStmt->tabName[0] || '*' == pStmt->tabName[0]) {
|
if ('\0' == pStmt->tabName[0] || '*' == pStmt->tabName[0]) {
|
||||||
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
|
if (pStmt->pTagCond) {
|
||||||
"The With clause can only be used for table level privilege");
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
|
||||||
|
"The With clause can only be used for table level privilege");
|
||||||
|
} else {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pCxt->pCurrStmt = (SNode*)pStmt;
|
|
||||||
SRealTableNode* pTable = NULL;
|
|
||||||
int32_t code = createRealTableForGrantTable(pStmt, &pTable);
|
int32_t code = createRealTableForGrantTable(pStmt, &pTable);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SName name;
|
SName name;
|
||||||
code = getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pTable->table.dbName, pTable->table.tableName, &name),
|
code = getTableMetaImpl(pCxt, toName(pCxt->pParseCxt->acctId, pTable->table.dbName, pTable->table.tableName, &name),
|
||||||
&(pTable->pMeta));
|
&(pTable->pMeta));
|
||||||
|
if (code) {
|
||||||
|
nodesDestroyNode((SNode*)pTable);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_SUPER_TABLE != pTable->pMeta->tableType && TSDB_NORMAL_TABLE != pTable->pMeta->tableType) {
|
||||||
|
nodesDestroyNode((SNode*)pTable);
|
||||||
|
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR,
|
||||||
|
"Only supertable and normal table can be granted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL == pStmt->pTagCond) {
|
||||||
|
nodesDestroyNode((SNode*)pTable);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCxt->pCurrStmt = (SNode*)pStmt;
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = addNamespace(pCxt, pTable);
|
code = addNamespace(pCxt, pTable);
|
||||||
}
|
}
|
||||||
|
@ -8214,6 +8265,11 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_DUPLICATED_COLUMN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((TSDB_DATA_TYPE_VARCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_BINARY_LEN) ||
|
||||||
|
(TSDB_DATA_TYPE_NCHAR == pStmt->dataType.type && calcTypeBytes(pStmt->dataType) > TSDB_MAX_NCHAR_LEN)) {
|
||||||
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
if (TSDB_MAX_COLUMNS == pTableMeta->tableInfo.numOfColumns) {
|
if (TSDB_MAX_COLUMNS == pTableMeta->tableInfo.numOfColumns) {
|
||||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
|
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -920,6 +920,10 @@ TEST_F(ParserInitialCTest, createStreamSemanticCheck) {
|
||||||
|
|
||||||
run("CREATE STREAM s1 INTO st1 AS SELECT PERCENTILE(c1, 30) FROM t1 INTERVAL(10S)",
|
run("CREATE STREAM s1 INTO st1 AS SELECT PERCENTILE(c1, 30) FROM t1 INTERVAL(10S)",
|
||||||
TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC);
|
TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC);
|
||||||
|
run("CREATE STREAM s2 INTO st1 AS SELECT ts, to_json('{c1:1}') FROM st1 PARTITION BY TBNAME",
|
||||||
|
TSDB_CODE_PAR_INVALID_STREAM_QUERY);
|
||||||
|
run("CREATE STREAM s3 INTO st3 TAGS(tname VARCHAR(10), id INT) SUBTABLE(CONCAT('new-', tbname)) "
|
||||||
|
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 INTERVAL(10S)", TSDB_CODE_PAR_INVALID_STREAM_QUERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
#add_subdirectory(filter)
|
add_subdirectory(filter)
|
||||||
add_subdirectory(scalar)
|
add_subdirectory(scalar)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "filterInt.h"
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
#include "scalar.h"
|
#include "scalar.h"
|
||||||
#include "stub.h"
|
#include "stub.h"
|
||||||
|
@ -344,6 +345,7 @@ TEST(timerangeTest, greater_and_lower_not_strict) {
|
||||||
nodesDestroyNode(logicNode1);
|
nodesDestroyNode(logicNode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
TEST(columnTest, smallint_column_greater_double_value) {
|
TEST(columnTest, smallint_column_greater_double_value) {
|
||||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||||
int16_t leftv[5] = {1, 2, 3, 4, 5};
|
int16_t leftv[5] = {1, 2, 3, 4, 5};
|
||||||
|
@ -1337,6 +1339,127 @@ TEST(scalarModelogicTest, diff_columns_or_and_or) {
|
||||||
nodesDestroyNode(logicNode1);
|
nodesDestroyNode(logicNode1);
|
||||||
blockDataDestroy(src);
|
blockDataDestroy(src);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class SignedT, class UnsignedT>
|
||||||
|
int32_t compareSignedWithUnsigned(SignedT l, UnsignedT r) {
|
||||||
|
if (l < 0) return -1;
|
||||||
|
auto l_uint64 = static_cast<uint64_t>(l);
|
||||||
|
auto r_uint64 = static_cast<uint64_t>(r);
|
||||||
|
if (l_uint64 < r_uint64) return -1;
|
||||||
|
if (l_uint64 > r_uint64) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class UnsignedT, class SignedT>
|
||||||
|
int32_t compareUnsignedWithSigned(UnsignedT l, SignedT r) {
|
||||||
|
if (r < 0) return 1;
|
||||||
|
auto l_uint64 = static_cast<uint64_t>(l);
|
||||||
|
auto r_uint64 = static_cast<uint64_t>(r);
|
||||||
|
if (l_uint64 < r_uint64) return -1;
|
||||||
|
if (l_uint64 > r_uint64) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class SignedT, class UnsignedT>
|
||||||
|
void doCompareWithValueRange_SignedWithUnsigned(__compar_fn_t fp) {
|
||||||
|
int32_t signedMin = -10, signedMax = 10;
|
||||||
|
int32_t unsignedMin = 0, unsignedMax = 10;
|
||||||
|
for (SignedT l = signedMin; l <= signedMax; ++l) {
|
||||||
|
for (UnsignedT r = unsignedMin; r <= unsignedMax; ++r) {
|
||||||
|
ASSERT_EQ(fp(&l, &r), compareSignedWithUnsigned(l, r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class UnsignedT, class SignedT>
|
||||||
|
void doCompareWithValueRange_UnsignedWithSigned(__compar_fn_t fp) {
|
||||||
|
int32_t signedMin = -10, signedMax = 10;
|
||||||
|
int32_t unsignedMin = 0, unsignedMax = 10;
|
||||||
|
for (UnsignedT l = unsignedMin; l <= unsignedMax; ++l) {
|
||||||
|
for (SignedT r = signedMin; r <= signedMax; ++r) {
|
||||||
|
ASSERT_EQ(fp(&l, &r), compareUnsignedWithSigned(l, r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class LType>
|
||||||
|
void doCompareWithValueRange_OnlyLeftType(__compar_fn_t fp, int32_t rType) {
|
||||||
|
switch (rType) {
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
doCompareWithValueRange_SignedWithUnsigned<LType, uint8_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
doCompareWithValueRange_SignedWithUnsigned<LType, uint16_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
doCompareWithValueRange_SignedWithUnsigned<LType, uint32_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
doCompareWithValueRange_SignedWithUnsigned<LType, uint64_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
doCompareWithValueRange_UnsignedWithSigned<LType, int8_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
doCompareWithValueRange_UnsignedWithSigned<LType, int16_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
doCompareWithValueRange_UnsignedWithSigned<LType, int32_t>(fp);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
doCompareWithValueRange_UnsignedWithSigned<LType, int64_t>(fp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doCompare(const std::vector<int32_t> &lTypes, const std::vector<int32_t> &rTypes, int32_t oper) {
|
||||||
|
for (int i = 0; i < lTypes.size(); ++i) {
|
||||||
|
for (int j = 0; j < rTypes.size(); ++j) {
|
||||||
|
auto fp = filterGetCompFuncEx(lTypes[i], rTypes[j], oper);
|
||||||
|
switch (lTypes[i]) {
|
||||||
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<int8_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<int16_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_INT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<int32_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<int64_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<uint8_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<uint16_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<uint32_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
doCompareWithValueRange_OnlyLeftType<uint64_t>(fp, rTypes[j]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(dataCompareTest, signed_and_unsigned_int) {
|
||||||
|
std::vector<int32_t> lType = {TSDB_DATA_TYPE_TINYINT, TSDB_DATA_TYPE_SMALLINT, TSDB_DATA_TYPE_INT,
|
||||||
|
TSDB_DATA_TYPE_BIGINT};
|
||||||
|
std::vector<int32_t> rType = {TSDB_DATA_TYPE_UTINYINT, TSDB_DATA_TYPE_USMALLINT, TSDB_DATA_TYPE_UINT,
|
||||||
|
TSDB_DATA_TYPE_UBIGINT};
|
||||||
|
|
||||||
|
doCompare(lType, rType, OP_TYPE_GREATER_THAN);
|
||||||
|
doCompare(rType, lType, OP_TYPE_GREATER_THAN);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
taosSeedRand(taosGetTimestampSec());
|
taosSeedRand(taosGetTimestampSec());
|
||||||
|
|
|
@ -39,7 +39,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
||||||
|
|
||||||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq);
|
||||||
|
|
||||||
int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
|
int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet);
|
||||||
|
|
||||||
int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId,
|
int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId,
|
||||||
SEpSet* pEpSet);
|
SEpSet* pEpSet);
|
||||||
|
|
|
@ -212,9 +212,10 @@ int32_t streamTaskOutput(SStreamTask* pTask, SStreamDataBlock* pBlock) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) {
|
int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg* pRsp, bool exec) {
|
||||||
qDebug("vgId:%d s-task:%s receive dispatch req from taskId:%d", pReq->upstreamNodeId, pTask->id.idStr,
|
qDebug("s-task:%s receive dispatch req from taskId:%d(vgId:%d)", pTask->id.idStr, pReq->upstreamTaskId,
|
||||||
pReq->upstreamTaskId);
|
pReq->upstreamNodeId);
|
||||||
|
|
||||||
|
// todo add the input queue buffer limitation
|
||||||
streamTaskEnqueueBlocks(pTask, pReq, pRsp);
|
streamTaskEnqueueBlocks(pTask, pReq, pRsp);
|
||||||
tDeleteStreamDispatchReq(pReq);
|
tDeleteStreamDispatchReq(pReq);
|
||||||
|
|
||||||
|
@ -222,10 +223,6 @@ int32_t streamProcessDispatchReq(SStreamTask* pTask, SStreamDispatchReq* pReq, S
|
||||||
if (streamTryExec(pTask) < 0) {
|
if (streamTryExec(pTask) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH || pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {*/
|
|
||||||
/*streamDispatch(pTask);*/
|
|
||||||
/*}*/
|
|
||||||
} else {
|
} else {
|
||||||
streamSchedExec(pTask);
|
streamSchedExec(pTask);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ static int32_t streamAddBlockToDispatchMsg(const SSDataBlock* pBlock, SStreamDis
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet) {
|
int32_t streamDispatchCheckMsg(SStreamTask* pTask, const SStreamTaskCheckReq* pReq, int32_t nodeId, SEpSet* pEpSet) {
|
||||||
void* buf = NULL;
|
void* buf = NULL;
|
||||||
int32_t code = -1;
|
int32_t code = -1;
|
||||||
SRpcMsg msg = {0};
|
SRpcMsg msg = {0};
|
||||||
|
@ -240,7 +240,7 @@ int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq*
|
||||||
msg.pCont = buf;
|
msg.pCont = buf;
|
||||||
msg.msgType = TDMT_STREAM_TASK_CHECK;
|
msg.msgType = TDMT_STREAM_TASK_CHECK;
|
||||||
|
|
||||||
qDebug("dispatch from s-task:%s to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr,
|
qDebug("s-task:%s dispatch check msg to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr,
|
||||||
pReq->streamId, pReq->downstreamTaskId, nodeId);
|
pReq->streamId, pReq->downstreamTaskId, nodeId);
|
||||||
|
|
||||||
tmsgSendReq(pEpSet, &msg);
|
tmsgSendReq(pEpSet, &msg);
|
||||||
|
|
|
@ -28,7 +28,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, const void* data, SArray*
|
||||||
|
|
||||||
while (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
while (pTask->taskLevel == TASK_LEVEL__SOURCE) {
|
||||||
int8_t status = atomic_load_8(&pTask->status.taskStatus);
|
int8_t status = atomic_load_8(&pTask->status.taskStatus);
|
||||||
if (status != TASK_STATUS__NORMAL && status != TASK_STATUS__RESTORE) {
|
if (status != TASK_STATUS__NORMAL) {
|
||||||
qError("stream task wait for the end of fill history, s-task:%s, status:%d", pTask->id.idStr,
|
qError("stream task wait for the end of fill history, s-task:%s, status:%d", pTask->id.idStr,
|
||||||
atomic_load_8(&pTask->status.taskStatus));
|
atomic_load_8(&pTask->status.taskStatus));
|
||||||
taosMsleep(2);
|
taosMsleep(2);
|
||||||
|
@ -250,10 +250,11 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
||||||
void* pInput = NULL;
|
void* pInput = NULL;
|
||||||
|
|
||||||
// merge multiple input data if possible in the input queue.
|
// merge multiple input data if possible in the input queue.
|
||||||
|
qDebug("s-task:%s start to extract data block from inputQ", pTask->id.idStr);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue);
|
SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue);
|
||||||
if (qItem == NULL) {
|
if (qItem == NULL) {
|
||||||
// qDebug("s-task:%s extract data from input queue, queue is empty, abort", pTask->id.idStr);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +299,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
|
SArray* pRes = taosArrayInit(0, sizeof(SSDataBlock));
|
||||||
qDebug("s-task:%s exec begin, numOfBlocks:%d", pTask->id.idStr, batchSize);
|
qDebug("s-task:%s start to execute, numOfBlocks:%d", pTask->id.idStr, batchSize);
|
||||||
|
|
||||||
streamTaskExecImpl(pTask, pInput, pRes);
|
streamTaskExecImpl(pTask, pInput, pRes);
|
||||||
|
|
||||||
|
@ -313,6 +314,7 @@ int32_t streamExecForAll(SStreamTask* pTask) {
|
||||||
pTask->chkInfo = (SCheckpointInfo) {.version = dataVer, .id = ckId, .currentVer = pTask->chkInfo.currentVer};
|
pTask->chkInfo = (SCheckpointInfo) {.version = dataVer, .id = ckId, .currentVer = pTask->chkInfo.currentVer};
|
||||||
|
|
||||||
taosWLockLatch(&pTask->pMeta->lock);
|
taosWLockLatch(&pTask->pMeta->lock);
|
||||||
|
|
||||||
streamMetaSaveTask(pTask->pMeta, pTask);
|
streamMetaSaveTask(pTask->pMeta, pTask);
|
||||||
if (streamMetaCommit(pTask->pMeta) < 0) {
|
if (streamMetaCommit(pTask->pMeta) < 0) {
|
||||||
taosWUnLockLatch(&pTask->pMeta->lock);
|
taosWUnLockLatch(&pTask->pMeta->lock);
|
||||||
|
|
|
@ -57,6 +57,13 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// task list
|
||||||
|
pMeta->pTaskList = taosArrayInit(4, sizeof(int32_t));
|
||||||
|
if (pMeta->pTaskList == NULL) {
|
||||||
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
|
||||||
if (streamMetaBegin(pMeta) < 0) {
|
if (streamMetaBegin(pMeta) < 0) {
|
||||||
goto _err;
|
goto _err;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +77,7 @@ SStreamMeta* streamMetaOpen(const char* path, void* ahandle, FTaskExpand expandF
|
||||||
_err:
|
_err:
|
||||||
taosMemoryFree(pMeta->path);
|
taosMemoryFree(pMeta->path);
|
||||||
if (pMeta->pTasks) taosHashCleanup(pMeta->pTasks);
|
if (pMeta->pTasks) taosHashCleanup(pMeta->pTasks);
|
||||||
|
if (pMeta->pTaskList) taosArrayDestroy(pMeta->pTaskList);
|
||||||
if (pMeta->pTaskDb) tdbTbClose(pMeta->pTaskDb);
|
if (pMeta->pTaskDb) tdbTbClose(pMeta->pTaskDb);
|
||||||
if (pMeta->pCheckpointDb) tdbTbClose(pMeta->pCheckpointDb);
|
if (pMeta->pCheckpointDb) tdbTbClose(pMeta->pCheckpointDb);
|
||||||
if (pMeta->db) tdbClose(pMeta->db);
|
if (pMeta->db) tdbClose(pMeta->db);
|
||||||
|
@ -100,6 +108,7 @@ void streamMetaClose(SStreamMeta* pMeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
taosHashCleanup(pMeta->pTasks);
|
taosHashCleanup(pMeta->pTasks);
|
||||||
|
pMeta->pTaskList = taosArrayDestroy(pMeta->pTaskList);
|
||||||
taosMemoryFree(pMeta->path);
|
taosMemoryFree(pMeta->path);
|
||||||
taosMemoryFree(pMeta);
|
taosMemoryFree(pMeta);
|
||||||
}
|
}
|
||||||
|
@ -179,12 +188,21 @@ int32_t streamMetaAddDeployedTask(SStreamMeta* pMeta, int64_t ver, SStreamTask*
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (streamMetaCommit(pMeta) < 0) {
|
||||||
|
tFreeStreamTask(pTask);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(int32_t), &pTask, POINTER_BYTES);
|
taosHashPut(pMeta->pTasks, &pTask->id.taskId, sizeof(int32_t), &pTask, POINTER_BYTES);
|
||||||
|
taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamMetaGetNumOfTasks(const SStreamMeta* pMeta) {
|
int32_t streamMetaGetNumOfTasks(const SStreamMeta* pMeta) {
|
||||||
return (int32_t) taosHashGetSize(pMeta->pTasks);
|
size_t size = taosHashGetSize(pMeta->pTasks);
|
||||||
|
ASSERT(taosArrayGetSize(pMeta->pTaskList) == taosHashGetSize(pMeta->pTasks));
|
||||||
|
|
||||||
|
return (int32_t) size;
|
||||||
}
|
}
|
||||||
|
|
||||||
SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int32_t taskId) {
|
SStreamTask* streamMetaAcquireTask(SStreamMeta* pMeta, int32_t taskId) {
|
||||||
|
@ -216,12 +234,23 @@ void streamMetaRemoveTask(SStreamMeta* pMeta, int32_t taskId) {
|
||||||
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t));
|
SStreamTask** ppTask = (SStreamTask**)taosHashGet(pMeta->pTasks, &taskId, sizeof(int32_t));
|
||||||
if (ppTask) {
|
if (ppTask) {
|
||||||
SStreamTask* pTask = *ppTask;
|
SStreamTask* pTask = *ppTask;
|
||||||
|
|
||||||
|
taosWLockLatch(&pMeta->lock);
|
||||||
|
|
||||||
taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t));
|
taosHashRemove(pMeta->pTasks, &taskId, sizeof(int32_t));
|
||||||
tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), pMeta->txn);
|
tdbTbDelete(pMeta->pTaskDb, &taskId, sizeof(int32_t), pMeta->txn);
|
||||||
|
|
||||||
atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__STOP);
|
atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__STOP);
|
||||||
|
|
||||||
taosWLockLatch(&pMeta->lock);
|
int32_t num = taosArrayGetSize(pMeta->pTaskList);
|
||||||
|
for(int32_t i = 0; i < num; ++i) {
|
||||||
|
int32_t* pTaskId = taosArrayGet(pMeta->pTaskList, i);
|
||||||
|
if (*pTaskId == taskId) {
|
||||||
|
taosArrayRemove(pMeta->pTaskList, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
streamMetaReleaseTask(pMeta, pTask);
|
streamMetaReleaseTask(pMeta, pTask);
|
||||||
taosWUnLockLatch(&pMeta->lock);
|
taosWUnLockLatch(&pMeta->lock);
|
||||||
}
|
}
|
||||||
|
@ -287,6 +316,7 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
|
||||||
tdbTbcClose(pCur);
|
tdbTbcClose(pCur);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
|
tDecoderInit(&decoder, (uint8_t*)pVal, vLen);
|
||||||
tDecodeStreamTask(&decoder, pTask);
|
tDecodeStreamTask(&decoder, pTask);
|
||||||
tDecoderClear(&decoder);
|
tDecoderClear(&decoder);
|
||||||
|
@ -305,7 +335,8 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*pTask->status.taskStatus = TASK_STATUS__NORMAL;*/
|
taosArrayPush(pMeta->pTaskList, &pTask->id.taskId);
|
||||||
|
|
||||||
if (pTask->fillHistory) {
|
if (pTask->fillHistory) {
|
||||||
pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM;
|
pTask->status.taskStatus = TASK_STATUS__WAIT_DOWNSTREAM;
|
||||||
streamTaskCheckDownstream(pTask, ver);
|
streamTaskCheckDownstream(pTask, ver);
|
||||||
|
|
|
@ -54,6 +54,8 @@ int32_t streamTaskLaunchRecover(SStreamTask* pTask, int64_t version) {
|
||||||
|
|
||||||
// checkstatus
|
// checkstatus
|
||||||
int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
|
int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
|
||||||
|
qDebug("s-taks:%s in fill history stage, ver:%"PRId64, pTask->id.idStr, version);
|
||||||
|
|
||||||
SStreamTaskCheckReq req = {
|
SStreamTaskCheckReq req = {
|
||||||
.streamId = pTask->id.streamId,
|
.streamId = pTask->id.streamId,
|
||||||
.upstreamTaskId = pTask->id.taskId,
|
.upstreamTaskId = pTask->id.taskId,
|
||||||
|
@ -63,16 +65,18 @@ int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
|
||||||
|
|
||||||
// serialize
|
// serialize
|
||||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||||
|
|
||||||
req.reqId = tGenIdPI64();
|
req.reqId = tGenIdPI64();
|
||||||
req.downstreamNodeId = pTask->fixedEpDispatcher.nodeId;
|
req.downstreamNodeId = pTask->fixedEpDispatcher.nodeId;
|
||||||
req.downstreamTaskId = pTask->fixedEpDispatcher.taskId;
|
req.downstreamTaskId = pTask->fixedEpDispatcher.taskId;
|
||||||
pTask->checkReqId = req.reqId;
|
pTask->checkReqId = req.reqId;
|
||||||
|
|
||||||
qDebug("task %d at node %d check downstream task %d at node %d", pTask->id.taskId, pTask->nodeId, req.downstreamTaskId,
|
qDebug("s-task:%s at node %d check downstream task %d at node %d", pTask->id.idStr, pTask->nodeId, req.downstreamTaskId,
|
||||||
req.downstreamNodeId);
|
req.downstreamNodeId);
|
||||||
streamDispatchOneCheckReq(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
|
streamDispatchCheckMsg(pTask, &req, pTask->fixedEpDispatcher.nodeId, &pTask->fixedEpDispatcher.epSet);
|
||||||
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||||
SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
|
SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
|
||||||
|
|
||||||
int32_t vgSz = taosArrayGetSize(vgInfo);
|
int32_t vgSz = taosArrayGetSize(vgInfo);
|
||||||
pTask->recoverTryingDownstream = vgSz;
|
pTask->recoverTryingDownstream = vgSz;
|
||||||
pTask->checkReqIds = taosArrayInit(vgSz, sizeof(int64_t));
|
pTask->checkReqIds = taosArrayInit(vgSz, sizeof(int64_t));
|
||||||
|
@ -83,14 +87,15 @@ int32_t streamTaskCheckDownstream(SStreamTask* pTask, int64_t version) {
|
||||||
taosArrayPush(pTask->checkReqIds, &req.reqId);
|
taosArrayPush(pTask->checkReqIds, &req.reqId);
|
||||||
req.downstreamNodeId = pVgInfo->vgId;
|
req.downstreamNodeId = pVgInfo->vgId;
|
||||||
req.downstreamTaskId = pVgInfo->taskId;
|
req.downstreamTaskId = pVgInfo->taskId;
|
||||||
qDebug("task %d at node %d check downstream task %d at node %d (shuffle)", pTask->id.taskId, pTask->nodeId,
|
qDebug("s-task:%s at node %d check downstream task %d at node %d (shuffle)", pTask->id.idStr, pTask->nodeId,
|
||||||
req.downstreamTaskId, req.downstreamNodeId);
|
req.downstreamTaskId, req.downstreamNodeId);
|
||||||
streamDispatchOneCheckReq(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet);
|
streamDispatchCheckMsg(pTask, &req, pVgInfo->vgId, &pVgInfo->epSet);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug("task %d at node %d direct launch recover since no downstream", pTask->id.taskId, pTask->nodeId);
|
qDebug("s-task:%s at node %d direct launch recover since no downstream", pTask->id.idStr, pTask->nodeId);
|
||||||
streamTaskLaunchRecover(pTask, version);
|
streamTaskLaunchRecover(pTask, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +114,14 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
|
||||||
req.downstreamTaskId, req.downstreamNodeId);
|
req.downstreamTaskId, req.downstreamNodeId);
|
||||||
|
|
||||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||||
streamDispatchOneCheckReq(pTask, &req, pRsp->downstreamNodeId, &pTask->fixedEpDispatcher.epSet);
|
streamDispatchCheckMsg(pTask, &req, pRsp->downstreamNodeId, &pTask->fixedEpDispatcher.epSet);
|
||||||
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||||
SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
|
SArray* vgInfo = pTask->shuffleDispatcher.dbInfo.pVgroupInfos;
|
||||||
int32_t vgSz = taosArrayGetSize(vgInfo);
|
int32_t vgSz = taosArrayGetSize(vgInfo);
|
||||||
for (int32_t i = 0; i < vgSz; i++) {
|
for (int32_t i = 0; i < vgSz; i++) {
|
||||||
SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i);
|
SVgroupInfo* pVgInfo = taosArrayGet(vgInfo, i);
|
||||||
if (pVgInfo->taskId == req.downstreamTaskId) {
|
if (pVgInfo->taskId == req.downstreamTaskId) {
|
||||||
streamDispatchOneCheckReq(pTask, &req, pRsp->downstreamNodeId, &pVgInfo->epSet);
|
streamDispatchCheckMsg(pTask, &req, pRsp->downstreamNodeId, &pVgInfo->epSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,8 +129,8 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamProcessTaskCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq* pReq) {
|
int32_t streamTaskCheckStatus(SStreamTask* pTask) {
|
||||||
return atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL;
|
return atomic_load_8(&pTask->status.taskStatus) == TASK_STATUS__NORMAL? 1:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version) {
|
int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp* pRsp, int64_t version) {
|
||||||
|
@ -135,7 +140,9 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
|
||||||
if (pRsp->status == 1) {
|
if (pRsp->status == 1) {
|
||||||
if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int32_t i = 0; i < taosArrayGetSize(pTask->checkReqIds); i++) {
|
|
||||||
|
int32_t numOfReqs = taosArrayGetSize(pTask->checkReqIds);
|
||||||
|
for (int32_t i = 0; i < numOfReqs; i++) {
|
||||||
int64_t reqId = *(int64_t*)taosArrayGet(pTask->checkReqIds, i);
|
int64_t reqId = *(int64_t*)taosArrayGet(pTask->checkReqIds, i);
|
||||||
if (reqId == pRsp->reqId) {
|
if (reqId == pRsp->reqId) {
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -149,9 +156,12 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
|
||||||
|
|
||||||
int32_t left = atomic_sub_fetch_32(&pTask->recoverTryingDownstream, 1);
|
int32_t left = atomic_sub_fetch_32(&pTask->recoverTryingDownstream, 1);
|
||||||
ASSERT(left >= 0);
|
ASSERT(left >= 0);
|
||||||
|
|
||||||
if (left == 0) {
|
if (left == 0) {
|
||||||
taosArrayDestroy(pTask->checkReqIds);
|
taosArrayDestroy(pTask->checkReqIds);
|
||||||
pTask->checkReqIds = NULL;
|
pTask->checkReqIds = NULL;
|
||||||
|
|
||||||
|
qDebug("s-task:%s all downstream tasks:%d are ready, now enter into recover stage", pTask->id.idStr, numOfReqs);
|
||||||
streamTaskLaunchRecover(pTask, version);
|
streamTaskLaunchRecover(pTask, version);
|
||||||
}
|
}
|
||||||
} else if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
} else if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||||
|
@ -163,7 +173,10 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
|
||||||
} else {
|
} else {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
} else { // not ready, it should wait for at least 100ms and then retry
|
} else { // not ready, wait for 100ms and retry
|
||||||
|
qDebug("s-task:%s downstream taskId:%d (vgId:%d) not ready, wait for 100ms and retry", pTask->id.idStr,
|
||||||
|
pRsp->downstreamTaskId, pRsp->downstreamNodeId);
|
||||||
|
taosMsleep(100);
|
||||||
streamRecheckOneDownstream(pTask, pRsp);
|
streamRecheckOneDownstream(pTask, pRsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ void tFreeStreamTask(SStreamTask* pTask) {
|
||||||
|
|
||||||
taosArrayDestroyP(pTask->childEpInfo, taosMemoryFree);
|
taosArrayDestroyP(pTask->childEpInfo, taosMemoryFree);
|
||||||
if (pTask->outputType == TASK_OUTPUT__TABLE) {
|
if (pTask->outputType == TASK_OUTPUT__TABLE) {
|
||||||
tDeleteSSchemaWrapper(pTask->tbSink.pSchemaWrapper);
|
tDeleteSchemaWrapper(pTask->tbSink.pSchemaWrapper);
|
||||||
taosMemoryFree(pTask->tbSink.pTSchema);
|
taosMemoryFree(pTask->tbSink.pTSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,8 @@ static void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl, bool rsp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void syncRespCleanRsp(SSyncRespMgr *pObj) {
|
void syncRespCleanRsp(SSyncRespMgr *pObj) {
|
||||||
|
if (pObj == NULL) return;
|
||||||
|
|
||||||
SSyncNode *pNode = pObj->data;
|
SSyncNode *pNode = pObj->data;
|
||||||
sTrace("vgId:%d, clean all resp", pNode->vgId);
|
sTrace("vgId:%d, clean all resp", pNode->vgId);
|
||||||
|
|
||||||
|
|
|
@ -1814,6 +1814,11 @@ int tdbBtreeNext(SBTC *pBtc, void **ppKey, int *kLen, void **ppVal, int *vLen) {
|
||||||
|
|
||||||
*ppVal = pVal;
|
*ppVal = pVal;
|
||||||
*vLen = cd.vLen;
|
*vLen = cd.vLen;
|
||||||
|
} else {
|
||||||
|
if (TDB_CELLDECODER_FREE_VAL(&cd)) {
|
||||||
|
tdbTrace("tdb/btree-next2 decoder: %p pVal free: %p", &cd, cd.pVal);
|
||||||
|
tdbFree(cd.pVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tdbBtcMoveToNext(pBtc);
|
ret = tdbBtcMoveToNext(pBtc);
|
||||||
|
|
|
@ -587,12 +587,12 @@ void* destroyConnPool(SCliThrd* pThrd) {
|
||||||
|
|
||||||
static SCliConn* getConnFromPool(SCliThrd* pThrd, char* key, bool* exceed) {
|
static SCliConn* getConnFromPool(SCliThrd* pThrd, char* key, bool* exceed) {
|
||||||
void* pool = pThrd->pool;
|
void* pool = pThrd->pool;
|
||||||
SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key));
|
SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key) + 1);
|
||||||
STrans* pTranInst = pThrd->pTransInst;
|
STrans* pTranInst = pThrd->pTransInst;
|
||||||
if (plist == NULL) {
|
if (plist == NULL) {
|
||||||
SConnList list = {0};
|
SConnList list = {0};
|
||||||
taosHashPut((SHashObj*)pool, key, strlen(key), (void*)&list, sizeof(list));
|
taosHashPut((SHashObj*)pool, key, strlen(key) + 1, (void*)&list, sizeof(list));
|
||||||
plist = taosHashGet(pool, key, strlen(key));
|
plist = taosHashGet(pool, key, strlen(key) + 1);
|
||||||
|
|
||||||
SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
|
SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
|
||||||
QUEUE_INIT(&nList->msgQ);
|
QUEUE_INIT(&nList->msgQ);
|
||||||
|
@ -627,11 +627,11 @@ static SCliConn* getConnFromPool(SCliThrd* pThrd, char* key, bool* exceed) {
|
||||||
static SCliConn* getConnFromPool2(SCliThrd* pThrd, char* key, SCliMsg** pMsg) {
|
static SCliConn* getConnFromPool2(SCliThrd* pThrd, char* key, SCliMsg** pMsg) {
|
||||||
void* pool = pThrd->pool;
|
void* pool = pThrd->pool;
|
||||||
STrans* pTransInst = pThrd->pTransInst;
|
STrans* pTransInst = pThrd->pTransInst;
|
||||||
SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key));
|
SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key) + 1);
|
||||||
if (plist == NULL) {
|
if (plist == NULL) {
|
||||||
SConnList list = {0};
|
SConnList list = {0};
|
||||||
taosHashPut((SHashObj*)pool, key, strlen(key), (void*)&list, sizeof(list));
|
taosHashPut((SHashObj*)pool, key, strlen(key) + 1, (void*)&list, sizeof(list));
|
||||||
plist = taosHashGet(pool, key, strlen(key));
|
plist = taosHashGet(pool, key, strlen(key) + 1);
|
||||||
|
|
||||||
SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
|
SMsgList* nList = taosMemoryCalloc(1, sizeof(SMsgList));
|
||||||
QUEUE_INIT(&nList->msgQ);
|
QUEUE_INIT(&nList->msgQ);
|
||||||
|
@ -717,7 +717,7 @@ static void addConnToPool(void* pool, SCliConn* conn) {
|
||||||
cliDestroyConnMsgs(conn, false);
|
cliDestroyConnMsgs(conn, false);
|
||||||
|
|
||||||
if (conn->list == NULL) {
|
if (conn->list == NULL) {
|
||||||
conn->list = taosHashGet((SHashObj*)pool, conn->ip, strlen(conn->ip));
|
conn->list = taosHashGet((SHashObj*)pool, conn->ip, strlen(conn->ip) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SConnList* pList = conn->list;
|
SConnList* pList = conn->list;
|
||||||
|
@ -822,7 +822,8 @@ static void cliRecvCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
tWarn("%s conn %p read error:%s, ref:%d", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread), T_REF_VAL_GET(conn));
|
tDebug("%s conn %p read error:%s, ref:%d", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread),
|
||||||
|
T_REF_VAL_GET(conn));
|
||||||
conn->broken = true;
|
conn->broken = true;
|
||||||
cliHandleExcept(conn);
|
cliHandleExcept(conn);
|
||||||
}
|
}
|
||||||
|
@ -875,8 +876,8 @@ static void cliDestroyConn(SCliConn* conn, bool clear) {
|
||||||
connList->list->numOfConn--;
|
connList->list->numOfConn--;
|
||||||
connList->size--;
|
connList->size--;
|
||||||
} else {
|
} else {
|
||||||
SConnList* connList = taosHashGet((SHashObj*)pThrd->pool, conn->ip, strlen(conn->ip));
|
SConnList* connList = taosHashGet((SHashObj*)pThrd->pool, conn->ip, strlen(conn->ip) + 1);
|
||||||
connList->list->numOfConn--;
|
if (connList != NULL) connList->list->numOfConn--;
|
||||||
}
|
}
|
||||||
conn->list = NULL;
|
conn->list = NULL;
|
||||||
pThrd->newConnCount--;
|
pThrd->newConnCount--;
|
||||||
|
@ -1269,7 +1270,7 @@ static void cliHandleFastFail(SCliConn* pConn, int status) {
|
||||||
|
|
||||||
if (pMsg != NULL && REQUEST_NO_RESP(&pMsg->msg) &&
|
if (pMsg != NULL && REQUEST_NO_RESP(&pMsg->msg) &&
|
||||||
(pTransInst->failFastFp != NULL && pTransInst->failFastFp(pMsg->msg.msgType))) {
|
(pTransInst->failFastFp != NULL && pTransInst->failFastFp(pMsg->msg.msgType))) {
|
||||||
SFailFastItem* item = taosHashGet(pThrd->failFastCache, pConn->ip, strlen(pConn->ip));
|
SFailFastItem* item = taosHashGet(pThrd->failFastCache, pConn->ip, strlen(pConn->ip) + 1);
|
||||||
int64_t cTimestamp = taosGetTimestampMs();
|
int64_t cTimestamp = taosGetTimestampMs();
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
int32_t elapse = cTimestamp - item->timestamp;
|
int32_t elapse = cTimestamp - item->timestamp;
|
||||||
|
@ -1281,7 +1282,7 @@ static void cliHandleFastFail(SCliConn* pConn, int status) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SFailFastItem item = {.count = 1, .timestamp = cTimestamp};
|
SFailFastItem item = {.count = 1, .timestamp = cTimestamp};
|
||||||
taosHashPut(pThrd->failFastCache, pConn->ip, strlen(pConn->ip), &item, sizeof(SFailFastItem));
|
taosHashPut(pThrd->failFastCache, pConn->ip, strlen(pConn->ip) + 1, &item, sizeof(SFailFastItem));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1459,7 +1460,7 @@ FORCE_INLINE int32_t cliBuildExceptResp(SCliMsg* pMsg, STransMsg* pResp) {
|
||||||
}
|
}
|
||||||
static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn) {
|
static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn) {
|
||||||
uint32_t addr = 0;
|
uint32_t addr = 0;
|
||||||
uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn));
|
uint32_t* v = taosHashGet(cache, fqdn, strlen(fqdn) + 1);
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
addr = taosGetIpv4FromFqdn(fqdn);
|
addr = taosGetIpv4FromFqdn(fqdn);
|
||||||
if (addr == 0xffffffff) {
|
if (addr == 0xffffffff) {
|
||||||
|
@ -1468,7 +1469,7 @@ static FORCE_INLINE uint32_t cliGetIpFromFqdnCache(SHashObj* cache, char* fqdn)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosHashPut(cache, fqdn, strlen(fqdn), &addr, sizeof(addr));
|
taosHashPut(cache, fqdn, strlen(fqdn) + 1, &addr, sizeof(addr));
|
||||||
} else {
|
} else {
|
||||||
addr = *v;
|
addr = *v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,7 +314,7 @@ void uvOnRecvCb(uv_stream_t* cli, ssize_t nread, const uv_buf_t* buf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tWarn("%s conn %p read error:%s", transLabel(pTransInst), conn, uv_err_name(nread));
|
tDebug("%s conn %p read error:%s", transLabel(pTransInst), conn, uv_err_name(nread));
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
conn->broken = true;
|
conn->broken = true;
|
||||||
if (conn->status == ConnAcquire) {
|
if (conn->status == ConnAcquire) {
|
||||||
|
|
|
@ -295,6 +295,36 @@ void walAlignVersions(SWal* pWal) {
|
||||||
wInfo("vgId:%d, reset commitVer to %" PRId64, pWal->cfg.vgId, pWal->vers.commitVer);
|
wInfo("vgId:%d, reset commitVer to %" PRId64, pWal->cfg.vgId, pWal->vers.commitVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int walRepairLogFileTs(SWal* pWal, bool* updateMeta) {
|
||||||
|
int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
|
||||||
|
int32_t fileIdx = -1;
|
||||||
|
int32_t lastCloseTs = 0;
|
||||||
|
char fnameStr[WAL_FILE_LEN] = {0};
|
||||||
|
|
||||||
|
while (++fileIdx < sz - 1) {
|
||||||
|
SWalFileInfo* pFileInfo = taosArrayGet(pWal->fileInfoSet, fileIdx);
|
||||||
|
if (pFileInfo->closeTs != -1) {
|
||||||
|
lastCloseTs = pFileInfo->closeTs;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
walBuildLogName(pWal, pFileInfo->firstVer, fnameStr);
|
||||||
|
int32_t mtime = 0;
|
||||||
|
if (taosStatFile(fnameStr, NULL, &mtime) < 0) {
|
||||||
|
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
wError("vgId:%d, failed to stat file due to %s, file:%s", pWal->cfg.vgId, strerror(errno), fnameStr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateMeta != NULL) *updateMeta = true;
|
||||||
|
if (pFileInfo->createTs == -1) pFileInfo->createTs = lastCloseTs;
|
||||||
|
pFileInfo->closeTs = mtime;
|
||||||
|
lastCloseTs = pFileInfo->closeTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool walLogEntriesComplete(const SWal* pWal) {
|
bool walLogEntriesComplete(const SWal* pWal) {
|
||||||
int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
|
int32_t sz = taosArrayGetSize(pWal->fileInfoSet);
|
||||||
bool complete = true;
|
bool complete = true;
|
||||||
|
@ -433,15 +463,8 @@ int walCheckAndRepairMeta(SWal* pWal) {
|
||||||
wError("failed to scan wal last ver since %s", terrstr());
|
wError("failed to scan wal last ver since %s", terrstr());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// remove the empty wal log, and its idx
|
// empty log file
|
||||||
wInfo("vgId:%d, wal remove empty file %s", pWal->cfg.vgId, fnameStr);
|
lastVer = pFileInfo->firstVer - 1;
|
||||||
taosRemoveFile(fnameStr);
|
|
||||||
walBuildIdxName(pWal, pFileInfo->firstVer, fnameStr);
|
|
||||||
wInfo("vgId:%d, wal remove empty file %s", pWal->cfg.vgId, fnameStr);
|
|
||||||
taosRemoveFile(fnameStr);
|
|
||||||
// remove its meta entry
|
|
||||||
taosArrayRemove(pWal->fileInfoSet, fileIdx);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update lastVer
|
// update lastVer
|
||||||
|
@ -460,6 +483,11 @@ int walCheckAndRepairMeta(SWal* pWal) {
|
||||||
}
|
}
|
||||||
(void)walAlignVersions(pWal);
|
(void)walAlignVersions(pWal);
|
||||||
|
|
||||||
|
// repair ts of files
|
||||||
|
if (walRepairLogFileTs(pWal, &updateMeta) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// update meta file
|
// update meta file
|
||||||
if (updateMeta) {
|
if (updateMeta) {
|
||||||
(void)walSaveMeta(pWal);
|
(void)walSaveMeta(pWal);
|
||||||
|
|
|
@ -37,7 +37,7 @@ SWalReader *walOpenReader(SWal *pWal, SWalFilterCond *cond) {
|
||||||
if (cond) {
|
if (cond) {
|
||||||
pReader->cond = *cond;
|
pReader->cond = *cond;
|
||||||
} else {
|
} else {
|
||||||
pReader->cond.scanUncommited = 0;
|
// pReader->cond.scanUncommited = 0;
|
||||||
pReader->cond.scanNotApplied = 0;
|
pReader->cond.scanNotApplied = 0;
|
||||||
pReader->cond.scanMeta = 0;
|
pReader->cond.scanMeta = 0;
|
||||||
pReader->cond.enableRef = 0;
|
pReader->cond.enableRef = 0;
|
||||||
|
@ -74,11 +74,15 @@ int32_t walNextValidMsg(SWalReader *pReader) {
|
||||||
int64_t lastVer = walGetLastVer(pReader->pWal);
|
int64_t lastVer = walGetLastVer(pReader->pWal);
|
||||||
int64_t committedVer = walGetCommittedVer(pReader->pWal);
|
int64_t committedVer = walGetCommittedVer(pReader->pWal);
|
||||||
int64_t appliedVer = walGetAppliedVer(pReader->pWal);
|
int64_t appliedVer = walGetAppliedVer(pReader->pWal);
|
||||||
int64_t endVer = pReader->cond.scanUncommited ? lastVer : committedVer;
|
if(appliedVer < committedVer){ // wait apply ver equal to commit ver, otherwise may lost data when consume data [TD-24010]
|
||||||
endVer = TMIN(appliedVer, endVer);
|
wDebug("vgId:%d, wal apply ver:%"PRId64" smaller than commit ver:%"PRId64, pReader->pWal->cfg.vgId, appliedVer, committedVer);
|
||||||
|
// taosMsleep(10);
|
||||||
|
}
|
||||||
|
// int64_t endVer = pReader->cond.scanUncommited ? lastVer : committedVer;
|
||||||
|
int64_t endVer = TMIN(appliedVer, committedVer);
|
||||||
|
|
||||||
wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64
|
wDebug("vgId:%d, wal start to fetch, index:%" PRId64 ", last index:%" PRId64 " commit index:%" PRId64
|
||||||
", applied index:%" PRId64 ", end index:%" PRId64,
|
", applied index:%" PRId64", end index:%" PRId64,
|
||||||
pReader->pWal->cfg.vgId, fetchVer, lastVer, committedVer, appliedVer, endVer);
|
pReader->pWal->cfg.vgId, fetchVer, lastVer, committedVer, appliedVer, endVer);
|
||||||
while (fetchVer <= endVer) {
|
while (fetchVer <= endVer) {
|
||||||
if (walFetchHeadNew(pReader, fetchVer) < 0) {
|
if (walFetchHeadNew(pReader, fetchVer) < 0) {
|
||||||
|
@ -237,6 +241,7 @@ static int32_t walFetchHeadNew(SWalReader *pRead, int64_t fetchVer) {
|
||||||
}
|
}
|
||||||
seeked = true;
|
seeked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
contLen = taosReadFile(pRead->pLogFile, pRead->pHead, sizeof(SWalCkHead));
|
contLen = taosReadFile(pRead->pLogFile, pRead->pHead, sizeof(SWalCkHead));
|
||||||
if (contLen == sizeof(SWalCkHead)) {
|
if (contLen == sizeof(SWalCkHead)) {
|
||||||
|
@ -262,7 +267,7 @@ static int32_t walFetchBodyNew(SWalReader *pReader) {
|
||||||
SWalCont *pReadHead = &pReader->pHead->head;
|
SWalCont *pReadHead = &pReader->pHead->head;
|
||||||
int64_t ver = pReadHead->version;
|
int64_t ver = pReadHead->version;
|
||||||
|
|
||||||
wDebug("vgId:%d, wal starts to fetch body, ver:%" PRId64 " ,len:%d", pReader->pWal->cfg.vgId, ver,
|
wDebug("vgId:%d, wal starts to fetch body, ver:%" PRId64 " ,len:%d, total", pReader->pWal->cfg.vgId, ver,
|
||||||
pReadHead->bodyLen);
|
pReadHead->bodyLen);
|
||||||
|
|
||||||
if (pReader->capacity < pReadHead->bodyLen) {
|
if (pReader->capacity < pReadHead->bodyLen) {
|
||||||
|
|
|
@ -284,15 +284,15 @@ int32_t walEndSnapshot(SWal *pWal) {
|
||||||
if (ver == -1) {
|
if (ver == -1) {
|
||||||
code = -1;
|
code = -1;
|
||||||
goto END;
|
goto END;
|
||||||
};
|
}
|
||||||
|
|
||||||
pWal->vers.snapshotVer = ver;
|
pWal->vers.snapshotVer = ver;
|
||||||
int ts = taosGetTimestampSec();
|
int ts = taosGetTimestampSec();
|
||||||
|
|
||||||
ver = TMAX(ver - pWal->vers.logRetention, pWal->vers.firstVer - 1);
|
ver = TMAX(ver - pWal->vers.logRetention, pWal->vers.firstVer - 1);
|
||||||
|
|
||||||
|
// compatible mode for refVer
|
||||||
bool hasTopic = false;
|
bool hasTopic = false;
|
||||||
int64_t refVer = ver;
|
int64_t refVer = INT64_MAX;
|
||||||
void *pIter = NULL;
|
void *pIter = NULL;
|
||||||
while (1) {
|
while (1) {
|
||||||
pIter = taosHashIterate(pWal->pRefHash, pIter);
|
pIter = taosHashIterate(pWal->pRefHash, pIter);
|
||||||
|
@ -300,54 +300,40 @@ int32_t walEndSnapshot(SWal *pWal) {
|
||||||
SWalRef *pRef = *(SWalRef **)pIter;
|
SWalRef *pRef = *(SWalRef **)pIter;
|
||||||
if (pRef->refVer == -1) continue;
|
if (pRef->refVer == -1) continue;
|
||||||
refVer = TMIN(refVer, pRef->refVer - 1);
|
refVer = TMIN(refVer, pRef->refVer - 1);
|
||||||
wDebug("vgId:%d, wal found ref %" PRId64 ", refId %" PRId64, pWal->cfg.vgId, pRef->refVer, pRef->refId);
|
|
||||||
hasTopic = true;
|
hasTopic = true;
|
||||||
}
|
}
|
||||||
// compatible mode
|
|
||||||
if (pWal->cfg.retentionPeriod == 0 && hasTopic) {
|
if (pWal->cfg.retentionPeriod == 0 && hasTopic) {
|
||||||
|
wInfo("vgId:%d, wal found refVer:%" PRId64 " in compatible mode, ver:%" PRId64, pWal->cfg.vgId, refVer, ver);
|
||||||
ver = TMIN(ver, refVer);
|
ver = TMIN(ver, refVer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find files safe to delete
|
||||||
int deleteCnt = 0;
|
int deleteCnt = 0;
|
||||||
int64_t newTotSize = pWal->totSize;
|
int64_t newTotSize = pWal->totSize;
|
||||||
SWalFileInfo tmp;
|
SWalFileInfo tmp = {0};
|
||||||
tmp.firstVer = ver;
|
tmp.firstVer = ver;
|
||||||
// find files safe to delete
|
|
||||||
SWalFileInfo *pInfo = taosArraySearch(pWal->fileInfoSet, &tmp, compareWalFileInfo, TD_LE);
|
SWalFileInfo *pInfo = taosArraySearch(pWal->fileInfoSet, &tmp, compareWalFileInfo, TD_LE);
|
||||||
|
|
||||||
if (pInfo) {
|
if (pInfo) {
|
||||||
SWalFileInfo *pLastFileInfo = taosArrayGetLast(pWal->fileInfoSet);
|
wDebug("vgId:%d, wal search found file info. ver:%" PRId64 ", first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, ver,
|
||||||
wDebug("vgId:%d, wal search found file info: first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
|
pInfo->firstVer, pInfo->lastVer);
|
||||||
pInfo->lastVer);
|
ASSERT(ver <= pInfo->lastVer);
|
||||||
if (ver >= pInfo->lastVer) {
|
if (ver == pInfo->lastVer) {
|
||||||
pInfo++;
|
pInfo++;
|
||||||
wDebug("vgId:%d, wal remove advance one file: first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
|
|
||||||
pInfo->lastVer);
|
|
||||||
}
|
|
||||||
if (pInfo <= pLastFileInfo) {
|
|
||||||
wDebug("vgId:%d, wal end remove for first:%" PRId64 " last:%" PRId64, pWal->cfg.vgId, pInfo->firstVer,
|
|
||||||
pInfo->lastVer);
|
|
||||||
} else {
|
|
||||||
wDebug("vgId:%d, wal no remove", pWal->cfg.vgId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate files, until the searched result
|
// iterate files, until the searched result
|
||||||
|
// delete according to file size or close time
|
||||||
for (SWalFileInfo *iter = pWal->fileInfoSet->pData; iter < pInfo; iter++) {
|
for (SWalFileInfo *iter = pWal->fileInfoSet->pData; iter < pInfo; iter++) {
|
||||||
wDebug("vgId:%d, wal check remove file %" PRId64 "(file size %" PRId64 " close ts %" PRId64
|
if ((pWal->cfg.retentionSize > 0 && newTotSize > pWal->cfg.retentionSize) ||
|
||||||
"), new tot size %" PRId64,
|
(pWal->cfg.retentionPeriod == 0 ||
|
||||||
pWal->cfg.vgId, iter->firstVer, iter->fileSize, iter->closeTs, newTotSize);
|
pWal->cfg.retentionPeriod > 0 && iter->closeTs >= 0 && iter->closeTs + pWal->cfg.retentionPeriod < ts)) {
|
||||||
if ((pWal->cfg.retentionSize != -1 && pWal->cfg.retentionSize != 0 && newTotSize > pWal->cfg.retentionSize) ||
|
|
||||||
((pWal->cfg.retentionPeriod == 0) || (pWal->cfg.retentionPeriod != -1 && iter->closeTs != -1 &&
|
|
||||||
iter->closeTs + pWal->cfg.retentionPeriod < ts))) {
|
|
||||||
// delete according to file size or close time
|
|
||||||
wDebug("vgId:%d, check pass", pWal->cfg.vgId);
|
|
||||||
deleteCnt++;
|
deleteCnt++;
|
||||||
newTotSize -= iter->fileSize;
|
newTotSize -= iter->fileSize;
|
||||||
taosArrayPush(pWal->toDeleteFiles, iter);
|
taosArrayPush(pWal->toDeleteFiles, iter);
|
||||||
}
|
}
|
||||||
wDebug("vgId:%d, check not pass", pWal->cfg.vgId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UPDATE_META:
|
|
||||||
// make new array, remove files
|
// make new array, remove files
|
||||||
taosArrayPopFrontBatch(pWal->fileInfoSet, deleteCnt);
|
taosArrayPopFrontBatch(pWal->fileInfoSet, deleteCnt);
|
||||||
if (taosArrayGetSize(pWal->fileInfoSet) == 0) {
|
if (taosArrayGetSize(pWal->fileInfoSet) == 0) {
|
||||||
|
@ -357,11 +343,12 @@ int32_t walEndSnapshot(SWal *pWal) {
|
||||||
pWal->vers.firstVer = ((SWalFileInfo *)taosArrayGet(pWal->fileInfoSet, 0))->firstVer;
|
pWal->vers.firstVer = ((SWalFileInfo *)taosArrayGet(pWal->fileInfoSet, 0))->firstVer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update meta
|
||||||
pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1;
|
pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1;
|
||||||
pWal->totSize = newTotSize;
|
pWal->totSize = newTotSize;
|
||||||
pWal->vers.verInSnapshotting = -1;
|
pWal->vers.verInSnapshotting = -1;
|
||||||
|
|
||||||
// save snapshot ver, commit ver
|
|
||||||
code = walSaveMeta(pWal);
|
code = walSaveMeta(pWal);
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
goto END;
|
goto END;
|
||||||
|
@ -369,23 +356,27 @@ int32_t walEndSnapshot(SWal *pWal) {
|
||||||
|
|
||||||
// delete files
|
// delete files
|
||||||
deleteCnt = taosArrayGetSize(pWal->toDeleteFiles);
|
deleteCnt = taosArrayGetSize(pWal->toDeleteFiles);
|
||||||
wDebug("vgId:%d, wal should delete %d files", pWal->cfg.vgId, deleteCnt);
|
char fnameStr[WAL_FILE_LEN] = {0};
|
||||||
char fnameStr[WAL_FILE_LEN];
|
pInfo = NULL;
|
||||||
|
|
||||||
for (int i = 0; i < deleteCnt; i++) {
|
for (int i = 0; i < deleteCnt; i++) {
|
||||||
pInfo = taosArrayGet(pWal->toDeleteFiles, i);
|
pInfo = taosArrayGet(pWal->toDeleteFiles, i);
|
||||||
|
|
||||||
walBuildLogName(pWal, pInfo->firstVer, fnameStr);
|
walBuildLogName(pWal, pInfo->firstVer, fnameStr);
|
||||||
wDebug("vgId:%d, wal remove file %s", pWal->cfg.vgId, fnameStr);
|
|
||||||
if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
|
if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
|
||||||
wError("vgId:%d, failed to remove log file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
|
wError("vgId:%d, failed to remove log file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
walBuildIdxName(pWal, pInfo->firstVer, fnameStr);
|
walBuildIdxName(pWal, pInfo->firstVer, fnameStr);
|
||||||
wDebug("vgId:%d, wal remove file %s", pWal->cfg.vgId, fnameStr);
|
|
||||||
if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
|
if (taosRemoveFile(fnameStr) < 0 && errno != ENOENT) {
|
||||||
wError("vgId:%d, failed to remove idx file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
|
wError("vgId:%d, failed to remove idx file %s due to %s", pWal->cfg.vgId, fnameStr, strerror(errno));
|
||||||
goto END;
|
goto END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pInfo != NULL) {
|
||||||
|
wInfo("vgId:%d, wal log files recycled. count:%d, until ver:%" PRId64 ", closeTs:%" PRId64, pWal->cfg.vgId,
|
||||||
|
deleteCnt, pInfo->lastVer, pInfo->closeTs);
|
||||||
|
}
|
||||||
taosArrayClear(pWal->toDeleteFiles);
|
taosArrayClear(pWal->toDeleteFiles);
|
||||||
|
|
||||||
END:
|
END:
|
||||||
|
|
|
@ -171,7 +171,7 @@ void taosGetSystemLocale(char *outLocale, char *outCharset) {
|
||||||
strcpy(outLocale, "en_US.UTF-8");
|
strcpy(outLocale, "en_US.UTF-8");
|
||||||
} else {
|
} else {
|
||||||
tstrncpy(outLocale, locale, TD_LOCALE_LEN);
|
tstrncpy(outLocale, locale, TD_LOCALE_LEN);
|
||||||
printf("locale not configured, set to system default:%s\n", outLocale);
|
//printf("locale not configured, set to system default:%s\n", outLocale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if user does not specify the charset, extract it from locale
|
// if user does not specify the charset, extract it from locale
|
||||||
|
|
|
@ -308,17 +308,19 @@ int32_t compareInt8Uint16(const void *pLeft, const void *pRight) {
|
||||||
|
|
||||||
int32_t compareInt8Uint32(const void *pLeft, const void *pRight) {
|
int32_t compareInt8Uint32(const void *pLeft, const void *pRight) {
|
||||||
int8_t left = GET_INT8_VAL(pLeft);
|
int8_t left = GET_INT8_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint32_t right = GET_UINT32_VAL(pRight);
|
uint32_t right = GET_UINT32_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint32_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint32_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt8Uint64(const void *pLeft, const void *pRight) {
|
int32_t compareInt8Uint64(const void *pLeft, const void *pRight) {
|
||||||
int8_t left = GET_INT8_VAL(pLeft);
|
int8_t left = GET_INT8_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint64_t right = GET_UINT64_VAL(pRight);
|
uint64_t right = GET_UINT64_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint64_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint64_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,17 +382,19 @@ int32_t compareInt16Uint16(const void *pLeft, const void *pRight) {
|
||||||
|
|
||||||
int32_t compareInt16Uint32(const void *pLeft, const void *pRight) {
|
int32_t compareInt16Uint32(const void *pLeft, const void *pRight) {
|
||||||
int16_t left = GET_INT16_VAL(pLeft);
|
int16_t left = GET_INT16_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint32_t right = GET_UINT32_VAL(pRight);
|
uint32_t right = GET_UINT32_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint32_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint32_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt16Uint64(const void *pLeft, const void *pRight) {
|
int32_t compareInt16Uint64(const void *pLeft, const void *pRight) {
|
||||||
int16_t left = GET_INT16_VAL(pLeft);
|
int16_t left = GET_INT16_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint64_t right = GET_UINT64_VAL(pRight);
|
uint64_t right = GET_UINT64_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint64_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint64_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,17 +456,19 @@ int32_t compareInt32Uint16(const void *pLeft, const void *pRight) {
|
||||||
|
|
||||||
int32_t compareInt32Uint32(const void *pLeft, const void *pRight) {
|
int32_t compareInt32Uint32(const void *pLeft, const void *pRight) {
|
||||||
int32_t left = GET_INT32_VAL(pLeft);
|
int32_t left = GET_INT32_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint32_t right = GET_UINT32_VAL(pRight);
|
uint32_t right = GET_UINT32_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint32_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint32_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareInt32Uint64(const void *pLeft, const void *pRight) {
|
int32_t compareInt32Uint64(const void *pLeft, const void *pRight) {
|
||||||
int32_t left = GET_INT32_VAL(pLeft);
|
int32_t left = GET_INT32_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint64_t right = GET_UINT64_VAL(pRight);
|
uint64_t right = GET_UINT64_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint64_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint64_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,9 +538,10 @@ int32_t compareInt64Uint32(const void *pLeft, const void *pRight) {
|
||||||
|
|
||||||
int32_t compareInt64Uint64(const void *pLeft, const void *pRight) {
|
int32_t compareInt64Uint64(const void *pLeft, const void *pRight) {
|
||||||
int64_t left = GET_INT64_VAL(pLeft);
|
int64_t left = GET_INT64_VAL(pLeft);
|
||||||
|
if (left < 0) return -1;
|
||||||
uint64_t right = GET_UINT64_VAL(pRight);
|
uint64_t right = GET_UINT64_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if ((uint64_t)left > right) return 1;
|
||||||
if (left < right) return -1;
|
if ((uint64_t)left < right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -857,24 +864,27 @@ int32_t compareUint16Uint64(const void *pLeft, const void *pRight) {
|
||||||
int32_t compareUint32Int8(const void *pLeft, const void *pRight) {
|
int32_t compareUint32Int8(const void *pLeft, const void *pRight) {
|
||||||
uint32_t left = GET_UINT32_VAL(pLeft);
|
uint32_t left = GET_UINT32_VAL(pLeft);
|
||||||
int8_t right = GET_INT8_VAL(pRight);
|
int8_t right = GET_INT8_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint32_t)right) return 1;
|
||||||
|
if (left < (uint32_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareUint32Int16(const void *pLeft, const void *pRight) {
|
int32_t compareUint32Int16(const void *pLeft, const void *pRight) {
|
||||||
uint32_t left = GET_UINT32_VAL(pLeft);
|
uint32_t left = GET_UINT32_VAL(pLeft);
|
||||||
int16_t right = GET_INT16_VAL(pRight);
|
int16_t right = GET_INT16_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint32_t)right) return 1;
|
||||||
|
if (left < (uint32_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareUint32Int32(const void *pLeft, const void *pRight) {
|
int32_t compareUint32Int32(const void *pLeft, const void *pRight) {
|
||||||
uint32_t left = GET_UINT32_VAL(pLeft);
|
uint32_t left = GET_UINT32_VAL(pLeft);
|
||||||
int32_t right = GET_INT32_VAL(pRight);
|
int32_t right = GET_INT32_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint32_t)right) return 1;
|
||||||
|
if (left < (uint32_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,32 +939,36 @@ int32_t compareUint32Uint64(const void *pLeft, const void *pRight) {
|
||||||
int32_t compareUint64Int8(const void *pLeft, const void *pRight) {
|
int32_t compareUint64Int8(const void *pLeft, const void *pRight) {
|
||||||
uint64_t left = GET_UINT64_VAL(pLeft);
|
uint64_t left = GET_UINT64_VAL(pLeft);
|
||||||
int8_t right = GET_INT8_VAL(pRight);
|
int8_t right = GET_INT8_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint64_t)right) return 1;
|
||||||
|
if (left < (uint64_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareUint64Int16(const void *pLeft, const void *pRight) {
|
int32_t compareUint64Int16(const void *pLeft, const void *pRight) {
|
||||||
uint64_t left = GET_UINT64_VAL(pLeft);
|
uint64_t left = GET_UINT64_VAL(pLeft);
|
||||||
int16_t right = GET_INT16_VAL(pRight);
|
int16_t right = GET_INT16_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint64_t)right) return 1;
|
||||||
|
if (left < (uint64_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareUint64Int32(const void *pLeft, const void *pRight) {
|
int32_t compareUint64Int32(const void *pLeft, const void *pRight) {
|
||||||
uint64_t left = GET_UINT64_VAL(pLeft);
|
uint64_t left = GET_UINT64_VAL(pLeft);
|
||||||
int32_t right = GET_INT32_VAL(pRight);
|
int32_t right = GET_INT32_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint64_t)right) return 1;
|
||||||
|
if (left < (uint64_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t compareUint64Int64(const void *pLeft, const void *pRight) {
|
int32_t compareUint64Int64(const void *pLeft, const void *pRight) {
|
||||||
uint64_t left = GET_UINT64_VAL(pLeft);
|
uint64_t left = GET_UINT64_VAL(pLeft);
|
||||||
int64_t right = GET_INT64_VAL(pRight);
|
int64_t right = GET_INT64_VAL(pRight);
|
||||||
if (left > right) return 1;
|
if (right < 0) return 1;
|
||||||
if (left < right) return -1;
|
if (left > (uint64_t)right) return 1;
|
||||||
|
if (left < (uint64_t)right) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_NO_WRITE_AUTH, "No write permission")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, "Connection killed")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, "Connection killed")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, "Syntax error in SQL")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, "Syntax error in SQL")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, "Database not specified or available")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, "Database not specified or available")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, "Table does not exist")
|
//TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, "Table does not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, "SQL statement too long")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY, "File is empty")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_FILE_EMPTY, "File is empty")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_LINE_SYNTAX_ERROR, "Syntax error in Line")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_LINE_SYNTAX_ERROR, "Syntax error in Line")
|
||||||
|
@ -203,6 +203,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_COLUMN_ALREADY_EXIST, "Column already exists
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_COLUMN_NOT_EXIST, "Column does not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_COLUMN_NOT_EXIST, "Column does not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STB_OPTION, "Invalid stable options")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STB_OPTION, "Invalid stable options")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ROW_BYTES, "Invalid row bytes")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ROW_BYTES, "Invalid row bytes")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_FIELD_VALUE_OVERFLOW, "out of range and overflow")
|
||||||
|
|
||||||
// mnode-func
|
// mnode-func
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_NAME, "Invalid func name")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_NAME, "Invalid func name")
|
||||||
|
|
|
@ -136,6 +136,7 @@
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/sysinfo.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/sysinfo.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_control.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_control.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_manage.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_manage.py
|
||||||
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/user_privilege.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/fsync.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/fsync.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/multilevel.py
|
||||||
,,n,system-test,python3 ./test.py -f 0-others/compatibility.py
|
,,n,system-test,python3 ./test.py -f 0-others/compatibility.py
|
||||||
|
|
|
@ -79,7 +79,7 @@ md5sum /home/TDinternal/debug/build/lib/libtaos.so
|
||||||
#define taospy 2.7.6
|
#define taospy 2.7.6
|
||||||
pip3 list|grep taospy
|
pip3 list|grep taospy
|
||||||
pip3 uninstall taospy -y
|
pip3 uninstall taospy -y
|
||||||
pip3 install taospy==2.7.6
|
pip3 install --default-timeout=120 taospy==2.7.6
|
||||||
|
|
||||||
$TIMEOUT_CMD $cmd
|
$TIMEOUT_CMD $cmd
|
||||||
RET=$?
|
RET=$?
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import requests
|
import requests
|
||||||
|
@ -238,17 +239,7 @@ def start_taosd():
|
||||||
start_cmd = 'cd %s && python3 test.py >>/dev/null '%(start_path)
|
start_cmd = 'cd %s && python3 test.py >>/dev/null '%(start_path)
|
||||||
os.system(start_cmd)
|
os.system(start_cmd)
|
||||||
|
|
||||||
def get_cmds(args_list):
|
def get_cmds(args_list):
|
||||||
# build_path = get_path()
|
|
||||||
# if repo == "community":
|
|
||||||
# crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
|
||||||
# elif repo == "TDengine":
|
|
||||||
# crash_gen_path = build_path[:-5]+"/tests/pytest/"
|
|
||||||
# else:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550 '%(crash_gen_path)
|
|
||||||
|
|
||||||
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
||||||
return crash_gen_cmd
|
return crash_gen_cmd
|
||||||
|
|
||||||
|
@ -295,7 +286,7 @@ def check_status():
|
||||||
elif "Crash_Gen is now exiting with status code: 0" in run_code:
|
elif "Crash_Gen is now exiting with status code: 0" in run_code:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -310,7 +301,7 @@ def main():
|
||||||
|
|
||||||
|
|
||||||
build_path = get_path()
|
build_path = get_path()
|
||||||
os.system("pip install git+https://github.com/taosdata/taos-connector-python.git")
|
|
||||||
if repo =="community":
|
if repo =="community":
|
||||||
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
||||||
elif repo =="TDengine":
|
elif repo =="TDengine":
|
||||||
|
@ -334,7 +325,9 @@ def main():
|
||||||
if not os.path.exists(run_dir):
|
if not os.path.exists(run_dir):
|
||||||
os.mkdir(run_dir)
|
os.mkdir(run_dir)
|
||||||
print(crash_cmds)
|
print(crash_cmds)
|
||||||
|
starttime = datetime.datetime.now()
|
||||||
run_crash_gen(crash_cmds)
|
run_crash_gen(crash_cmds)
|
||||||
|
endtime = datetime.datetime.now()
|
||||||
status = check_status()
|
status = check_status()
|
||||||
|
|
||||||
print("exit status : ", status)
|
print("exit status : ", status)
|
||||||
|
@ -349,7 +342,29 @@ def main():
|
||||||
print('======== crash_gen run sucess and exit as expected ========')
|
print('======== crash_gen run sucess and exit as expected ========')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n " + f" and git commit : {git_commit}"
|
cmd = crash_cmds.split('&')[2]
|
||||||
|
if status == 0:
|
||||||
|
log_dir = "none"
|
||||||
|
else:
|
||||||
|
log_dir= "/root/pxiao/crash_gen_logs"
|
||||||
|
|
||||||
|
if status == 3:
|
||||||
|
core_dir = "/root/pxiao/crash_gen_logs"
|
||||||
|
else:
|
||||||
|
core_dir = "none"
|
||||||
|
|
||||||
|
text = f'''
|
||||||
|
exit status: {msg_dict[status]}
|
||||||
|
test scope: crash_gen
|
||||||
|
owner: pxiao
|
||||||
|
hostname: {hostname}
|
||||||
|
start time: {starttime}
|
||||||
|
end time: {endtime}
|
||||||
|
git commit : {git_commit}
|
||||||
|
log dir: {log_dir}
|
||||||
|
core dir: {core_dir}
|
||||||
|
cmd: {cmd}'''
|
||||||
|
|
||||||
send_msg(get_msg(text))
|
send_msg(get_msg(text))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("exception:", e)
|
print("exception:", e)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import requests
|
import requests
|
||||||
|
@ -241,15 +242,6 @@ def start_taosd():
|
||||||
os.system(start_cmd +">>/dev/null")
|
os.system(start_cmd +">>/dev/null")
|
||||||
|
|
||||||
def get_cmds(args_list):
|
def get_cmds(args_list):
|
||||||
# build_path = get_path()
|
|
||||||
# if repo == "community":
|
|
||||||
# crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
|
||||||
# elif repo == "TDengine":
|
|
||||||
# crash_gen_path = build_path[:-5]+"/tests/pytest/"
|
|
||||||
# else:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550 '%(crash_gen_path)
|
|
||||||
|
|
||||||
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
||||||
return crash_gen_cmd
|
return crash_gen_cmd
|
||||||
|
@ -343,7 +335,6 @@ def main():
|
||||||
args = limits(args)
|
args = limits(args)
|
||||||
|
|
||||||
build_path = get_path()
|
build_path = get_path()
|
||||||
os.system("pip install git+https://github.com/taosdata/taos-connector-python.git >>/dev/null")
|
|
||||||
if repo =="community":
|
if repo =="community":
|
||||||
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
||||||
elif repo =="TDengine":
|
elif repo =="TDengine":
|
||||||
|
@ -368,7 +359,9 @@ def main():
|
||||||
if not os.path.exists(run_dir):
|
if not os.path.exists(run_dir):
|
||||||
os.mkdir(run_dir)
|
os.mkdir(run_dir)
|
||||||
print(crash_cmds)
|
print(crash_cmds)
|
||||||
|
starttime = datetime.datetime.now()
|
||||||
run_crash_gen(crash_cmds)
|
run_crash_gen(crash_cmds)
|
||||||
|
endtime = datetime.datetime.now()
|
||||||
status = check_status()
|
status = check_status()
|
||||||
# back_path = os.path.join(core_path,"valgrind_report")
|
# back_path = os.path.join(core_path,"valgrind_report")
|
||||||
|
|
||||||
|
@ -384,8 +377,30 @@ def main():
|
||||||
print('======== crash_gen run sucess and exit as expected ========')
|
print('======== crash_gen run sucess and exit as expected ========')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n " + f" and git commit : {git_commit}"
|
cmd = crash_cmds.split('&')[2]
|
||||||
send_msg(get_msg(text))
|
if status == 0:
|
||||||
|
log_dir = "none"
|
||||||
|
else:
|
||||||
|
log_dir= "/root/pxiao/crash_gen_logs"
|
||||||
|
|
||||||
|
if status == 3:
|
||||||
|
core_dir = "/root/pxiao/crash_gen_logs"
|
||||||
|
else:
|
||||||
|
core_dir = "none"
|
||||||
|
|
||||||
|
text = f'''
|
||||||
|
exit status: {msg_dict[status]}
|
||||||
|
test scope: crash_gen
|
||||||
|
owner: pxiao
|
||||||
|
hostname: {hostname}
|
||||||
|
start time: {starttime}
|
||||||
|
end time: {endtime}
|
||||||
|
git commit : {git_commit}
|
||||||
|
log dir: {log_dir}
|
||||||
|
core dir: {core_dir}
|
||||||
|
cmd: {cmd}'''
|
||||||
|
|
||||||
|
send_msg(get_msg(text))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("exception:", e)
|
print("exception:", e)
|
||||||
exit(status)
|
exit(status)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import socket
|
import socket
|
||||||
import requests
|
import requests
|
||||||
|
@ -241,16 +242,7 @@ def start_taosd():
|
||||||
os.system(start_cmd +">>/dev/null")
|
os.system(start_cmd +">>/dev/null")
|
||||||
|
|
||||||
def get_cmds(args_list):
|
def get_cmds(args_list):
|
||||||
# build_path = get_path()
|
|
||||||
# if repo == "community":
|
|
||||||
# crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
|
||||||
# elif repo == "TDengine":
|
|
||||||
# crash_gen_path = build_path[:-5]+"/tests/pytest/"
|
|
||||||
# else:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# crash_gen_cmd = 'cd %s && ./crash_gen.sh --valgrind -p -t 10 -s 1000 -g 0x32c,0x32d,0x3d3,0x18,0x2501,0x369,0x388,0x061a,0x2550 '%(crash_gen_path)
|
|
||||||
|
|
||||||
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
crash_gen_cmd = get_auto_mix_cmds(args_list,valgrind=valgrind_mode)
|
||||||
return crash_gen_cmd
|
return crash_gen_cmd
|
||||||
|
|
||||||
|
@ -342,8 +334,7 @@ def main():
|
||||||
args = random_args(args_list)
|
args = random_args(args_list)
|
||||||
args = limits(args)
|
args = limits(args)
|
||||||
|
|
||||||
build_path = get_path()
|
build_path = get_path()
|
||||||
os.system("pip install git+https://github.com/taosdata/taos-connector-python.git >>/dev/null")
|
|
||||||
if repo =="community":
|
if repo =="community":
|
||||||
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
crash_gen_path = build_path[:-5]+"community/tests/pytest/"
|
||||||
elif repo =="TDengine":
|
elif repo =="TDengine":
|
||||||
|
@ -368,7 +359,9 @@ def main():
|
||||||
if not os.path.exists(run_dir):
|
if not os.path.exists(run_dir):
|
||||||
os.mkdir(run_dir)
|
os.mkdir(run_dir)
|
||||||
print(crash_cmds)
|
print(crash_cmds)
|
||||||
|
starttime = datetime.datetime.now()
|
||||||
run_crash_gen(crash_cmds)
|
run_crash_gen(crash_cmds)
|
||||||
|
endtime = datetime.datetime.now()
|
||||||
status = check_status()
|
status = check_status()
|
||||||
# back_path = os.path.join(core_path,"valgrind_report")
|
# back_path = os.path.join(core_path,"valgrind_report")
|
||||||
|
|
||||||
|
@ -384,7 +377,29 @@ def main():
|
||||||
print('======== crash_gen run sucess and exit as expected ========')
|
print('======== crash_gen run sucess and exit as expected ========')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
text = f"crash_gen instance exit status of docker [ {hostname} ] is : {msg_dict[status]}\n " + f" and git commit : {git_commit}"
|
cmd = crash_cmds.split('&')[2]
|
||||||
|
if status == 0:
|
||||||
|
log_dir = "none"
|
||||||
|
else:
|
||||||
|
log_dir= "/root/pxiao/crash_gen_logs"
|
||||||
|
|
||||||
|
if status == 3:
|
||||||
|
core_dir = "/root/pxiao/crash_gen_logs"
|
||||||
|
else:
|
||||||
|
core_dir = "none"
|
||||||
|
|
||||||
|
text = f'''
|
||||||
|
exit status: {msg_dict[status]}
|
||||||
|
test scope: crash_gen
|
||||||
|
owner: pxiao
|
||||||
|
hostname: {hostname}
|
||||||
|
start time: {starttime}
|
||||||
|
end time: {endtime}
|
||||||
|
git commit : {git_commit}
|
||||||
|
log dir: {log_dir}
|
||||||
|
core dir: {core_dir}
|
||||||
|
cmd: {cmd}'''
|
||||||
|
|
||||||
send_msg(get_msg(text))
|
send_msg(get_msg(text))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("exception:", e)
|
print("exception:", e)
|
||||||
|
|
|
@ -52,8 +52,9 @@ class ConfigureyCluster:
|
||||||
dnode.addExtraCfg("secondEp", f"{hostname}:{startPort_sec}")
|
dnode.addExtraCfg("secondEp", f"{hostname}:{startPort_sec}")
|
||||||
|
|
||||||
# configure dnoe of independent mnodes
|
# configure dnoe of independent mnodes
|
||||||
if num <= self.mnodeNums and self.mnodeNums != 0 and independentMnode == True :
|
if num <= self.mnodeNums and self.mnodeNums != 0 and independentMnode == "True" :
|
||||||
dnode.addExtraCfg("supportVnodes", 1024)
|
tdLog.info("set mnode supportVnodes 0")
|
||||||
|
dnode.addExtraCfg("supportVnodes", 0)
|
||||||
# print(dnode)
|
# print(dnode)
|
||||||
self.dnodes.append(dnode)
|
self.dnodes.append(dnode)
|
||||||
return self.dnodes
|
return self.dnodes
|
||||||
|
@ -71,6 +72,7 @@ class ConfigureyCluster:
|
||||||
tdSql.init(conn.cursor())
|
tdSql.init(conn.cursor())
|
||||||
mnodeNums=int(mnodeNums)
|
mnodeNums=int(mnodeNums)
|
||||||
for i in range(2,mnodeNums+1):
|
for i in range(2,mnodeNums+1):
|
||||||
|
tdLog.info("create mnode on dnode %d"%i)
|
||||||
tdSql.execute(" create mnode on dnode %d;"%i)
|
tdSql.execute(" create mnode on dnode %d;"%i)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -657,6 +657,17 @@ if $data20 != null then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
|
print =============== error
|
||||||
|
sql create table tb2023(ts timestamp, f int);
|
||||||
|
sql_error alter table tb2023 add column v varchar(16375);
|
||||||
|
sql_error alter table tb2023 add column v varchar(16385);
|
||||||
|
sql_error alter table tb2023 add column v varchar(33100);
|
||||||
|
sql alter table tb2023 add column v varchar(16374);
|
||||||
|
sql desc tb2023
|
||||||
|
sql alter table tb2023 drop column v
|
||||||
|
sql_error alter table tb2023 add column v nchar(4094);
|
||||||
|
sql alter table tb2023 add column v nchar(4093);
|
||||||
|
sql desc tb2023
|
||||||
print ======= over
|
print ======= over
|
||||||
sql drop database d1
|
sql drop database d1
|
||||||
sql select * from information_schema.ins_databases
|
sql select * from information_schema.ins_databases
|
||||||
|
|
|
@ -58,16 +58,16 @@ if $data23 != 0 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
print ========== stop dnode2
|
#print ========== stop dnode2
|
||||||
system sh/exec.sh -n dnode2 -s stop -x SIGKILL
|
#system sh/exec.sh -n dnode2 -s stop -x SIGKILL
|
||||||
|
|
||||||
sleep 1000
|
#sleep 1000
|
||||||
print =============== drop database
|
#print =============== drop database
|
||||||
sql_error drop database d1
|
sql drop database d1
|
||||||
|
|
||||||
print ========== start dnode2
|
#print ========== start dnode2
|
||||||
system sh/exec.sh -n dnode2 -s start
|
#system sh/exec.sh -n dnode2 -s start
|
||||||
sleep 1000
|
#sleep 1000
|
||||||
|
|
||||||
print =============== re-create database
|
print =============== re-create database
|
||||||
$x = 0
|
$x = 0
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
###################################################################
|
||||||
|
# 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 taos
|
||||||
|
from taos.tmq import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.common import *
|
||||||
|
from util.log import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.sqlset import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
self.replicaVar = int(replicaVar)
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
self.setsql = TDSetSql()
|
||||||
|
self.stbname = 'stb'
|
||||||
|
self.binary_length = 20 # the length of binary for column_dict
|
||||||
|
self.nchar_length = 20 # the length of nchar for column_dict
|
||||||
|
self.column_dict = {
|
||||||
|
'ts': 'timestamp',
|
||||||
|
'col1': 'float',
|
||||||
|
'col2': 'int',
|
||||||
|
'col3': 'float',
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tag_dict = {
|
||||||
|
't1': 'int',
|
||||||
|
't2': f'binary({self.binary_length})'
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tag_list = [
|
||||||
|
f'1, "Beijing"',
|
||||||
|
f'2, "Shanghai"',
|
||||||
|
f'3, "Guangzhou"',
|
||||||
|
f'4, "Shenzhen"'
|
||||||
|
]
|
||||||
|
|
||||||
|
self.values_list = [
|
||||||
|
f'now, 9.1, 200, 0.3'
|
||||||
|
]
|
||||||
|
|
||||||
|
self.tbnum = 4
|
||||||
|
|
||||||
|
def create_user(self):
|
||||||
|
user_name = 'test'
|
||||||
|
tdSql.execute(f'create user {user_name} pass "test"')
|
||||||
|
tdSql.execute(f'grant read on db.stb with t2 = "Beijing" to {user_name}')
|
||||||
|
|
||||||
|
def prepare_data(self):
|
||||||
|
tdSql.execute(self.setsql.set_create_stable_sql(self.stbname, self.column_dict, self.tag_dict))
|
||||||
|
for i in range(self.tbnum):
|
||||||
|
tdSql.execute(f'create table {self.stbname}_{i} using {self.stbname} tags({self.tag_list[i]})')
|
||||||
|
for j in self.values_list:
|
||||||
|
tdSql.execute(f'insert into {self.stbname}_{i} values({j})')
|
||||||
|
|
||||||
|
def user_privilege_check(self):
|
||||||
|
testconn = taos.connect(user='test', password='test')
|
||||||
|
expectErrNotOccured = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
sql = "select count(*) from db.stb where t2 = 'Beijing'"
|
||||||
|
res = testconn.query(sql)
|
||||||
|
data = res.fetch_all()
|
||||||
|
count = data[0][0]
|
||||||
|
except BaseException:
|
||||||
|
expectErrNotOccured = True
|
||||||
|
|
||||||
|
if expectErrNotOccured:
|
||||||
|
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||||
|
tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured")
|
||||||
|
elif count != 1:
|
||||||
|
tdLog.exit(f"{sql}, expect result doesn't match")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def user_privilege_error_check(self):
|
||||||
|
testconn = taos.connect(user='test', password='test')
|
||||||
|
expectErrNotOccured = False
|
||||||
|
|
||||||
|
sql_list = ["alter talbe db.stb_1 set t2 = 'Wuhan'", "drop table db.stb_1"]
|
||||||
|
|
||||||
|
for sql in sql_list:
|
||||||
|
try:
|
||||||
|
res = testconn.execute(sql)
|
||||||
|
except BaseException:
|
||||||
|
expectErrNotOccured = True
|
||||||
|
|
||||||
|
if expectErrNotOccured:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||||
|
tdLog.exit(f"{caller.filename}({caller.lineno}) failed: sql:{sql}, expect error not occured")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
self.prepare_data()
|
||||||
|
self.create_user()
|
||||||
|
self.user_privilege_check()
|
||||||
|
self.user_privilege_error_check()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -34,6 +34,9 @@ class TDTestCase:
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
tdLog.info("sml_test ret != 0")
|
tdLog.info("sml_test ret != 0")
|
||||||
|
|
||||||
|
tdSql.query(f"select * from ts3303.stb2")
|
||||||
|
tdSql.query(f"select * from ts3303.meters")
|
||||||
|
|
||||||
# tdSql.execute('use sml_db')
|
# tdSql.execute('use sml_db')
|
||||||
tdSql.query(f"select * from {dbname}.t_b7d815c9222ca64cdf2614c61de8f211")
|
tdSql.query(f"select * from {dbname}.t_b7d815c9222ca64cdf2614c61de8f211")
|
||||||
tdSql.checkRows(1)
|
tdSql.checkRows(1)
|
||||||
|
|
|
@ -207,7 +207,7 @@ class ClusterComCheck:
|
||||||
count+=1
|
count+=1
|
||||||
else:
|
else:
|
||||||
tdLog.debug(tdSql.queryResult)
|
tdLog.debug(tdSql.queryResult)
|
||||||
tdLog.exit("stop mnodes on dnode %d failed in 10s ")
|
tdLog.exit(f"stop mnodes on dnode {offlineDnodeNo} failed in 10s ")
|
||||||
|
|
||||||
def check3mnode2off(self,mnodeNums=3):
|
def check3mnode2off(self,mnodeNums=3):
|
||||||
count=0
|
count=0
|
||||||
|
@ -226,7 +226,45 @@ class ClusterComCheck:
|
||||||
count+=1
|
count+=1
|
||||||
else:
|
else:
|
||||||
tdLog.debug(tdSql.queryResult)
|
tdLog.debug(tdSql.queryResult)
|
||||||
tdLog.exit("stop mnodes on dnode %d failed in 10s ")
|
tdLog.exit("stop mnodes on dnode 2 or 3 failed in 10s")
|
||||||
|
|
||||||
|
def check_vgroups_status(self,vgroup_numbers=2,db_replica=3,count_number=10,db_name="db"):
|
||||||
|
""" check vgroups status in 10s after db vgroups status is changed """
|
||||||
|
vgroup_numbers = int(vgroup_numbers)
|
||||||
|
self.db_replica = int(db_replica)
|
||||||
|
tdLog.debug("start to check status of vgroups")
|
||||||
|
count=0
|
||||||
|
last_number=vgroup_numbers-1
|
||||||
|
while count < count_number:
|
||||||
|
time.sleep(1)
|
||||||
|
tdSql.query(f"show {db_name}.vgroups;")
|
||||||
|
if count == 0 :
|
||||||
|
if tdSql.checkRows(vgroup_numbers) :
|
||||||
|
tdLog.success(f"{db_name} has {vgroup_numbers} vgroups" )
|
||||||
|
else:
|
||||||
|
tdLog.exit(f"vgroup number of {db_name} is not correct")
|
||||||
|
if self.db_replica == 1 :
|
||||||
|
if tdSql.queryResult[0][4] == 'leader' and tdSql.queryResult[1][4] == 'leader' and tdSql.queryResult[last_number][4] == 'leader':
|
||||||
|
ready_time= (count + 1)
|
||||||
|
tdLog.success(f"all vgroups of {db_name} are leaders in {count + 1} s")
|
||||||
|
return True
|
||||||
|
count+=1
|
||||||
|
elif self.db_replica == 3 :
|
||||||
|
vgroup_status_first=[tdSql.queryResult[0][4],tdSql.queryResult[0][6],tdSql.queryResult[0][8]]
|
||||||
|
|
||||||
|
vgroup_status_last=[tdSql.queryResult[last_number][4],tdSql.queryResult[last_number][6],tdSql.queryResult[last_number][8]]
|
||||||
|
if vgroup_status_first.count('leader') == 1 and vgroup_status_first.count('follower') == 2:
|
||||||
|
if vgroup_status_last.count('leader') == 1 and vgroup_status_last.count('follower') == 2:
|
||||||
|
ready_time= (count + 1)
|
||||||
|
tdLog.success(f"all vgroups of {db_name} are ready in {ready_time} s")
|
||||||
|
return True
|
||||||
|
count+=1
|
||||||
|
else:
|
||||||
|
tdLog.debug(tdSql.queryResult)
|
||||||
|
tdLog.notice(f"all vgroups leader of {db_name} is selected {count}s ")
|
||||||
|
caller = inspect.getframeinfo(inspect.stack()[1][0])
|
||||||
|
args = (caller.filename, caller.lineno)
|
||||||
|
tdLog.exit("%s(%d) failed " % args)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
import taos
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.dnodes import TDDnodes
|
||||||
|
from util.dnodes import TDDnode
|
||||||
|
from util.cluster import *
|
||||||
|
sys.path.append("./6-cluster")
|
||||||
|
from clusterCommonCreate import *
|
||||||
|
from clusterCommonCheck import clusterComCheck
|
||||||
|
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
from multiprocessing import Process
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import inspect
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
self.TDDnodes = None
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
|
||||||
|
|
||||||
|
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 _async_raise(self, tid, exctype):
|
||||||
|
"""raises the exception, performs cleanup if needed"""
|
||||||
|
if not inspect.isclass(exctype):
|
||||||
|
exctype = type(exctype)
|
||||||
|
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
|
||||||
|
if res == 0:
|
||||||
|
raise ValueError("invalid thread id")
|
||||||
|
elif res != 1:
|
||||||
|
# """if it returns a number greater than one, you're in trouble,
|
||||||
|
# and you should call it again with exc=NULL to revert the effect"""
|
||||||
|
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
|
||||||
|
raise SystemError("PyThreadState_SetAsyncExc failed")
|
||||||
|
|
||||||
|
def stopThread(self,thread):
|
||||||
|
self._async_raise(thread.ident, SystemExit)
|
||||||
|
|
||||||
|
|
||||||
|
def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
|
||||||
|
tdLog.printNoPrefix("======== test case 1: ")
|
||||||
|
paraDict = {'dbName': 'db0_0',
|
||||||
|
'dropFlag': 1,
|
||||||
|
'event': '',
|
||||||
|
'vgroups': 4,
|
||||||
|
'replica': 1,
|
||||||
|
'stbName': 'stb',
|
||||||
|
'stbNumbers': 2,
|
||||||
|
'colPrefix': 'c',
|
||||||
|
'tagPrefix': 't',
|
||||||
|
'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'ctbPrefix': 'ctb',
|
||||||
|
'ctbNum': 200,
|
||||||
|
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||||
|
"rowsPerTbl": 1000,
|
||||||
|
"batchNum": 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeNumbers=int(dnodeNumbers)
|
||||||
|
mnodeNums=int(mnodeNums)
|
||||||
|
vnodeNumbers = int(dnodeNumbers-mnodeNums)
|
||||||
|
allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
|
||||||
|
rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
|
||||||
|
rowsall=rowsPerStb*paraDict['stbNumbers']
|
||||||
|
dbNumbers = 1
|
||||||
|
|
||||||
|
tdLog.info("first check dnode and mnode")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
tdSql.checkData(0,1,'%s:6030'%self.host)
|
||||||
|
tdSql.checkData(4,1,'%s:6430'%self.host)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
#check mnode status
|
||||||
|
tdLog.info("check mnode status")
|
||||||
|
clusterComCheck.checkMnodeStatus(mnodeNums)
|
||||||
|
|
||||||
|
# add some error operations and
|
||||||
|
tdLog.info("Confirm the status of the dnode again")
|
||||||
|
tdSql.error("create mnode on dnode 2")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
print(tdSql.queryResult)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
# create database and stable
|
||||||
|
clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
|
||||||
|
tdLog.info("Take turns stopping Mnodes ")
|
||||||
|
|
||||||
|
tdDnodes=cluster.dnodes
|
||||||
|
stopcount =0
|
||||||
|
threads=[]
|
||||||
|
|
||||||
|
# create stable:stb_0
|
||||||
|
stableName= paraDict['stbName']
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
|
||||||
|
#create child table:ctb_0
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
|
||||||
|
#insert date
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
|
||||||
|
for tr in threads:
|
||||||
|
tr.start()
|
||||||
|
for tr in threads:
|
||||||
|
tr.join()
|
||||||
|
|
||||||
|
while stopcount < restartNumbers:
|
||||||
|
tdLog.info(" restart loop: %d"%stopcount )
|
||||||
|
if stopRole == "mnode":
|
||||||
|
for i in range(mnodeNums):
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "vnode":
|
||||||
|
for i in range(vnodeNumbers):
|
||||||
|
tdDnodes[i+mnodeNums].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i+mnodeNums].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "dnode":
|
||||||
|
for i in range(dnodeNumbers):
|
||||||
|
if i == 0 :
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],0)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
# newTdSql.execute('alter database db0_0 replica 3')
|
||||||
|
clusterComCreate.alterStbMetaData(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"])
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
if i == 3 :
|
||||||
|
TdSqlEx=tdCom.newTdSql()
|
||||||
|
tdLog.info("alter database db0_0 replica 3")
|
||||||
|
TdSqlEx.execute('alter database db0_0 replica 3')
|
||||||
|
|
||||||
|
|
||||||
|
# dnodeNumbers don't include database of schema
|
||||||
|
if clusterComCheck.checkDnodes(dnodeNumbers):
|
||||||
|
tdLog.info("123")
|
||||||
|
else:
|
||||||
|
print("456")
|
||||||
|
|
||||||
|
self.stopThread(threads)
|
||||||
|
tdLog.exit("one or more of dnodes failed to start ")
|
||||||
|
# self.check3mnode()
|
||||||
|
stopcount+=1
|
||||||
|
|
||||||
|
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
# clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
|
||||||
|
|
||||||
|
# tdSql.execute("use %s" %(paraDict["dbName"]))
|
||||||
|
tdSql.query("show %s.stables"%(paraDict["dbName"]))
|
||||||
|
tdSql.checkRows(paraDict["stbNumbers"])
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
|
||||||
|
tdSql.query("select count(*) from %s"%stableName)
|
||||||
|
if i == 0 :
|
||||||
|
tdSql.checkData(0,0,rowsPerStb*2)
|
||||||
|
else:
|
||||||
|
tdSql.checkData(0,0,rowsPerStb)
|
||||||
|
clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=3,db_name=paraDict["dbName"],count_number=150)
|
||||||
|
def run(self):
|
||||||
|
# print(self.master_dnode.cfgDict)
|
||||||
|
self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=1,stopRole='dnode')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,206 @@
|
||||||
|
import taos
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.dnodes import TDDnodes
|
||||||
|
from util.dnodes import TDDnode
|
||||||
|
from util.cluster import *
|
||||||
|
sys.path.append("./6-cluster")
|
||||||
|
from clusterCommonCreate import *
|
||||||
|
from clusterCommonCheck import clusterComCheck
|
||||||
|
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
from multiprocessing import Process
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import inspect
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
self.TDDnodes = None
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
|
||||||
|
|
||||||
|
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 _async_raise(self, tid, exctype):
|
||||||
|
"""raises the exception, performs cleanup if needed"""
|
||||||
|
if not inspect.isclass(exctype):
|
||||||
|
exctype = type(exctype)
|
||||||
|
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
|
||||||
|
if res == 0:
|
||||||
|
raise ValueError("invalid thread id")
|
||||||
|
elif res != 1:
|
||||||
|
# """if it returns a number greater than one, you're in trouble,
|
||||||
|
# and you should call it again with exc=NULL to revert the effect"""
|
||||||
|
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
|
||||||
|
raise SystemError("PyThreadState_SetAsyncExc failed")
|
||||||
|
|
||||||
|
def stopThread(self,thread):
|
||||||
|
self._async_raise(thread.ident, SystemExit)
|
||||||
|
|
||||||
|
|
||||||
|
def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
|
||||||
|
tdLog.printNoPrefix("======== test case 1: ")
|
||||||
|
paraDict = {'dbName': 'db0_0',
|
||||||
|
'dropFlag': 1,
|
||||||
|
'event': '',
|
||||||
|
'vgroups': 4,
|
||||||
|
'replica': 3,
|
||||||
|
'stbName': 'stb',
|
||||||
|
'stbNumbers': 2,
|
||||||
|
'colPrefix': 'c',
|
||||||
|
'tagPrefix': 't',
|
||||||
|
'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'ctbPrefix': 'ctb',
|
||||||
|
'ctbNum': 200,
|
||||||
|
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||||
|
"rowsPerTbl": 1000,
|
||||||
|
"batchNum": 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeNumbers=int(dnodeNumbers)
|
||||||
|
mnodeNums=int(mnodeNums)
|
||||||
|
vnodeNumbers = int(dnodeNumbers-mnodeNums)
|
||||||
|
allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
|
||||||
|
rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
|
||||||
|
rowsall=rowsPerStb*paraDict['stbNumbers']
|
||||||
|
dbNumbers = 1
|
||||||
|
|
||||||
|
tdLog.info("first check dnode and mnode")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
tdSql.checkData(0,1,'%s:6030'%self.host)
|
||||||
|
tdSql.checkData(4,1,'%s:6430'%self.host)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
#check mnode status
|
||||||
|
tdLog.info("check mnode status")
|
||||||
|
clusterComCheck.checkMnodeStatus(mnodeNums)
|
||||||
|
|
||||||
|
# add some error operations and
|
||||||
|
tdLog.info("Confirm the status of the dnode again")
|
||||||
|
tdSql.error("create mnode on dnode 2")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
print(tdSql.queryResult)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
# create database and stable
|
||||||
|
clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
|
||||||
|
tdLog.info("Take turns stopping Mnodes ")
|
||||||
|
|
||||||
|
tdDnodes=cluster.dnodes
|
||||||
|
stopcount =0
|
||||||
|
threads=[]
|
||||||
|
|
||||||
|
# create stable:stb_0
|
||||||
|
stableName= paraDict['stbName']
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
|
||||||
|
#create child table:ctb_0
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
|
||||||
|
#insert date
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
|
||||||
|
for tr in threads:
|
||||||
|
tr.start()
|
||||||
|
for tr in threads:
|
||||||
|
tr.join()
|
||||||
|
|
||||||
|
while stopcount < restartNumbers:
|
||||||
|
tdLog.info(" restart loop: %d"%stopcount )
|
||||||
|
if stopRole == "mnode":
|
||||||
|
for i in range(mnodeNums):
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "vnode":
|
||||||
|
for i in range(vnodeNumbers):
|
||||||
|
tdDnodes[i+mnodeNums].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i+mnodeNums].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "dnode":
|
||||||
|
for i in range(dnodeNumbers):
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
if i == 0 :
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],0)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
# newTdSql.execute('alter database db0_0 replica 3')
|
||||||
|
clusterComCreate.alterStbMetaData(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"])
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
if i == 3 :
|
||||||
|
TdSqlEx=tdCom.newTdSql()
|
||||||
|
tdLog.info("alter database db0_0 replica 1")
|
||||||
|
TdSqlEx.execute('alter database db0_0 replica 1')
|
||||||
|
|
||||||
|
|
||||||
|
# dnodeNumbers don't include database of schema
|
||||||
|
if clusterComCheck.checkDnodes(dnodeNumbers):
|
||||||
|
tdLog.info("123")
|
||||||
|
else:
|
||||||
|
print("456")
|
||||||
|
|
||||||
|
self.stopThread(threads)
|
||||||
|
tdLog.exit("one or more of dnodes failed to start ")
|
||||||
|
# self.check3mnode()
|
||||||
|
stopcount+=1
|
||||||
|
|
||||||
|
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
# clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
|
||||||
|
|
||||||
|
# tdSql.execute("use %s" %(paraDict["dbName"]))
|
||||||
|
tdSql.query("show %s.stables"%(paraDict["dbName"]))
|
||||||
|
tdSql.checkRows(paraDict["stbNumbers"])
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
|
||||||
|
tdSql.query("select count(*) from %s"%stableName)
|
||||||
|
if i == 0 :
|
||||||
|
tdSql.checkData(0,0,rowsPerStb*2)
|
||||||
|
else:
|
||||||
|
tdSql.checkData(0,0,rowsPerStb)
|
||||||
|
clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=1,db_name=paraDict["dbName"],count_number=150)
|
||||||
|
def run(self):
|
||||||
|
# print(self.master_dnode.cfgDict)
|
||||||
|
self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=1,stopRole='dnode')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,222 @@
|
||||||
|
import taos
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.dnodes import TDDnodes
|
||||||
|
from util.dnodes import TDDnode
|
||||||
|
from util.cluster import *
|
||||||
|
sys.path.append("./6-cluster")
|
||||||
|
from clusterCommonCreate import *
|
||||||
|
from clusterCommonCheck import clusterComCheck
|
||||||
|
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
from multiprocessing import Process
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import inspect
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
self.TDDnodes = None
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
|
||||||
|
|
||||||
|
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 _async_raise(self, tid, exctype):
|
||||||
|
"""raises the exception, performs cleanup if needed"""
|
||||||
|
if not inspect.isclass(exctype):
|
||||||
|
exctype = type(exctype)
|
||||||
|
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
|
||||||
|
if res == 0:
|
||||||
|
raise ValueError("invalid thread id")
|
||||||
|
elif res != 1:
|
||||||
|
# """if it returns a number greater than one, you're in trouble,
|
||||||
|
# and you should call it again with exc=NULL to revert the effect"""
|
||||||
|
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
|
||||||
|
raise SystemError("PyThreadState_SetAsyncExc failed")
|
||||||
|
|
||||||
|
def stopThread(self,thread):
|
||||||
|
self._async_raise(thread.ident, SystemExit)
|
||||||
|
|
||||||
|
|
||||||
|
def insertData(self,countstart,countstop):
|
||||||
|
# fisrt add data : db\stable\childtable\general table
|
||||||
|
|
||||||
|
for couti in range(countstart,countstop):
|
||||||
|
tdLog.debug("drop database if exists db%d" %couti)
|
||||||
|
tdSql.execute("drop database if exists db%d" %couti)
|
||||||
|
print("create database if not exists db%d replica 1 duration 300" %couti)
|
||||||
|
tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti)
|
||||||
|
tdSql.execute("use db%d" %couti)
|
||||||
|
tdSql.execute(
|
||||||
|
'''create table stb1
|
||||||
|
(ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
|
||||||
|
tags (t1 int)
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
'''
|
||||||
|
create table t1
|
||||||
|
(ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
for i in range(4):
|
||||||
|
tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )')
|
||||||
|
|
||||||
|
|
||||||
|
def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
|
||||||
|
tdLog.printNoPrefix("======== test case 1: ")
|
||||||
|
paraDict = {'dbName': 'db0_0',
|
||||||
|
'dropFlag': 1,
|
||||||
|
'event': '',
|
||||||
|
'vgroups': 4,
|
||||||
|
'replica': 1,
|
||||||
|
'stbName': 'stb',
|
||||||
|
'stbNumbers': 2,
|
||||||
|
'colPrefix': 'c',
|
||||||
|
'tagPrefix': 't',
|
||||||
|
'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'ctbPrefix': 'ctb',
|
||||||
|
'ctbNum': 1000,
|
||||||
|
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||||
|
"rowsPerTbl": 100,
|
||||||
|
"batchNum": 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeNumbers = int(dnodeNumbers)
|
||||||
|
mnodeNums = int(mnodeNums)
|
||||||
|
vnodeNumbers = int(dnodeNumbers-mnodeNums)
|
||||||
|
allctbNumbers = (paraDict['stbNumbers']*paraDict["ctbNum"])
|
||||||
|
rowsPerStb = paraDict["ctbNum"]*paraDict["rowsPerTbl"]
|
||||||
|
rowsall = rowsPerStb*paraDict['stbNumbers']
|
||||||
|
dbNumbers = 1
|
||||||
|
replica3 = 3
|
||||||
|
tdLog.info("first check dnode and mnode")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
tdSql.checkData(0,1,'%s:6030'%self.host)
|
||||||
|
tdSql.checkData(4,1,'%s:6430'%self.host)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
#check mnode status
|
||||||
|
tdLog.info("check mnode status")
|
||||||
|
clusterComCheck.checkMnodeStatus(mnodeNums)
|
||||||
|
|
||||||
|
# add some error operations and
|
||||||
|
tdLog.info("Confirm the status of the dnode again")
|
||||||
|
tdSql.error("create mnode on dnode 2")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
print(tdSql.queryResult)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
# create database and stable
|
||||||
|
clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
|
||||||
|
tdLog.info("Take turns stopping Mnodes ")
|
||||||
|
|
||||||
|
tdDnodes=cluster.dnodes
|
||||||
|
stopcount =0
|
||||||
|
threads=[]
|
||||||
|
|
||||||
|
# create stable:stb_0
|
||||||
|
stableName= paraDict['stbName']
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
|
||||||
|
#create child table:ctb_0
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
|
||||||
|
#insert date
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
|
||||||
|
for tr in threads:
|
||||||
|
tr.start()
|
||||||
|
TdSqlEx=tdCom.newTdSql()
|
||||||
|
tdLog.info("alter database db0_0 replica 3")
|
||||||
|
TdSqlEx.execute('alter database db0_0 replica 3')
|
||||||
|
while stopcount < restartNumbers:
|
||||||
|
tdLog.info(" restart loop: %d"%stopcount )
|
||||||
|
if stopRole == "mnode":
|
||||||
|
for i in range(mnodeNums):
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "vnode":
|
||||||
|
for i in range(vnodeNumbers):
|
||||||
|
tdDnodes[i+mnodeNums].stoptaosd()
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i+mnodeNums].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
elif stopRole == "dnode":
|
||||||
|
for i in range(dnodeNumbers):
|
||||||
|
tdDnodes[i].stoptaosd()
|
||||||
|
# tdLog.info('select cast(c2 as nchar(10)) from db0_0.stb_1;')
|
||||||
|
# TdSqlEx.execute('select cast(c2 as nchar(10)) from db0_0.stb_1;')
|
||||||
|
# tdLog.info('select avg(c1) from db0_0.stb_0 interval(10s);')
|
||||||
|
# TdSqlEx.execute('select avg(c1) from db0_0.stb_0 interval(10s);')
|
||||||
|
# sleep(10)
|
||||||
|
tdDnodes[i].starttaosd()
|
||||||
|
# sleep(10)
|
||||||
|
# dnodeNumbers don't include database of schema
|
||||||
|
if clusterComCheck.checkDnodes(dnodeNumbers):
|
||||||
|
tdLog.info("123")
|
||||||
|
else:
|
||||||
|
print("456")
|
||||||
|
|
||||||
|
self.stopThread(threads)
|
||||||
|
tdLog.exit("one or more of dnodes failed to start ")
|
||||||
|
# self.check3mnode()
|
||||||
|
stopcount+=1
|
||||||
|
|
||||||
|
for tr in threads:
|
||||||
|
tr.join()
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
# clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
|
||||||
|
|
||||||
|
# tdSql.execute("use %s" %(paraDict["dbName"]))
|
||||||
|
tdSql.query("show %s.stables"%(paraDict["dbName"]))
|
||||||
|
tdSql.checkRows(paraDict["stbNumbers"])
|
||||||
|
# for i in range(paraDict['stbNumbers']):
|
||||||
|
# stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
|
||||||
|
# tdSql.query("select count(*) from %s"%stableName)
|
||||||
|
# tdSql.checkData(0,0,rowsPerStb)
|
||||||
|
clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica3,db_name=paraDict["dbName"],count_number=240)
|
||||||
|
def run(self):
|
||||||
|
# print(self.master_dnode.cfgDict)
|
||||||
|
self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,196 @@
|
||||||
|
import taos
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
|
||||||
|
from util.log import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.dnodes import TDDnodes
|
||||||
|
from util.dnodes import TDDnode
|
||||||
|
from util.cluster import *
|
||||||
|
sys.path.append("./6-cluster")
|
||||||
|
from clusterCommonCreate import *
|
||||||
|
from clusterCommonCheck import clusterComCheck
|
||||||
|
|
||||||
|
import time
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
from multiprocessing import Process
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import inspect
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
self.TDDnodes = None
|
||||||
|
tdSql.init(conn.cursor())
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
|
||||||
|
|
||||||
|
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 _async_raise(self, tid, exctype):
|
||||||
|
"""raises the exception, performs cleanup if needed"""
|
||||||
|
if not inspect.isclass(exctype):
|
||||||
|
exctype = type(exctype)
|
||||||
|
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
|
||||||
|
if res == 0:
|
||||||
|
raise ValueError("invalid thread id")
|
||||||
|
elif res != 1:
|
||||||
|
# """if it returns a number greater than one, you're in trouble,
|
||||||
|
# and you should call it again with exc=NULL to revert the effect"""
|
||||||
|
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
|
||||||
|
raise SystemError("PyThreadState_SetAsyncExc failed")
|
||||||
|
|
||||||
|
def stopThread(self,thread):
|
||||||
|
self._async_raise(thread.ident, SystemExit)
|
||||||
|
|
||||||
|
|
||||||
|
def insertData(self,countstart,countstop):
|
||||||
|
# fisrt add data : db\stable\childtable\general table
|
||||||
|
|
||||||
|
for couti in range(countstart,countstop):
|
||||||
|
tdLog.debug("drop database if exists db%d" %couti)
|
||||||
|
tdSql.execute("drop database if exists db%d" %couti)
|
||||||
|
print("create database if not exists db%d replica 1 duration 300" %couti)
|
||||||
|
tdSql.execute("create database if not exists db%d replica 1 duration 300" %couti)
|
||||||
|
tdSql.execute("use db%d" %couti)
|
||||||
|
tdSql.execute(
|
||||||
|
'''create table stb1
|
||||||
|
(ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
|
||||||
|
tags (t1 int)
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
tdSql.execute(
|
||||||
|
'''
|
||||||
|
create table t1
|
||||||
|
(ts timestamp, c1 int, c2 bigint, c3 smallint, c4 tinyint, c5 float, c6 double, c7 bool, c8 binary(16),c9 nchar(32), c10 timestamp)
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
for i in range(4):
|
||||||
|
tdSql.execute(f'create table ct{i+1} using stb1 tags ( {i+1} )')
|
||||||
|
|
||||||
|
|
||||||
|
def fiveDnodeThreeMnode(self,dnodeNumbers,mnodeNums,restartNumbers,stopRole):
|
||||||
|
tdLog.printNoPrefix("======== test case 1: ")
|
||||||
|
paraDict = {'dbName': 'db0_0',
|
||||||
|
'dropFlag': 1,
|
||||||
|
'event': '',
|
||||||
|
'vgroups': 4,
|
||||||
|
'replica': 3,
|
||||||
|
'stbName': 'stb',
|
||||||
|
'stbNumbers': 2,
|
||||||
|
'colPrefix': 'c',
|
||||||
|
'tagPrefix': 't',
|
||||||
|
'colSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'tagSchema': [{'type': 'INT', 'count':1}, {'type': 'binary', 'len':20, 'count':1}],
|
||||||
|
'ctbPrefix': 'ctb',
|
||||||
|
'ctbNum': 1,
|
||||||
|
'startTs': 1640966400000, # 2022-01-01 00:00:00.000
|
||||||
|
"rowsPerTbl": 1,
|
||||||
|
"batchNum": 5000
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeNumbers=int(dnodeNumbers)
|
||||||
|
mnodeNums=int(mnodeNums)
|
||||||
|
vnodeNumbers = int(dnodeNumbers-mnodeNums)
|
||||||
|
replica1 = 1
|
||||||
|
replica3 = 3
|
||||||
|
allctbNumbers=(paraDict['stbNumbers']*paraDict["ctbNum"])
|
||||||
|
rowsPerStb=paraDict["ctbNum"]*paraDict["rowsPerTbl"]
|
||||||
|
rowsall=rowsPerStb*paraDict['stbNumbers']
|
||||||
|
dbNumbers = 1
|
||||||
|
|
||||||
|
tdLog.info("first check dnode and mnode")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
tdSql.checkData(0,1,'%s:6030'%self.host)
|
||||||
|
tdSql.checkData(4,1,'%s:6430'%self.host)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
#check mnode status
|
||||||
|
tdLog.info("check mnode status")
|
||||||
|
clusterComCheck.checkMnodeStatus(mnodeNums)
|
||||||
|
|
||||||
|
# add some error operations and
|
||||||
|
tdLog.info("Confirm the status of the dnode again")
|
||||||
|
tdSql.error("create mnode on dnode 2")
|
||||||
|
tdSql.query("select * from information_schema.ins_dnodes;")
|
||||||
|
print(tdSql.queryResult)
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
|
||||||
|
# create database and stable
|
||||||
|
clusterComCreate.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], paraDict["vgroups"],paraDict['replica'])
|
||||||
|
tdLog.info("Take turns stopping Mnodes ")
|
||||||
|
|
||||||
|
tdDnodes=cluster.dnodes
|
||||||
|
stopcount =0
|
||||||
|
threads=[]
|
||||||
|
|
||||||
|
# create stable:stb_0
|
||||||
|
stableName= paraDict['stbName']
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_stables(newTdSql, paraDict["dbName"],stableName,paraDict['stbNumbers'])
|
||||||
|
#create child table:ctb_0
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
clusterComCreate.create_ctable(newTdSql, paraDict["dbName"],stableName,stableName, paraDict['ctbNum'])
|
||||||
|
#insert date
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s_%d'%(paraDict['stbName'],i)
|
||||||
|
newTdSql=tdCom.newTdSql()
|
||||||
|
threads.append(threading.Thread(target=clusterComCreate.insert_data, args=(newTdSql, paraDict["dbName"],stableName,paraDict["ctbNum"],paraDict["rowsPerTbl"],paraDict["batchNum"],paraDict["startTs"])))
|
||||||
|
for tr in threads:
|
||||||
|
tr.start()
|
||||||
|
TdSqlEx=tdCom.newTdSql()
|
||||||
|
tdLog.info(f"alter database db0_0 replica {replica1}")
|
||||||
|
TdSqlEx.execute(f'alter database db0_0 replica {replica1}')
|
||||||
|
for tr in threads:
|
||||||
|
tr.join()
|
||||||
|
clusterComCheck.checkDnodes(dnodeNumbers)
|
||||||
|
clusterComCheck.checkDbRows(dbNumbers)
|
||||||
|
# clusterComCheck.checkDb(dbNumbers,1,paraDict["dbName"])
|
||||||
|
|
||||||
|
# tdSql.execute("use %s" %(paraDict["dbName"]))
|
||||||
|
tdSql.query("show %s.stables"%(paraDict["dbName"]))
|
||||||
|
tdSql.checkRows(paraDict["stbNumbers"])
|
||||||
|
for i in range(paraDict['stbNumbers']):
|
||||||
|
stableName= '%s.%s_%d'%(paraDict["dbName"],paraDict['stbName'],i)
|
||||||
|
tdSql.query("select count(*) from %s"%stableName)
|
||||||
|
tdSql.checkData(0,0,rowsPerStb)
|
||||||
|
|
||||||
|
clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica1,db_name=paraDict["dbName"],count_number=20)
|
||||||
|
sleep(5)
|
||||||
|
tdLog.info(f"show transactions;alter database db0_0 replica {replica3};")
|
||||||
|
TdSqlEx.execute(f'show transactions;')
|
||||||
|
TdSqlEx.execute(f'alter database db0_0 replica {replica3};')
|
||||||
|
clusterComCheck.check_vgroups_status(vgroup_numbers=paraDict["vgroups"],db_replica=replica3,db_name=paraDict["dbName"],count_number=120)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# print(self.master_dnode.cfgDict)
|
||||||
|
self.fiveDnodeThreeMnode(dnodeNumbers=6,mnodeNums=3,restartNumbers=4,stopRole='dnode')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue