From cd1606802fb0a0248d1046416657dff59dbbfd4b Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 8 Jan 2025 18:52:03 +0800 Subject: [PATCH 01/67] feat:add test script --- .../system-test/7-tmq/taosx-performance.json | 69 +++++++++++++++++++ tests/system-test/7-tmq/taosx-performance.py | 36 ++++++++++ 2 files changed, 105 insertions(+) create mode 100644 tests/system-test/7-tmq/taosx-performance.json create mode 100644 tests/system-test/7-tmq/taosx-performance.py diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json new file mode 100644 index 0000000000..568959645f --- /dev/null +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -0,0 +1,69 @@ +{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "connection_pool_size": 20, + "thread_bind_vgroup": "yes", + "thread_count": 20, + "create_table_thread_count": 16, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "num_of_records_per_req": 10000, + "prepared_rand": 10000, + "chinese": "no", + "escape_character": "yes", + "continue_if_fail": "no", + "databases": [ + { + "dbinfo": { + "name": "test", + "drop": "yes", + "vgroups": 32, + "precision": "ms", + "WAL_RETENTION_PERIOD": 864000 + }, + "super_tables": [ + { + "name": "meters", + "child_table_exists": "no", + "childtable_count": 10000, + "childtable_prefix": "d", + "auto_create_table": "no", + "batch_create_tbl_num": 500, + "data_source": "rand", + "insert_mode": "stmt", + "non_stop_mode": "no", + "line_protocol": "line", + "insert_rows": 10000, + "childtable_limit": 0, + "childtable_offset": 0, + "interlace_rows": 1, + "insert_interval": 0, + "partial_col_num": 0, + "timestamp_step": 10, + "start_timestamp": "2020-10-01 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "use_sample_ts": "no", + "tags_file": "", + "columns": [ + {"type": "FLOAT", "name": "current", "count": 1, "max": 12, "min": 8 }, + { "type": "INT", "name": "voltage", "max": 225, "min": 215 }, + { "type": "FLOAT", "name": "phase", "max": 1, "min": 0 } + ], + "tags": [ + {"type": "TINYINT", "name": "groupid", "max": 10, "min": 1}, + {"type": "BINARY", "name": "location", "len": 16, + "values": ["San Francisco", "Los Angles", "San Diego", + "San Jose", "Palo Alto", "Campbell", "Mountain View", + "Sunnyvale", "Santa Clara", "Cupertino"] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py new file mode 100644 index 0000000000..324028a43f --- /dev/null +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -0,0 +1,36 @@ +import taos +import sys +import time +import socket +import os +import threading + +sys.path.append("../../pytest") + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +from taos.tmq import * +sys.path.append("./7-tmq") +from tmqCommon import * + +tdDnodes1 = TDDnodes() +tdDnodes2 = TDDnodes() + +if __name__ == "__main__": + tdDnodes1.stopAll() + updatecfgDict1 = {'debugFlag': 135, 'serverPort': 6030} + tdDnodes1.init("./dnode1") + tdDnodes1.deploy(1,updatecfgDict1) + tdDnodes1.start(1) + + updatecfgDict2 = {'debugFlag': 135, 'serverPort': 7030} + tdDnodes2.init("./dnode2") + tdDnodes2.deploy(1,updatecfgDict2) + tdDnodes2.start(1) + + os.system("taosBenchmark -f taosx-performance.json") + + tdLog.info("Procedures for tdengine deployed in") From dc708a43785a428932bc4e8c19416d92ec363da5 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 13 Jan 2025 10:14:33 +0800 Subject: [PATCH 02/67] feat:add test script --- .../system-test/7-tmq/taosx-performance.json | 4 +-- tests/system-test/7-tmq/taosx-performance.py | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 5 deletions(-) mode change 100644 => 100755 tests/system-test/7-tmq/taosx-performance.py diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json index 568959645f..cbff630cbd 100644 --- a/tests/system-test/7-tmq/taosx-performance.json +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -21,7 +21,7 @@ "dbinfo": { "name": "test", "drop": "yes", - "vgroups": 32, + "vgroups": 8, "precision": "ms", "WAL_RETENTION_PERIOD": 864000 }, @@ -66,4 +66,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py old mode 100644 new mode 100755 index 324028a43f..63cfc01031 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -20,17 +20,44 @@ tdDnodes1 = TDDnodes() tdDnodes2 = TDDnodes() if __name__ == "__main__": + args = sys.argv[1:] + + insertData = False + if len(sys.argv[1:]) == 1: + insertData = True + + if not os.path.isdir("taosx-perf"): + os.system("mkdir taosx-perf") + os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") + os.chdir("taosx-perf") + print(os.getcwd()) + tdDnodes1.stopAll() - updatecfgDict1 = {'debugFlag': 135, 'serverPort': 6030} + updatecfgDict1 = {'debugFlag': 131, 'serverPort': 6030} tdDnodes1.init("./dnode1") tdDnodes1.deploy(1,updatecfgDict1) tdDnodes1.start(1) - updatecfgDict2 = {'debugFlag': 135, 'serverPort': 7030} + updatecfgDict2 = {'debugFlag': 131, 'serverPort': 7030} tdDnodes2.init("./dnode2") tdDnodes2.deploy(1,updatecfgDict2) tdDnodes2.start(1) - os.system("taosBenchmark -f taosx-performance.json") + if insertData : + os.system("taosBenchmark -f ../taosx-performance.json") + + print("create test in dst") + + os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") + os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") + + print("start to run taosx") + os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") + time.sleep(10) + + print("start to run perf") + #os.system("perf record -a -g -F 99 -p `pidof taosx` sleep 60") + + #os.system("perf script | ./FlameGraph/stackcollapse-perf.pl| ./FlameGraph/flamegraph.pl > flame.svg") tdLog.info("Procedures for tdengine deployed in") From def67c0d559209408de254e49e21bbf2a2f6f82c Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Mon, 20 Jan 2025 09:24:14 +0800 Subject: [PATCH 03/67] feat:add test script --- tests/system-test/7-tmq/taosx-performance.json | 13 ++++++++----- tests/system-test/7-tmq/taosx-performance.py | 5 ++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json index cbff630cbd..352bdbbd6d 100644 --- a/tests/system-test/7-tmq/taosx-performance.json +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -11,7 +11,7 @@ "create_table_thread_count": 16, "result_file": "./insert_res.txt", "confirm_parameter_prompt": "no", - "num_of_records_per_req": 10000, + "num_of_records_per_req": 10, "prepared_rand": 10000, "chinese": "no", "escape_character": "yes", @@ -34,7 +34,7 @@ "auto_create_table": "no", "batch_create_tbl_num": 500, "data_source": "rand", - "insert_mode": "stmt", + "insert_mode": "taosc", "non_stop_mode": "no", "line_protocol": "line", "insert_rows": 10000, @@ -49,10 +49,13 @@ "sample_file": "./sample.csv", "use_sample_ts": "no", "tags_file": "", + "generate_row_rule": 2, "columns": [ - {"type": "FLOAT", "name": "current", "count": 1, "max": 12, "min": 8 }, - { "type": "INT", "name": "voltage", "max": 225, "min": 215 }, - { "type": "FLOAT", "name": "phase", "max": 1, "min": 0 } + {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, + { "type": "BOOL", "name": "phaseewe" }, + { "type": "BINARY", "name": "locatin", "len":16374 }, + { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, + { "type": "DOUBLE", "name": "phase", "max": 1000, "min": 0 } ], "tags": [ {"type": "TINYINT", "name": "groupid", "max": 10, "min": 1}, diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 63cfc01031..1c70b9bb6b 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -43,14 +43,13 @@ if __name__ == "__main__": tdDnodes2.deploy(1,updatecfgDict2) tdDnodes2.start(1) + os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") + os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") if insertData : os.system("taosBenchmark -f ../taosx-performance.json") print("create test in dst") - os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") - os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") - print("start to run taosx") os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") time.sleep(10) From 7c5c9f624565946d1b08f893f05760b1d0da8207 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 22 Jan 2025 16:38:37 +0800 Subject: [PATCH 04/67] fix:[TS-5776]add raw type from consumer --- contrib/CMakeLists.txt | 1 + include/client/taos.h | 3 +- include/common/tcommon.h | 1 + include/common/tmsg.h | 9 +- include/libs/parser/parser.h | 3 + include/libs/qcom/query.h | 5 +- include/util/taoserror.h | 1 + source/client/inc/clientInt.h | 6 + source/client/src/clientMain.c | 39 ++++--- source/client/src/clientRawBlockWrite.c | 116 +++++++++++++++++++- source/client/src/clientTmq.c | 64 ++++++++--- source/common/src/msg/tmsg.c | 137 ++++++++++++++++++----- source/dnode/vnode/inc/vnode.h | 5 +- source/dnode/vnode/src/inc/tq.h | 3 +- source/dnode/vnode/src/tq/tqRead.c | 66 ++++++++++- source/dnode/vnode/src/tq/tqScan.c | 140 ++++++++++++------------ source/dnode/vnode/src/tq/tqUtil.c | 26 +++-- source/dnode/vnode/src/vnd/vnodeSvr.c | 2 +- source/libs/executor/src/scanoperator.c | 2 +- source/libs/parser/src/parInsertSml.c | 15 +++ source/libs/parser/src/parInsertUtil.c | 38 ++++++- source/util/src/terror.c | 1 + 22 files changed, 521 insertions(+), 162 deletions(-) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 2304ad54aa..6afcdd22f2 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -74,6 +74,7 @@ endif() # jemalloc if(${JEMALLOC_ENABLED}) cat("${TD_SUPPORT_DIR}/jemalloc_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) + MESSAGE("JEMALLOC_ENABLED is on") endif() # msvc regex diff --git a/include/client/taos.h b/include/client/taos.h index 17f97d3d3d..94a7884950 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -360,7 +360,8 @@ typedef enum tmq_res_t { TMQ_RES_INVALID = -1, TMQ_RES_DATA = 1, TMQ_RES_TABLE_META = 2, - TMQ_RES_METADATA = 3 + TMQ_RES_METADATA = 3, + TMQ_RES_RAWDATA = 4 } tmq_res_t; typedef struct tmq_topic_assignment { diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 0450766535..08fae0952c 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -121,6 +121,7 @@ enum { TMQ_MSG_TYPE__POLL_DATA_META_RSP, TMQ_MSG_TYPE__WALINFO_RSP, TMQ_MSG_TYPE__POLL_BATCH_META_RSP, + TMQ_MSG_TYPE__POLL_RAW_DATA_RSP, }; static char* tmqMsgTypeStr[] = { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index aebe09b563..d14044a8bf 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -2311,6 +2311,10 @@ typedef struct SSysTableSchema { int32_t tSerializeSRetrieveTableReq(void* buf, int32_t bufLen, SRetrieveTableReq* pReq); int32_t tDeserializeSRetrieveTableReq(void* buf, int32_t bufLen, SRetrieveTableReq* pReq); +#define RETRIEVE_TABLE_RSP_VERSION 0 +#define RETRIEVE_TABLE_RSP_TMQ_VERSION 1 +#define RETRIEVE_TABLE_RSP_TMQ_RAW_VERSION 2 + typedef struct { int64_t useconds; int8_t completed; // all results are returned to client @@ -4176,6 +4180,7 @@ typedef struct { STqOffsetVal reqOffset; int8_t enableReplay; int8_t sourceExcluded; + int8_t rawData; int8_t enableBatchMeta; } SMqPollReq; @@ -4506,6 +4511,7 @@ typedef struct { typedef struct { SArray* aSubmitTbData; // SArray + bool raw; } SSubmitReq2; typedef struct { @@ -4514,8 +4520,9 @@ typedef struct { char data[]; // SSubmitReq2 } SSubmitReq2Msg; +int32_t transformRawSSubmitTbData(void* data, int64_t suid, int64_t uid, int32_t sver); int32_t tEncodeSubmitReq(SEncoder* pCoder, const SSubmitReq2* pReq); -int32_t tDecodeSubmitReq(SDecoder* pCoder, SSubmitReq2* pReq); +int32_t tDecodeSubmitReq(SDecoder* pCoder, SSubmitReq2* pReq, SArray* rawList); void tDestroySubmitTbData(SSubmitTbData* pTbData, int32_t flag); void tDestroySubmitReq(SSubmitReq2* pReq, int32_t flag); diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 95f522f504..f4bf5fafd4 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -180,8 +180,11 @@ int32_t smlBindData(SQuery* handle, bool dataFormat, SArray* tags, SArray* colsS STableMeta* pTableMeta, char* tableName, const char* sTableName, int32_t sTableNameLen, int32_t ttl, char* msgBuf, int32_t msgBufLen, void* charsetCxt); int32_t smlBuildOutput(SQuery* handle, SHashObj* pVgHash); +int32_t smlBuildOutputRaw(SQuery* handle, SHashObj* pVgHash); +int rawBlockBindRawData(SHashObj* pVgroupHash, SArray* pVgroupList, STableMeta* pTableMeta, void* data); int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreateTbReq* pCreateTb, void* fields, int numFields, bool needChangeLength, char* errstr, int32_t errstrLen, bool raw); +int32_t checkSchema(SSchema* pColSchema, int8_t* fields, char* errstr, int32_t errstrLen); int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray); int32_t serializeVgroupsCreateTableBatch(SHashObj* pVgroupHashmap, SArray** pOut); diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 5b28eadc4f..02cb96e4c7 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -222,7 +222,10 @@ typedef struct STableDataCxt { STSchema* pSchema; SBoundColInfo boundColsInfo; SArray* pValues; - SSubmitTbData* pData; + union { + SSubmitTbData* pData; + void* raw; + }; SRowKey lastKey; bool ordered; bool duplicateTs; diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 464dffa937..8488e2800a 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -1016,6 +1016,7 @@ int32_t taosGetErrSize(); #define TSDB_CODE_TMQ_NO_TABLE_QUALIFIED TAOS_DEF_ERROR_CODE(0, 0x4015) #define TSDB_CODE_TMQ_NO_NEED_REBALANCE TAOS_DEF_ERROR_CODE(0, 0x4016) #define TSDB_CODE_TMQ_INVALID_STATUS TAOS_DEF_ERROR_CODE(0, 0x4017) +#define TSDB_CODE_TMQ_INVALID_DATA TAOS_DEF_ERROR_CODE(0, 0x4018) // stream #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 2543a1f3ec..ae88883739 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -45,6 +45,7 @@ enum { RES_TYPE__TMQ_META, RES_TYPE__TMQ_METADATA, RES_TYPE__TMQ_BATCH_META, + RES_TYPE__TMQ_RAWDATA, }; #define SHOW_VARIABLES_RESULT_COLS 5 @@ -55,6 +56,7 @@ enum { #define SHOW_VARIABLES_RESULT_FIELD5_LEN (TSDB_CONFIG_INFO_LEN + VARSTR_HEADER_SIZE) #define TD_RES_QUERY(res) (*(int8_t*)(res) == RES_TYPE__QUERY) +#define TD_RES_TMQ_RAW(res) (*(int8_t*)(res) == RES_TYPE__TMQ_RAWDATA) #define TD_RES_TMQ(res) (*(int8_t*)(res) == RES_TYPE__TMQ) #define TD_RES_TMQ_META(res) (*(int8_t*)(res) == RES_TYPE__TMQ_META) #define TD_RES_TMQ_METADATA(res) (*(int8_t*)(res) == RES_TYPE__TMQ_METADATA) @@ -251,6 +253,10 @@ typedef struct { SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; + struct{ + int32_t len; + void* rawData; + }; }; } SMqRspObj; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 83aff351dd..eb1bffeee3 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -253,7 +253,7 @@ void taos_cleanup(void) { taosCloseRef(id); nodesDestroyAllocatorSet(); - // cleanupAppInfo(); + cleanupAppInfo(); rpcCleanup(); tscDebug("rpc cleanup"); @@ -502,7 +502,7 @@ void taos_close(TAOS *taos) { } int taos_errno(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return terrno; } @@ -514,7 +514,7 @@ int taos_errno(TAOS_RES *res) { } const char *taos_errstr(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return (const char *)tstrerror(terrno); } @@ -554,6 +554,9 @@ void taos_free_result(TAOS_RES *res) { tDeleteMqMetaRsp(&pRsp->metaRsp); } else if (TD_RES_TMQ_BATCH_META(res)) { tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp); + } else if (TD_RES_TMQ_RAW(res)) { + taosMemoryFree(pRsp->rawData); + doFreeReqResultInfo(&pRsp->resInfo); } taosMemoryFree(pRsp); } @@ -572,7 +575,7 @@ void taos_kill_query(TAOS *taos) { } int taos_field_count(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -583,7 +586,7 @@ int taos_field_count(TAOS_RES *res) { int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); } TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { - if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return NULL; } @@ -643,7 +646,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { return NULL; } else { tscError("invalid result passed to taos_fetch_row"); - terrno = TSDB_CODE_TSC_INTERNAL_ERROR; + terrno = TSDB_CODE_TMQ_INVALID_DATA; return NULL; } } @@ -764,7 +767,7 @@ int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD } int *taos_fetch_lengths(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return NULL; } @@ -773,7 +776,7 @@ int *taos_fetch_lengths(TAOS_RES *res) { } TAOS_ROW *taos_result_block(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { terrno = TSDB_CODE_INVALID_PARA; return NULL; } @@ -841,7 +844,7 @@ const char *taos_get_client_info() { return td_version; } // return int32_t int taos_affected_rows(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -853,7 +856,7 @@ int taos_affected_rows(TAOS_RES *res) { // return int64_t int64_t taos_affected_rows64(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -864,7 +867,7 @@ int64_t taos_affected_rows64(TAOS_RES *res) { } int taos_result_precision(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return TSDB_TIME_PRECISION_MILLI; } @@ -904,7 +907,7 @@ int taos_select_db(TAOS *taos, const char *db) { } void taos_stop_query(TAOS_RES *res) { - if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_BATCH_META(res)) { return; } @@ -913,7 +916,7 @@ void taos_stop_query(TAOS_RES *res) { } bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return true; } SReqResultInfo *pResultInfo = tscGetCurResInfo(res); @@ -938,7 +941,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { } int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -973,7 +976,7 @@ int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) { return 0; } else { tscError("taos_fetch_block_s invalid res type"); - return -1; + return TSDB_CODE_TMQ_INVALID_DATA; } } @@ -981,7 +984,7 @@ int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) { *numOfRows = 0; *pData = NULL; - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -1018,7 +1021,7 @@ int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) { } int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) { - if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { + if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { return 0; } @@ -1038,7 +1041,7 @@ int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) { int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) { if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) || - TD_RES_TMQ_BATCH_META(res)) { + TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) { return TSDB_CODE_INVALID_PARA; } diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index c200d38a56..689adf51e7 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -1844,9 +1844,10 @@ static void* getRawDataFromRes(void* pRetrieve) { } void* rawData = NULL; // deal with compatibility - if (*(int64_t*)pRetrieve == 0) { + if (*(int64_t*)pRetrieve == RETRIEVE_TABLE_RSP_VERSION) { rawData = ((SRetrieveTableRsp*)pRetrieve)->data; - } else if (*(int64_t*)pRetrieve == 1) { + } else if (*(int64_t*)pRetrieve == RETRIEVE_TABLE_RSP_TMQ_VERSION || + *(int64_t*)pRetrieve == RETRIEVE_TABLE_RSP_TMQ_RAW_VERSION) { rawData = ((SRetrieveTableRspForTmq*)pRetrieve)->data; } return rawData; @@ -1947,7 +1948,10 @@ static int32_t initRawCacheHash() { } static bool needRefreshMeta(void* rawData, STableMeta* pTableMeta, SSchemaWrapper* pSW) { - if (rawData == NULL || pTableMeta == NULL || pSW == NULL) { + if (rawData == NULL){ + return false; + } + if (pTableMeta == NULL || pSW == NULL) { uError("invalid parameter in %s", __func__); return false; } @@ -1965,6 +1969,7 @@ static bool needRefreshMeta(void* rawData, STableMeta* pTableMeta, SSchemaWrappe if (pSW->nCols != pTableMeta->tableInfo.numOfColumns) { return true; } + for (int i = 0; i < pSW->nCols; i++) { int j = 0; for (; j < pTableMeta->tableInfo.numOfColumns; j++) { @@ -1972,7 +1977,7 @@ static bool needRefreshMeta(void* rawData, STableMeta* pTableMeta, SSchemaWrappe char* fieldName = pSW->pSchema[i].name; if (strcmp(pColSchema->name, fieldName) == 0) { - if (*fields != pColSchema->type || *(int32_t*)(fields + sizeof(int8_t)) != pColSchema->bytes) { + if (checkSchema(pColSchema, fields, NULL, 0) != 0){ return true; } break; @@ -2069,7 +2074,7 @@ static int32_t processCacheMeta(SHashObj* pVgHash, SHashObj* pNameHash, SHashObj SVCreateTbReq* pCreateReqDst, SCatalog* pCatalog, SRequestConnInfo* conn, SName* pName, STableMeta** pMeta, SSchemaWrapper* pSW, void* rawData, int32_t retry) { if (pVgHash == NULL || pNameHash == NULL || pMetaHash == NULL || pCatalog == NULL || conn == NULL || pName == NULL || - pMeta == NULL || pSW == NULL || rawData == NULL) { + pMeta == NULL || pSW == NULL) { uError("invalid parameter in %s", __func__); return TSDB_CODE_INVALID_PARA; } @@ -2298,6 +2303,96 @@ end: return code; } +static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) { + if (taos == NULL || data == NULL) { + uError("invalid parameter in %s", __func__); + return TSDB_CODE_INVALID_PARA; + } + int32_t code = TSDB_CODE_SUCCESS; + SQuery* pQuery = NULL; + SHashObj* pVgroupHash = NULL; + SMqRspObj rspObj = {0}; + SDecoder decoder = {0}; + + SRequestObj* pRequest = NULL; + SCatalog* pCatalog = NULL; + SRequestConnInfo conn = {0}; + + RAW_RETURN_CHECK(buildRawRequest(taos, &pRequest, &pCatalog, &conn)); + uDebug(LOG_ID_TAG " write raw metadata, data:%p, dataLen:%d", LOG_ID_VALUE, data, dataLen); + RAW_RETURN_CHECK(decodeRawData(&decoder, data, dataLen, tDecodeSTaosxRsp, &rspObj)); + + SHashObj* pVgHash = NULL; + SHashObj* pNameHash = NULL; + SHashObj* pMetaHash = NULL; + RAW_RETURN_CHECK(getRawCache(&pVgHash, &pNameHash, &pMetaHash, taos)); + int retry = 0; + while (1) { + RAW_RETURN_CHECK(smlInitHandle(&pQuery)); + uDebug(LOG_ID_TAG " write raw meta data block num:%d", LOG_ID_VALUE, rspObj.dataRsp.blockNum); + SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)(pQuery)->pRoot; + pVgroupHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false); + RAW_NULL_CHECK(pVgroupHash); + pStmt->pVgDataBlocks = taosArrayInit(8, POINTER_BYTES); + RAW_NULL_CHECK(pStmt->pVgDataBlocks); + + while (++rspObj.resIter < rspObj.dataRsp.blockNum) { + if (!rspObj.dataRsp.withSchema) { + goto end; + } + + const char* tbName = (const char*)taosArrayGetP(rspObj.dataRsp.blockTbName, rspObj.resIter); + RAW_NULL_CHECK(tbName); + SSchemaWrapper* pSW = (SSchemaWrapper*)taosArrayGetP(rspObj.dataRsp.blockSchema, rspObj.resIter); + RAW_NULL_CHECK(pSW); + void* pRetrieve = taosArrayGetP(rspObj.dataRsp.blockData, rspObj.resIter); + RAW_NULL_CHECK(pRetrieve); + void* rawData = getRawDataFromRes(pRetrieve); + RAW_NULL_CHECK(rawData); + + uDebug(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); + SName pName = {TSDB_TABLE_NAME_T, pRequest->pTscObj->acctId, {0}, {0}}; + tstrncpy(pName.dbname, pRequest->pDb, TSDB_DB_NAME_LEN); + tstrncpy(pName.tname, tbName, TSDB_TABLE_NAME_LEN); + + // find schema data info + STableMeta* pTableMeta = NULL; + RAW_RETURN_CHECK(processCacheMeta(pVgHash, pNameHash, pMetaHash, NULL, pCatalog, &conn, &pName, + &pTableMeta, pSW, NULL, retry)); + char err[ERR_MSG_LEN] = {0}; + code = rawBlockBindRawData(pVgroupHash, pStmt->pVgDataBlocks, pTableMeta, rawData); + if (code != TSDB_CODE_SUCCESS) { + SET_ERROR_MSG("table:%s, err:%s", pName.tname, err); + goto end; + } + } + taosHashCleanup(pVgroupHash); + pVgroupHash = NULL; + + RAW_RETURN_CHECK(smlBuildOutputRaw(pQuery, pVgHash)); + launchQueryImpl(pRequest, pQuery, true, NULL); + code = pRequest->code; + + if (NEED_CLIENT_HANDLE_ERROR(code) && retry++ < 3) { + uInfo("write raw retry:%d/3 end code:%d, msg:%s", retry, code, tstrerror(code)); + qDestroyQuery(pQuery); + pQuery = NULL; + rspObj.resIter = -1; + continue; + } + break; + } + + end: + uDebug(LOG_ID_TAG " write raw metadata return, msg:%s", LOG_ID_VALUE, tstrerror(code)); + tDeleteSTaosxRsp(&rspObj.dataRsp); + tDecoderClear(&decoder); + qDestroyQuery(pQuery); + taosHashCleanup(pVgroupHash); + destroyRequest(pRequest); + return code; +} + static void processSimpleMeta(SMqMetaRsp* pMetaRsp, cJSON** meta) { if (pMetaRsp == NULL || meta == NULL) { uError("invalid parameter in %s", __func__); @@ -2499,6 +2594,11 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { raw->raw_len = rspObj->batchMetaRsp.metaBuffLen; raw->raw_type = rspObj->resType; uDebug("tmq get raw batch meta:%p", raw); + } else if (TD_RES_TMQ_RAW(res)) { + raw->raw = rspObj->rawData; + raw->raw_len = rspObj->len; + raw->raw_type = rspObj->resType; + uDebug("tmq get raw raw:%p", raw); } else { uError("tmq get raw error type:%d", *(int8_t*)res); return TSDB_CODE_TMQ_INVALID_MSG; @@ -2508,7 +2608,9 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { void tmq_free_raw(tmq_raw_data raw) { uDebug("tmq free raw data type:%d", raw.raw_type); - if (raw.raw_type == RES_TYPE__TMQ || raw.raw_type == RES_TYPE__TMQ_METADATA) { + if (raw.raw_type == RES_TYPE__TMQ || + raw.raw_type == RES_TYPE__TMQ_RAWDATA || + raw.raw_type == RES_TYPE__TMQ_METADATA) { taosMemoryFree(raw.raw); } (void)memset(terrMsg, 0, ERR_MSG_LEN); @@ -2559,6 +2661,8 @@ static int32_t writeRawImpl(TAOS* taos, void* buf, uint32_t len, uint16_t type) return taosDeleteData(taos, buf, len); } else if (type == RES_TYPE__TMQ_METADATA) { return tmqWriteRawMetaDataImpl(taos, buf, len); + } else if (type == RES_TYPE__TMQ_RAWDATA) { + return tmqWriteRawRawDataImpl(taos, buf, len); } else if (type == RES_TYPE__TMQ) { return tmqWriteRawDataImpl(taos, buf, len); } else if (type == RES_TYPE__TMQ_BATCH_META) { diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index f4426fc94a..e611e7e417 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -91,6 +91,7 @@ struct tmq_conf_t { int8_t snapEnable; int8_t replayEnable; int8_t sourceExcluded; // do not consume, bit + int8_t rawData; // fetch raw data uint16_t port; int32_t autoCommitInterval; int32_t sessionTimeoutMs; @@ -120,6 +121,7 @@ struct tmq_t { int8_t resetOffsetCfg; int8_t replayEnable; int8_t sourceExcluded; // do not consume, bit + int8_t rawData; // fetch raw data int64_t consumerId; tmq_commit_cb* commitCb; void* commitCbUserParam; @@ -195,6 +197,10 @@ typedef struct { SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; + struct{ + int32_t len; + void* rawData; + }; }; } SMqPollRspWrapper; @@ -490,11 +496,17 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value } } if (strcasecmp(key, "msg.consume.excluded") == 0) { - int64_t tmp; + int64_t tmp = 0; code = taosStr2int64(value, &tmp); conf->sourceExcluded = (0 == code && tmp != 0) ? TD_REQ_FROM_TAOX : 0; return TMQ_CONF_OK; } + if (strcasecmp(key, "msg.consume.rawdata") == 0) { + int64_t tmp = 0; + code = taosStr2int64(value, &tmp); + conf->rawData = (0 == code && tmp != 0) ? 1 : 0; + return TMQ_CONF_OK; + } if (strcasecmp(key, "td.connect.db") == 0) { return TMQ_CONF_OK; @@ -811,7 +823,7 @@ static void asyncCommitFromResult(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_c goto end; } - if (TD_RES_TMQ(pRes) || TD_RES_TMQ_META(pRes) || + if (TD_RES_TMQ(pRes) || TD_RES_TMQ_RAW(pRes) || TD_RES_TMQ_META(pRes) || TD_RES_TMQ_METADATA(pRes) || TD_RES_TMQ_BATCH_META(pRes)) { SMqRspObj* pRspObj = (SMqRspObj*)pRes; pTopicName = pRspObj->topic; @@ -1081,6 +1093,7 @@ void tmqSendHbReq(void* param, void* tmrId) { sendInfo->fp = tmqHbCb; sendInfo->msgType = TDMT_MND_TMQ_HB; + SEpSet epSet = getEpSet_s(&tmq->pTscObj->pAppInfo->mgmtEp); int32_t code = asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &epSet, NULL, sendInfo); @@ -1121,6 +1134,10 @@ static void tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) { DELETE_POLL_RSP(tDeleteMqMetaRsp,&pRsp->metaRsp) } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { DELETE_POLL_RSP(tDeleteMqBatchMetaRsp,&pRsp->batchMetaRsp) + } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { + SMqPollRspWrapper* pRsp = &rspWrapper->pollRsp; + taosMemoryFreeClear(pRsp->pEpset); + taosMemoryFreeClear(pRsp->rawData); } } @@ -1709,6 +1726,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; + pTmq->rawData = conf->rawData; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { @@ -2042,6 +2060,10 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) } else if (rspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) + } else if (rspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { + pRspWrapper->pollRsp.len = pMsg->len; + pRspWrapper->pollRsp.rawData = pMsg->pData; + pMsg->pData = NULL; } else { // invalid rspType tqErrorC("consumer:0x%" PRIx64 " invalid rsp msg received, type:%d ignored", tmq->consumerId, rspType); code = TSDB_CODE_TSC_INTERNAL_ERROR; @@ -2098,6 +2120,7 @@ void tmqBuildConsumeReqImpl(SMqPollReq* pReq, tmq_t* tmq, int64_t timeout, SMqCl pReq->reqId = generateRequestId(); pReq->enableReplay = tmq->replayEnable; pReq->sourceExcluded = tmq->sourceExcluded; + pReq->rawData = tmq->rawData; pReq->enableBatchMeta = tmq->enableBatchMeta; } @@ -2346,6 +2369,10 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){ SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; + struct{ + int32_t len; + void* rawData; + }; } MEMSIZE; SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj)); @@ -2418,13 +2445,16 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ pVg->epSet = *pollRspWrapper->pEpset; } - if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP || pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { + if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP || + pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP || + pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { updateVgInfo(pVg, &pollRspWrapper->dataRsp.reqOffset, &pollRspWrapper->dataRsp.rspOffset, pollRspWrapper->head.walsver, pollRspWrapper->head.walever, tmq->consumerId, pollRspWrapper->dataRsp.blockNum != 0); char buf[TSDB_OFFSET_LEN] = {0}; tFormatOffset(buf, TSDB_OFFSET_LEN, &pollRspWrapper->rspOffset); - if (pollRspWrapper->dataRsp.blockNum == 0) { + if (pollRspWrapper->dataRsp.blockNum == 0 && + pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { tqDebugC("consumer:0x%" PRIx64 " empty block received, vgId:%d, offset:%s, vg total:%" PRId64 ", total:%" PRId64 ",QID:0x%" PRIx64, tmq->consumerId, pVg->vgId, buf, pVg->numOfRows, tmq->totalRows, pollRspWrapper->reqId); @@ -2435,12 +2465,18 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ tqErrorC("consumer:0x%" PRIx64 " failed to allocate memory for meta rsp", tmq->consumerId); goto END; } - pRspObj->resType = pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP ? RES_TYPE__TMQ : RES_TYPE__TMQ_METADATA; + pRspObj->resType = pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP ? RES_TYPE__TMQ_RAWDATA : + (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP ? RES_TYPE__TMQ : RES_TYPE__TMQ_METADATA); int64_t numOfRows = 0; - tmqBuildRspFromWrapperInner(pollRspWrapper, pVg, &numOfRows, pRspObj); - tmq->totalRows += numOfRows; + if (pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP){ + tmqBuildRspFromWrapperInner(pollRspWrapper, pVg, &numOfRows, pRspObj); + tmq->totalRows += numOfRows; + } else { + pRspObj->rawData = pollRspWrapper->rawData; + pRspObj->len = pollRspWrapper->len; + } pVg->emptyBlockReceiveTs = 0; - if (tmq->replayEnable) { + if (tmq->replayEnable && pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { pVg->blockReceiveTs = taosGetTimestampMs(); pVg->blockSleepForReplay = pRspObj->dataRsp.sleepTime; if (pVg->blockSleepForReplay > 0) { @@ -2656,6 +2692,8 @@ tmq_res_t tmq_get_res_type(TAOS_RES* res) { return TMQ_RES_METADATA; } else if (TD_RES_TMQ_BATCH_META(res)) { return TMQ_RES_TABLE_META; + } else if (TD_RES_TMQ_RAW(res)) { + return TMQ_RES_RAWDATA; } else { return TMQ_RES_INVALID; } @@ -2665,7 +2703,7 @@ const char* tmq_get_topic_name(TAOS_RES* res) { if (res == NULL) { return NULL; } - if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || + if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) { char* tmp = strchr(((SMqRspObj*)res)->topic, '.'); if (tmp == NULL) { @@ -2682,7 +2720,7 @@ const char* tmq_get_db_name(TAOS_RES* res) { return NULL; } - if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || + if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_BATCH_META(res) || TD_RES_TMQ_META(res)) { char* tmp = strchr(((SMqRspObj*)res)->db, '.'); if (tmp == NULL) { @@ -2698,7 +2736,7 @@ int32_t tmq_get_vgroup_id(TAOS_RES* res) { if (res == NULL) { return TSDB_CODE_INVALID_PARA; } - if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || + if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) || TD_RES_TMQ_BATCH_META(res) || TD_RES_TMQ_META(res)) { return ((SMqRspObj*)res)->vgId; } else { @@ -2710,7 +2748,7 @@ int64_t tmq_get_vgroup_offset(TAOS_RES* res) { if (res == NULL) { return TSDB_CODE_INVALID_PARA; } - if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) { + if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) { SMqRspObj* pRspObj = (SMqRspObj*)res; STqOffsetVal* pOffset = &pRspObj->dataRsp.reqOffset; if (pOffset->type == TMQ_OFFSET__LOG) { @@ -2735,7 +2773,7 @@ const char* tmq_get_table_name(TAOS_RES* res) { if (res == NULL) { return NULL; } - if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) { + if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) ) { SMqRspObj* pRspObj = (SMqRspObj*)res; SMqDataRsp* data = &pRspObj->dataRsp; if (!data->withTbName || data->blockTbName == NULL || pRspObj->resIter < 0 || diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index a3989012f6..1b6c7add3f 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -9205,6 +9205,7 @@ int32_t tSerializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) { TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->enableReplay)); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->sourceExcluded)); TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->enableBatchMeta)); + TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->rawData)); tEndEncode(&encoder); @@ -9258,6 +9259,10 @@ int32_t tDeserializeSMqPollReq(void *buf, int32_t bufLen, SMqPollReq *pReq) { pReq->enableBatchMeta = false; } + if (!tDecodeIsEnd(&decoder)) { + TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->rawData)); + } + tEndDecode(&decoder); _exit: @@ -11609,6 +11614,26 @@ int32_t tDecodeSBatchDeleteReqSetCtime(SDecoder *pDecoder, SBatchDeleteReq *pReq _exit: return code; } +int32_t transformRawSSubmitTbData(void* data, int64_t suid, int64_t uid, int32_t sver){ + int32_t code = 0; + int32_t lino = 0; + SDecoder decoder = {0}; + tDecoderInit(&decoder, (uint8_t *)POINTER_SHIFT(data, INT_BYTES), *(uint32_t*)data); + + int32_t flags = 0; + TAOS_CHECK_EXIT(tDecodeI32v(&decoder, &flags)); + flags |= TD_REQ_FROM_TAOX; + flags &= ~SUBMIT_REQ_AUTO_CREATE_TABLE; + + SEncoder encoder = {0}; + tEncoderInit(&encoder, (uint8_t *)POINTER_SHIFT(data, INT_BYTES), *(uint32_t*)data); + TAOS_CHECK_EXIT(tEncodeI32v(&encoder, flags)); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, suid)); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, uid)); + TAOS_CHECK_EXIT(tEncodeI32v(&encoder, sver)); + _exit: + return code; +} static int32_t tEncodeSSubmitTbData(SEncoder *pCoder, const SSubmitTbData *pSubmitTbData) { int32_t code = 0; @@ -11656,14 +11681,21 @@ _exit: return code; } -static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbData) { +static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbData, void* rawData) { int32_t code = 0; int32_t lino; int32_t flags; uint8_t version; + uint8_t* dataAfterCreate = NULL; + uint8_t* dataStart = pCoder->data; + uint32_t posStart = pCoder->pos; + uint32_t posAfterCreate = 0; + TAOS_CHECK_EXIT(tStartDecode(pCoder)); + uint32_t pos = pCoder->pos; TAOS_CHECK_EXIT(tDecodeI32v(pCoder, &flags)); + uint32_t flagsLen = pCoder->pos - posStart; pSubmitTbData->flags = flags & 0xff; version = (flags >> 8) & 0xff; @@ -11675,6 +11707,8 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa } TAOS_CHECK_EXIT(tDecodeSVCreateTbReq(pCoder, pSubmitTbData->pCreateTbReq)); + dataAfterCreate = pCoder->data; + posAfterCreate = pCoder->pos; } // submit data @@ -11682,35 +11716,56 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pSubmitTbData->uid)); TAOS_CHECK_EXIT(tDecodeI32v(pCoder, &pSubmitTbData->sver)); - if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { - uint64_t nColData; + if (rawData != NULL){ // no need to decode data + if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { + uint64_t nColData = 0; - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); - pSubmitTbData->aCol = taosArrayInit(nColData, sizeof(SColData)); - if (pSubmitTbData->aCol == NULL) { - TAOS_CHECK_EXIT(terrno); - } + for (int32_t i = 0; i < nColData; ++i) { + SColData pColData = {0}; + TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, &pColData)); + } + } else { + uint64_t nRow = 0; + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); - for (int32_t i = 0; i < nColData; ++i) { - TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1))); + for (int32_t iRow = 0; iRow < nRow; ++iRow) { + SRow *ppRow = NULL; + TAOS_CHECK_EXIT(tDecodeRow(pCoder, &ppRow)); + } } } else { - uint64_t nRow; - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); + if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { + uint64_t nColData = 0; - pSubmitTbData->aRowP = taosArrayInit(nRow, sizeof(SRow *)); - if (pSubmitTbData->aRowP == NULL) { - TAOS_CHECK_EXIT(terrno); - } + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); - for (int32_t iRow = 0; iRow < nRow; ++iRow) { - SRow **ppRow = taosArrayReserve(pSubmitTbData->aRowP, 1); - if (ppRow == NULL) { + pSubmitTbData->aCol = taosArrayInit(nColData, sizeof(SColData)); + if (pSubmitTbData->aCol == NULL) { TAOS_CHECK_EXIT(terrno); } - TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow)); + for (int32_t i = 0; i < nColData; ++i) { + TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1))); + } + } else { + uint64_t nRow = 0; + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); + + pSubmitTbData->aRowP = taosArrayInit(nRow, sizeof(SRow *)); + if (pSubmitTbData->aRowP == NULL) { + TAOS_CHECK_EXIT(terrno); + } + + for (int32_t iRow = 0; iRow < nRow; ++iRow) { + SRow **ppRow = taosArrayReserve(pSubmitTbData->aRowP, 1); + if (ppRow == NULL) { + TAOS_CHECK_EXIT(terrno); + } + + TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow)); + } } } @@ -11720,6 +11775,16 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa } tEndDecode(pCoder); + if (rawData != NULL){ + if (dataAfterCreate != NULL){ + TAOS_MEMCPY(dataAfterCreate - INT_BYTES - flagsLen, dataStart, INT_BYTES + flagsLen); + *(int32_t*)(dataAfterCreate - INT_BYTES - flagsLen) = pCoder->pos - posAfterCreate + flagsLen; + *(void**)rawData = dataAfterCreate - INT_BYTES - flagsLen; + }else{ + *(void**)rawData = dataStart; + } + } + _exit: return code; @@ -11731,15 +11796,27 @@ int32_t tEncodeSubmitReq(SEncoder *pCoder, const SSubmitReq2 *pReq) { TAOS_CHECK_EXIT(tStartEncode(pCoder)); TAOS_CHECK_EXIT(tEncodeU64v(pCoder, taosArrayGetSize(pReq->aSubmitTbData))); - for (uint64_t i = 0; i < taosArrayGetSize(pReq->aSubmitTbData); i++) { - TAOS_CHECK_EXIT(tEncodeSSubmitTbData(pCoder, taosArrayGet(pReq->aSubmitTbData, i))); + if (pReq->raw){ + for (uint64_t i = 0; i < taosArrayGetSize(pReq->aSubmitTbData); i++) { + void* data = taosArrayGetP(pReq->aSubmitTbData, i); + if (pCoder->data != NULL){ + TAOS_MEMCPY(pCoder->data + pCoder->pos, data, *(uint32_t*)data + INT_BYTES); + + } + pCoder->pos += *(uint32_t*)data + INT_BYTES; + } + } else{ + for (uint64_t i = 0; i < taosArrayGetSize(pReq->aSubmitTbData); i++) { + TAOS_CHECK_EXIT(tEncodeSSubmitTbData(pCoder, taosArrayGet(pReq->aSubmitTbData, i))); + } } + tEndEncode(pCoder); _exit: return code; } -int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq) { +int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq, SArray* rawList) { int32_t code = 0; memset(pReq, 0, sizeof(*pReq)); @@ -11763,7 +11840,8 @@ int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq) { } for (uint64_t i = 0; i < nSubmitTbData; i++) { - if (tDecodeSSubmitTbData(pCoder, taosArrayReserve(pReq->aSubmitTbData, 1)) < 0) { + if (tDecodeSSubmitTbData(pCoder, taosArrayReserve(pReq->aSubmitTbData, 1), + rawList != NULL ? taosArrayReserve(rawList, 1) : NULL) < 0) { code = TSDB_CODE_INVALID_MSG; goto _exit; } @@ -11834,12 +11912,15 @@ void tDestroySubmitTbData(SSubmitTbData *pTbData, int32_t flag) { void tDestroySubmitReq(SSubmitReq2 *pReq, int32_t flag) { if (pReq->aSubmitTbData == NULL) return; - int32_t nSubmitTbData = TARRAY_SIZE(pReq->aSubmitTbData); - SSubmitTbData *aSubmitTbData = (SSubmitTbData *)TARRAY_DATA(pReq->aSubmitTbData); + if (!pReq->raw){ + int32_t nSubmitTbData = TARRAY_SIZE(pReq->aSubmitTbData); + SSubmitTbData *aSubmitTbData = (SSubmitTbData *)TARRAY_DATA(pReq->aSubmitTbData); - for (int32_t i = 0; i < nSubmitTbData; i++) { - tDestroySubmitTbData(&aSubmitTbData[i], flag); + for (int32_t i = 0; i < nSubmitTbData; i++) { + tDestroySubmitTbData(&aSubmitTbData[i], flag); + } } + taosArrayDestroy(pReq->aSubmitTbData); pReq->aSubmitTbData = NULL; } diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index b33bdb0976..5a6489d182 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -241,11 +241,10 @@ SSDataBlock *tqGetResultBlock(STqReader *pReader); int64_t tqGetResultBlockTime(STqReader *pReader); int32_t extractMsgFromWal(SWalReader *pReader, void **pItem, int64_t maxVer, const char *id); -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, SArray* rawList); bool tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids); int32_t tqRetrieveDataBlock(STqReader *pReader, SSDataBlock **pRes, const char *idstr); -int32_t tqRetrieveTaosxBlock(STqReader *pReader, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet, - int64_t *createTime); +int32_t tqRetrieveTaosxBlock(STqReader *pReader, SMqDataRsp* pRsp, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet, SArray* rawList, int8_t fetchMeta); int32_t tqGetStreamExecInfo(SVnode *pVnode, int64_t streamId, int64_t *pDelay, bool *fhFinished); // sma diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 12a803d1d8..57e238b499 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -117,7 +117,7 @@ int32_t tqScanData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, STqOffsetVal* int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t reqId); // tqExec -int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded); +int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, const SMqPollReq* pRequest); int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type, int32_t vgId); void tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId); @@ -178,6 +178,7 @@ int32_t tqExtractDropCtbDataBlock(const void* data, int32_t len, int64_t ver, vo #define TQ_SUBSCRIBE_NAME "subscribe" #define TQ_OFFSET_NAME "offset-ver0" #define TQ_POLL_MAX_TIME 1000 +#define TQ_POLL_MAX_BYTES 1048576 #ifdef __cplusplus } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 937ca80bcc..6452f7bb5c 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -352,7 +352,7 @@ int32_t tqReaderSeek(STqReader* pReader, int64_t ver, const char* id) { return TSDB_CODE_INVALID_PARA; } if (walReaderSeekVer(pReader->pWalReader, ver) < 0) { - return -1; + return terrno; } tqDebug("wal reader seek to ver:%" PRId64 " %s", ver, id); return 0; @@ -485,14 +485,14 @@ bool tqNextBlockInWal(STqReader* pReader, const char* id, int sourceExcluded) { void* pBody = POINTER_SHIFT(pWalReader->pHead->head.body, sizeof(SSubmitReq2Msg)); int32_t bodyLen = pWalReader->pHead->head.bodyLen - sizeof(SSubmitReq2Msg); int64_t ver = pWalReader->pHead->head.version; - if (tqReaderSetSubmitMsg(pReader, pBody, bodyLen, ver) != 0) { + if (tqReaderSetSubmitMsg(pReader, pBody, bodyLen, ver, NULL) != 0) { return false; } pReader->nextBlk = 0; } } -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, SArray* rawList) { if (pReader == NULL) { return TSDB_CODE_INVALID_PARA; } @@ -504,7 +504,7 @@ int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, i SDecoder decoder = {0}; tDecoderInit(&decoder, pReader->msg.msgStr, pReader->msg.msgLen); - int32_t code = tDecodeSubmitReq(&decoder, &pReader->submit); + int32_t code = tDecodeSubmitReq(&decoder, &pReader->submit, rawList); tDecoderClear(&decoder); if (code != 0) { @@ -1046,7 +1046,45 @@ END: return code; } -int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet, int64_t *createTime) { +static int32_t buildCreateTbInfo(SMqDataRsp* pRsp, SVCreateTbReq* pCreateTbReq){ + int32_t code = 0; + int32_t lino = 0; + void* createReq = NULL; + TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA); + TSDB_CHECK_NULL(pCreateTbReq, code, lino, END, TSDB_CODE_INVALID_PARA); + + if (pRsp->createTableNum == 0) { + pRsp->createTableLen = taosArrayInit(0, sizeof(int32_t)); + TSDB_CHECK_NULL(pRsp->createTableLen, code, lino, END, terrno); + pRsp->createTableReq = taosArrayInit(0, sizeof(void*)); + TSDB_CHECK_NULL(pRsp->createTableReq, code, lino, END, terrno); + } + + uint32_t len = 0; + tEncodeSize(tEncodeSVCreateTbReq, pCreateTbReq, len, code); + TSDB_CHECK_CODE(code, lino, END); + createReq = taosMemoryCalloc(1, len); + TSDB_CHECK_NULL(createReq, code, lino, END, terrno); + + SEncoder encoder = {0}; + tEncoderInit(&encoder, createReq, len); + code = tEncodeSVCreateTbReq(&encoder, pCreateTbReq); + tEncoderClear(&encoder); + TSDB_CHECK_CODE(code, lino, END); + TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableLen, &len), code, lino, END, terrno); + TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableReq, &createReq), code, lino, END, terrno); + pRsp->createTableNum++; + tqDebug("build create table info msg success"); + + END: + if (code != 0){ + tqError("%s failed at %d, failed to build create table info msg:%s", __FUNCTION__, lino, tstrerror(code)); + taosMemoryFree(createReq); + } + return code; +} + +int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet, SArray* rawList, int8_t fetchMeta) { tqDebug("tq reader retrieve data block msg pointer:%p, index:%d", pReader->msg.msgStr, pReader->nextBlk); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk); if (pSubmitTbData == NULL) { @@ -1062,8 +1100,9 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas int64_t uid = pSubmitTbData->uid; pReader->lastBlkUid = uid; + int64_t createTime = INT64_MAX; tDeleteSchemaWrapper(pReader->pSchemaWrapper); - pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1, createTime); + pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1, &createTime); if (pReader->pSchemaWrapper == NULL) { tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table", pReader->pWalReader->pWal->cfg.vgId, uid, pReader->cachedSchemaVer); @@ -1071,6 +1110,21 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SArray* blocks, SArray* schemas return TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND; } + if (fetchMeta != WITH_DATA && + pSubmitTbData->pCreateTbReq != NULL && + pSubmitTbData->ctimeMs - createTime <= 0) { // judge if table is already created to avoid sending crateTbReq + int32_t code = buildCreateTbInfo(pRsp, pSubmitTbData->pCreateTbReq); + if (code != 0) { + return code; + } + } else if (rawList != NULL){ + if (taosArrayPush(schemas, &pReader->pSchemaWrapper) == NULL){ + return terrno; + } + pReader->pSchemaWrapper = NULL; + return 0; + } + if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { return tqProcessColData(pReader, pSubmitTbData, blocks, schemas); } else { diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index a65b118aea..9501ca4099 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -14,6 +14,32 @@ */ #include "tq.h" +static int32_t tqAddRawDataToRsp(const void* rawData, SMqDataRsp* pRsp, int8_t precision) { + int32_t code = TDB_CODE_SUCCESS; + int32_t lino = 0; + void* buf = NULL; + + int32_t dataStrLen = sizeof(SRetrieveTableRspForTmq) + *(uint32_t *)rawData + INT_BYTES; + buf = taosMemoryCalloc(1, dataStrLen); + TSDB_CHECK_NULL(buf, code, lino, END, terrno); + + SRetrieveTableRspForTmq* pRetrieve = (SRetrieveTableRspForTmq*)buf; + pRetrieve->version = RETRIEVE_TABLE_RSP_TMQ_RAW_VERSION; + pRetrieve->precision = precision; + pRetrieve->compressed = 0; + + memcpy(pRetrieve->data, rawData, *(uint32_t *)rawData + INT_BYTES); + TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &dataStrLen), code, lino, END, terrno); + TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); + + tqDebug("add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); + END: + if (code != TSDB_CODE_SUCCESS) { + taosMemoryFree(buf); + tqError("%s failed at %d, failed to add block data to response:%s", __FUNCTION__, lino, tstrerror(code)); + } + return code; +} static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision) { int32_t code = 0; @@ -25,7 +51,7 @@ static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, TSDB_CHECK_NULL(buf, code, lino, END, terrno); SRetrieveTableRspForTmq* pRetrieve = (SRetrieveTableRspForTmq*)buf; - pRetrieve->version = 1; + pRetrieve->version = RETRIEVE_TABLE_RSP_TMQ_VERSION; pRetrieve->precision = precision; pRetrieve->compressed = 0; pRetrieve->numOfRows = htobe64((int64_t)pBlock->info.rows); @@ -290,45 +316,8 @@ END: return code; } -static int32_t buildCreateTbInfo(SMqDataRsp* pRsp, SVCreateTbReq* pCreateTbReq){ - int32_t code = 0; - int32_t lino = 0; - void* createReq = NULL; - TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA); - TSDB_CHECK_NULL(pCreateTbReq, code, lino, END, TSDB_CODE_INVALID_PARA); - - if (pRsp->createTableNum == 0) { - pRsp->createTableLen = taosArrayInit(0, sizeof(int32_t)); - TSDB_CHECK_NULL(pRsp->createTableLen, code, lino, END, terrno); - pRsp->createTableReq = taosArrayInit(0, sizeof(void*)); - TSDB_CHECK_NULL(pRsp->createTableReq, code, lino, END, terrno); - } - - uint32_t len = 0; - tEncodeSize(tEncodeSVCreateTbReq, pCreateTbReq, len, code); - TSDB_CHECK_CODE(code, lino, END); - createReq = taosMemoryCalloc(1, len); - TSDB_CHECK_NULL(createReq, code, lino, END, terrno); - - SEncoder encoder = {0}; - tEncoderInit(&encoder, createReq, len); - code = tEncodeSVCreateTbReq(&encoder, pCreateTbReq); - tEncoderClear(&encoder); - TSDB_CHECK_CODE(code, lino, END); - TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableLen, &len), code, lino, END, terrno); - TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableReq, &createReq), code, lino, END, terrno); - pRsp->createTableNum++; - tqDebug("build create table info msg success"); - -END: - if (code != 0){ - tqError("%s failed at %d, failed to build create table info msg:%s", __FUNCTION__, lino, tstrerror(code)); - taosMemoryFree(createReq); - } - return code; -} - -static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded){ +static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int32_t* totalRows, + const SMqPollReq* pRequest, SArray* rawList){ int32_t code = 0; int32_t lino = 0; SArray* pBlocks = NULL; @@ -342,36 +331,46 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int pSchemas = taosArrayInit(0, sizeof(void*)); TSDB_CHECK_NULL(pSchemas, code, lino, END, terrno); - SSubmitTbData* pSubmitTbDataRet = NULL; - int64_t createTime = INT64_MAX; - code = tqRetrieveTaosxBlock(pReader, pBlocks, pSchemas, &pSubmitTbDataRet, &createTime); + SSubmitTbData* pSubmitTbData = NULL; + code = tqRetrieveTaosxBlock(pReader, pRsp, pBlocks, pSchemas, &pSubmitTbData, rawList, pHandle->fetchMeta); TSDB_CHECK_CODE(code, lino, END); - bool tmp = (pSubmitTbDataRet->flags & sourceExcluded) != 0; + bool tmp = (pSubmitTbData->flags & pRequest->sourceExcluded) != 0; TSDB_CHECK_CONDITION(!tmp, code, lino, END, TSDB_CODE_SUCCESS); + int32_t blockNum = taosArrayGetSize(pBlocks) == 0 ? 1 : taosArrayGetSize(pBlocks); + if (pRsp->withTbName) { int64_t uid = pExec->pTqReader->lastBlkUid; - code = tqAddTbNameToRsp(pTq, uid, pRsp, taosArrayGetSize(pBlocks)); + code = tqAddTbNameToRsp(pTq, uid, pRsp, blockNum); TSDB_CHECK_CODE(code, lino, END); } - if (pHandle->fetchMeta != WITH_DATA && pSubmitTbDataRet->pCreateTbReq != NULL) { - if (pSubmitTbDataRet->ctimeMs - createTime <= 1000) { // judge if table is already created to avoid sending crateTbReq - code = buildCreateTbInfo(pRsp, pSubmitTbDataRet->pCreateTbReq); - TSDB_CHECK_CODE(code, lino, END); - } - } - tmp = (pHandle->fetchMeta == ONLY_META && pSubmitTbDataRet->pCreateTbReq == NULL); + + tmp = (pHandle->fetchMeta == ONLY_META && pSubmitTbData->pCreateTbReq == NULL); TSDB_CHECK_CONDITION(!tmp, code, lino, END, TSDB_CODE_SUCCESS); - for (int32_t i = 0; i < taosArrayGetSize(pBlocks); i++) { - SSDataBlock* pBlock = taosArrayGet(pBlocks, i); - if (pBlock == NULL) { - continue; + for (int32_t i = 0; i < blockNum; i++) { + if (taosArrayGetSize(pBlocks) == 0){ + void* rawData = taosArrayGetP(rawList, pReader->nextBlk - 1); + if (rawData == NULL) { + continue; + } + if (tqAddRawDataToRsp(rawData, pRsp, pTq->pVnode->config.tsdbCfg.precision) != 0){ + tqError("vgId:%d, failed to add block to rsp msg", pTq->pVnode->config.vgId); + continue; + } + *totalRows += *(uint32_t *)rawData + INT_BYTES; // bytes actually + } else { + SSDataBlock* pBlock = taosArrayGet(pBlocks, i); + if (pBlock == NULL) { + continue; + } + + if (tqAddBlockDataToRsp(pBlock, pRsp, taosArrayGetSize(pBlock->pDataBlock), pTq->pVnode->config.tsdbCfg.precision) != 0){ + tqError("vgId:%d, failed to add block to rsp msg", pTq->pVnode->config.vgId); + continue; + } + *totalRows += pBlock->info.rows; + blockDataFreeRes(pBlock); } - if (tqAddBlockDataToRsp(pBlock, pRsp, taosArrayGetSize(pBlock->pDataBlock), pTq->pVnode->config.tsdbCfg.precision) != 0){ - tqError("vgId:%d, failed to add block to rsp msg", pTq->pVnode->config.vgId); - continue; - } - *totalRows += pBlock->info.rows; - blockDataFreeRes(pBlock); + SSchemaWrapper* pSW = taosArrayGetP(pSchemas, i); if (taosArrayPush(pRsp->blockSchema, &pSW) == NULL){ tqError("vgId:%d, failed to add schema to rsp msg", pTq->pVnode->config.vgId); @@ -391,29 +390,30 @@ END: } } -int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, int8_t sourceExcluded) { +int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, const SMqPollReq* pRequest) { int32_t code = 0; int32_t lino = 0; - TSDB_CHECK_NULL(pRsp, code, lino, END, TSDB_CODE_INVALID_PARA); - TSDB_CHECK_NULL(pTq, code, lino, END, TSDB_CODE_INVALID_PARA); - TSDB_CHECK_NULL(pHandle, code, lino, END, TSDB_CODE_INVALID_PARA); - TSDB_CHECK_NULL(totalRows, code, lino, END, TSDB_CODE_INVALID_PARA); STqExecHandle* pExec = &pHandle->execHandle; STqReader* pReader = pExec->pTqReader; - code = tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver); + SArray *rawList = NULL; + if (pRequest->rawData){ + rawList = taosArrayInit(0, POINTER_BYTES); + } + code = tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver, rawList); TSDB_CHECK_CODE(code, lino, END); if (pExec->subType == TOPIC_SUB_TYPE__TABLE) { while (tqNextBlockImpl(pReader, NULL)) { - tqProcessSubData(pTq, pHandle, pRsp, totalRows, sourceExcluded); + tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); } } else if (pExec->subType == TOPIC_SUB_TYPE__DB) { while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) { - tqProcessSubData(pTq, pHandle, pRsp, totalRows, sourceExcluded); + tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); } } END: + taosArrayDestroy(rawList); if (code != 0){ tqError("%s failed at %d, failed to scan log:%s", __FUNCTION__, lino, tstrerror(code)); } diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 197a45cdb9..d619e0534d 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -131,7 +131,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand } tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, (latest) offset reset to %" PRId64, consumerId, pHandle->subKey, vgId, dataRsp.rspOffset.version); - code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); + code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, (pRequest->rawData == 1) ? TMQ_MSG_TYPE__POLL_RAW_DATA_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); tDeleteMqDataRsp(&dataRsp); *pBlockReturned = true; @@ -222,6 +222,10 @@ end: static void tDeleteCommon(void* parm) {} +#define POLL_RSP_TYPE(pRequest,taosxRsp) \ +taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : \ +(pRequest->rawData == 1 ? TMQ_MSG_TYPE__POLL_RAW_DATA_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP) + static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, STqOffsetVal* offset) { int32_t vgId = TD_VID(pTq->pVnode); @@ -274,7 +278,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, } tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, - taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); + POLL_RSP_TYPE(pRequest, taosxRsp), vgId); goto END; } @@ -287,7 +291,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if (totalRows > 0) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, - taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); + POLL_RSP_TYPE(pRequest, taosxRsp), vgId); goto END; } @@ -370,12 +374,14 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, .ver = pHead->version, }; - TQ_ERR_GO_TO_END(tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows, pRequest->sourceExcluded)); + TQ_ERR_GO_TO_END(tqTaosxScanLog(pTq, pHandle, submit, &taosxRsp, &totalRows, pRequest)); - if (totalRows >= tmqRowSize || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout))) { + if ((pRequest->rawData == 0 && totalRows >= tmqRowSize) || + (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout)) || + (pRequest->rawData != 0 && totalRows >= TQ_POLL_MAX_BYTES)) { tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, - taosxRsp.createTableNum > 0 ? TMQ_MSG_TYPE__POLL_DATA_META_RSP : TMQ_MSG_TYPE__POLL_DATA_RSP, vgId); + POLL_RSP_TYPE(pRequest, taosxRsp), vgId); goto END; } else { fetchVer++; @@ -534,7 +540,9 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* int32_t len = 0; int32_t code = 0; - if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || + type == TMQ_MSG_TYPE__WALINFO_RSP || + type == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { tEncodeSize(tEncodeMqDataRsp, pRsp, len, code); } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { tEncodeSize(tEncodeSTaosxRsp, pRsp, len, code); @@ -558,7 +566,9 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* SEncoder encoder = {0}; tEncoderInit(&encoder, abuf, len); - if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) { + if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || + type == TMQ_MSG_TYPE__WALINFO_RSP || + type == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { code = tEncodeMqDataRsp(&encoder, pRsp); } else if (type == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { code = tEncodeSTaosxRsp(&encoder, pRsp); diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index c7b0caf286..3fb7b597ce 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -1873,7 +1873,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t ver, void *pReq, in len -= sizeof(SSubmitReq2Msg); SDecoder dc = {0}; tDecoderInit(&dc, pReq, len); - if (tDecodeSubmitReq(&dc, pSubmitReq) < 0) { + if (tDecodeSubmitReq(&dc, pSubmitReq, NULL) < 0) { code = TSDB_CODE_INVALID_MSG; goto _exit; } diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 1060cbcffe..4f647a2e9c 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -3953,7 +3953,7 @@ FETCH_NEXT_BLOCK: QUERY_CHECK_NULL(pSubmit, code, lino, _end, terrno); qDebug("set %d/%d as the input submit block, %s", current + 1, totalBlocks, id); - if (pAPI->tqReaderFn.tqReaderSetSubmitMsg(pInfo->tqReader, pSubmit->msgStr, pSubmit->msgLen, pSubmit->ver) < + if (pAPI->tqReaderFn.tqReaderSetSubmitMsg(pInfo->tqReader, pSubmit->msgStr, pSubmit->msgLen, pSubmit->ver, NULL) < 0) { qError("submit msg messed up when initializing stream submit block %p, current %d/%d, %s", pSubmit, current, totalBlocks, id); diff --git a/source/libs/parser/src/parInsertSml.c b/source/libs/parser/src/parInsertSml.c index 676aed4464..bd463bfd9d 100644 --- a/source/libs/parser/src/parInsertSml.c +++ b/source/libs/parser/src/parInsertSml.c @@ -403,3 +403,18 @@ end: } return code; } + +int32_t smlBuildOutputRaw(SQuery* handle, SHashObj* pVgHash) { + int32_t lino = 0; + int32_t code = 0; + + SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)(handle)->pRoot; + code = insBuildVgDataBlocks(pVgHash, pStmt->pVgDataBlocks, &pStmt->pDataBlocks, false); + TSDB_CHECK_CODE(code, lino, end); + + end: + if (code != 0) { + uError("%s failed at %d since %s", __func__, lino, tstrerror(code)); + } + return code; +} diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index ed1f498a32..8ec9032a7c 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -483,7 +483,7 @@ static int32_t fillVgroupDataCxt(STableDataCxt* pTableCxt, SVgroupDataCxt* pVgCx return code; } -static int32_t createVgroupDataCxt(STableDataCxt* pTableCxt, SHashObj* pVgroupHash, SArray* pVgroupList, +static int32_t createVgroupDataCxt(int32_t vgId, SHashObj* pVgroupHash, SArray* pVgroupList, SVgroupDataCxt** pOutput) { SVgroupDataCxt* pVgCxt = taosMemoryCalloc(1, sizeof(SVgroupDataCxt)); if (NULL == pVgCxt) { @@ -495,7 +495,7 @@ static int32_t createVgroupDataCxt(STableDataCxt* pTableCxt, SHashObj* pVgroupHa return terrno; } - pVgCxt->vgId = pTableCxt->pMeta->vgId; + pVgCxt->vgId = vgId; int32_t code = taosHashPut(pVgroupHash, &pVgCxt->vgId, sizeof(pVgCxt->vgId), &pVgCxt, POINTER_BYTES); if (TSDB_CODE_SUCCESS == code) { if (NULL == taosArrayPush(pVgroupList, &pVgCxt)) { @@ -642,7 +642,7 @@ int32_t insAppendStmtTableDataCxt(SHashObj* pAllVgHash, STableColsData* pTbData, if (NULL == pp) { pp = taosHashGet(pBuildInfo->pVgroupHash, &vgId, sizeof(vgId)); if (NULL == pp) { - code = createVgroupDataCxt(pTbCtx, pBuildInfo->pVgroupHash, pBuildInfo->pVgroupList, &pVgCxt); + code = createVgroupDataCxt(vgId, pBuildInfo->pVgroupHash, pBuildInfo->pVgroupList, &pVgCxt); } else { pVgCxt = *(SVgroupDataCxt**)pp; } @@ -777,7 +777,7 @@ int32_t insMergeTableDataCxt(SHashObj* pTableHash, SArray** pVgDataBlocks, bool int32_t vgId = pTableCxt->pMeta->vgId; void** pp = taosHashGet(pVgroupHash, &vgId, sizeof(vgId)); if (NULL == pp) { - code = createVgroupDataCxt(pTableCxt, pVgroupHash, pVgroupList, &pVgCxt); + code = createVgroupDataCxt(vgId, pVgroupHash, pVgroupList, &pVgCxt); } else { pVgCxt = *(SVgroupDataCxt**)pp; } @@ -1074,3 +1074,33 @@ int rawBlockBindData(SQuery* query, STableMeta* pTableMeta, void* data, SVCreate end: return ret; } + +int rawBlockBindRawData(SHashObj* pVgroupHash, SArray* pVgroupList, STableMeta* pTableMeta, void* data) { + transformRawSSubmitTbData(data, pTableMeta->suid, pTableMeta->uid, pTableMeta->sversion); + SVgroupDataCxt* pVgCxt = NULL; + void** pp = taosHashGet(pVgroupHash, &pTableMeta->vgId, sizeof(pTableMeta->vgId)); + if (NULL == pp) { + int code = createVgroupDataCxt(pTableMeta->vgId, pVgroupHash, pVgroupList, &pVgCxt); + if (code != 0){ + return code; + } + } else { + pVgCxt = *(SVgroupDataCxt**)pp; + } + if (NULL == pVgCxt->pData->aSubmitTbData) { + pVgCxt->pData->aSubmitTbData = taosArrayInit(0, POINTER_BYTES); + pVgCxt->pData->raw = true; + if (NULL == pVgCxt->pData->aSubmitTbData) { + return terrno; + } + } + + // push data to submit, rebuild empty data for next submit + if (NULL == taosArrayPush(pVgCxt->pData->aSubmitTbData, &data)) { + return terrno; + } + + qDebug("add raw data to vgId:%d", pTableMeta->vgId); + + return 0; +} diff --git a/source/util/src/terror.c b/source/util/src/terror.c index ba2d471ccf..842d42a002 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -859,6 +859,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_REPLAY_NOT_SUPPORT, "Replay is disabled TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_TABLE_QUALIFIED, "No table qualified for query") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_NEED_REBALANCE, "No need rebalance") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_STATUS, "Invalid status, please subscribe topic first") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_DATA, "Invalid data use here") // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") From 3fb2ec432ed03486d3f3bd1ed1c9495797de2c0f Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 22 Jan 2025 17:40:59 +0800 Subject: [PATCH 05/67] fix:[TS-5776]add raw type from consumer --- source/client/src/clientTmq.c | 2 +- source/common/src/tdatablock.c | 2 +- source/libs/executor/src/dataInserter.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index e611e7e417..4d5ecdc320 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -2587,7 +2587,7 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) { END: terrno = code; - if (tmq != NULL) { + if (tmq != NULL && terrno != 0) { tqErrorC("consumer:0x%" PRIx64 " poll error at line:%d, msg:%s", tmq->consumerId, lino, tstrerror(terrno)); } return NULL; diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index bd18c9ceb9..adfa7a21ef 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -2682,7 +2682,7 @@ int32_t buildSubmitReqFromDataBlock(SSubmitReq2** ppReq, const SSDataBlock* pDat terrno = 0; if (NULL == pReq) { - if (!(pReq = taosMemoryMalloc(sizeof(SSubmitReq2)))) { + if (!(pReq = taosMemoryCalloc(1, sizeof(SSubmitReq2)))) { code = terrno; goto _end; } diff --git a/source/libs/executor/src/dataInserter.c b/source/libs/executor/src/dataInserter.c index ec041cba70..3bd6f4e64a 100644 --- a/source/libs/executor/src/dataInserter.c +++ b/source/libs/executor/src/dataInserter.c @@ -187,7 +187,7 @@ int32_t buildSubmitReqFromBlock(SDataInserterHandle* pInserter, SSubmitReq2** pp terrno = TSDB_CODE_SUCCESS; if (NULL == pReq) { - if (!(pReq = taosMemoryMalloc(sizeof(SSubmitReq2)))) { + if (!(pReq = taosMemoryCalloc(1, sizeof(SSubmitReq2)))) { goto _end; } From 7fad4bceb0e992a8fc16704124429fba039317dc Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 24 Jan 2025 13:44:56 +0800 Subject: [PATCH 06/67] fix:[TS-5776]add raw type from consumer --- include/common/tcommon.h | 2 +- include/common/tmsg.h | 7 ++ include/util/taoserror.h | 1 + source/client/inc/clientInt.h | 4 - source/client/src/clientMain.c | 3 +- source/client/src/clientRawBlockWrite.c | 19 +++-- source/client/src/clientTmq.c | 29 +++---- source/common/src/msg/tmsg.c | 107 +++++++++++++----------- source/dnode/vnode/src/tq/tq.c | 9 +- source/dnode/vnode/src/tq/tqRead.c | 8 +- source/dnode/vnode/src/tq/tqScan.c | 30 +++++++ source/dnode/vnode/src/tq/tqUtil.c | 5 +- source/libs/parser/src/parInsertUtil.c | 9 +- source/util/src/terror.c | 1 + 14 files changed, 145 insertions(+), 89 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 08fae0952c..ecfa17ffb3 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -125,7 +125,7 @@ enum { }; static char* tmqMsgTypeStr[] = { - "data", "meta", "ask ep", "meta data", "wal info", "batch meta" + "data", "meta", "ask ep", "meta data", "wal info", "batch meta", "raw data" }; enum { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index d14044a8bf..c9b9bd417c 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -4182,6 +4182,7 @@ typedef struct { int8_t sourceExcluded; int8_t rawData; int8_t enableBatchMeta; + SHashObj *uidHash; // to find if uid is duplicated } SMqPollReq; int32_t tSerializeSMqPollReq(void* buf, int32_t bufLen, SMqPollReq* pReq); @@ -4255,13 +4256,19 @@ typedef struct { SArray* createTableLen; SArray* createTableReq; }; + struct{ + int32_t len; + void* rawData; + }; }; } SMqDataRsp; int32_t tEncodeMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pObj); int32_t tDecodeMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp); +int32_t tDecodeMqRawDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp); void tDeleteMqDataRsp(SMqDataRsp* pRsp); +void tDeleteMqRawDataRsp(SMqDataRsp* pRsp); int32_t tEncodeSTaosxRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp); int32_t tDecodeSTaosxRsp(SDecoder* pDecoder, SMqDataRsp* pRsp); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 8488e2800a..793ffa17bc 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -1017,6 +1017,7 @@ int32_t taosGetErrSize(); #define TSDB_CODE_TMQ_NO_NEED_REBALANCE TAOS_DEF_ERROR_CODE(0, 0x4016) #define TSDB_CODE_TMQ_INVALID_STATUS TAOS_DEF_ERROR_CODE(0, 0x4017) #define TSDB_CODE_TMQ_INVALID_DATA TAOS_DEF_ERROR_CODE(0, 0x4018) +#define TSDB_CODE_TMQ_DUPLICATE_UID TAOS_DEF_ERROR_CODE(0, 0x4019) // stream #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index ae88883739..c9e0410341 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -253,10 +253,6 @@ typedef struct { SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; - struct{ - int32_t len; - void* rawData; - }; }; } SMqRspObj; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index eb1bffeee3..9f0706bdaf 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -555,8 +555,7 @@ void taos_free_result(TAOS_RES *res) { } else if (TD_RES_TMQ_BATCH_META(res)) { tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp); } else if (TD_RES_TMQ_RAW(res)) { - taosMemoryFree(pRsp->rawData); - doFreeReqResultInfo(&pRsp->resInfo); + tDeleteMqRawDataRsp(&pRsp->dataRsp); } taosMemoryFree(pRsp); } diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 689adf51e7..f418b7e94c 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -2319,8 +2319,8 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) SRequestConnInfo conn = {0}; RAW_RETURN_CHECK(buildRawRequest(taos, &pRequest, &pCatalog, &conn)); - uDebug(LOG_ID_TAG " write raw metadata, data:%p, dataLen:%d", LOG_ID_VALUE, data, dataLen); - RAW_RETURN_CHECK(decodeRawData(&decoder, data, dataLen, tDecodeSTaosxRsp, &rspObj)); + uDebug(LOG_ID_TAG " write raw rawdata, data:%p, dataLen:%d", LOG_ID_VALUE, data, dataLen); + RAW_RETURN_CHECK(decodeRawData(&decoder, data, dataLen, tDecodeMqDataRsp, &rspObj)); SHashObj* pVgHash = NULL; SHashObj* pNameHash = NULL; @@ -2329,9 +2329,9 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) int retry = 0; while (1) { RAW_RETURN_CHECK(smlInitHandle(&pQuery)); - uDebug(LOG_ID_TAG " write raw meta data block num:%d", LOG_ID_VALUE, rspObj.dataRsp.blockNum); + uDebug(LOG_ID_TAG " write raw rawdata block num:%d", LOG_ID_VALUE, rspObj.dataRsp.blockNum); SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)(pQuery)->pRoot; - pVgroupHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false); + pVgroupHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); RAW_NULL_CHECK(pVgroupHash); pStmt->pVgDataBlocks = taosArrayInit(8, POINTER_BYTES); RAW_NULL_CHECK(pStmt->pVgDataBlocks); @@ -2384,7 +2384,7 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) } end: - uDebug(LOG_ID_TAG " write raw metadata return, msg:%s", LOG_ID_VALUE, tstrerror(code)); + uDebug(LOG_ID_TAG " write raw rawdata return, msg:%s", LOG_ID_VALUE, tstrerror(code)); tDeleteSTaosxRsp(&rspObj.dataRsp); tDecoderClear(&decoder); qDestroyQuery(pQuery); @@ -2567,6 +2567,7 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { uError("invalid parameter in %s", __func__); return TSDB_CODE_INVALID_PARA; } + *raw = (tmq_raw_data){0}; SMqRspObj* rspObj = ((SMqRspObj*)res); if (TD_RES_TMQ_META(res)) { raw->raw = rspObj->metaRsp.metaRsp; @@ -2595,8 +2596,9 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { raw->raw_type = rspObj->resType; uDebug("tmq get raw batch meta:%p", raw); } else if (TD_RES_TMQ_RAW(res)) { - raw->raw = rspObj->rawData; - raw->raw_len = rspObj->len; + raw->raw = rspObj->dataRsp.rawData; + rspObj->dataRsp.rawData = NULL; + raw->raw_len = rspObj->dataRsp.len; raw->raw_type = rspObj->resType; uDebug("tmq get raw raw:%p", raw); } else { @@ -2609,9 +2611,10 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) { void tmq_free_raw(tmq_raw_data raw) { uDebug("tmq free raw data type:%d", raw.raw_type); if (raw.raw_type == RES_TYPE__TMQ || - raw.raw_type == RES_TYPE__TMQ_RAWDATA || raw.raw_type == RES_TYPE__TMQ_METADATA) { taosMemoryFree(raw.raw); + } else if(raw.raw_type == RES_TYPE__TMQ_RAWDATA && raw.raw != NULL){ + taosMemoryFree(raw.raw - sizeof(SMqRspHead)); } (void)memset(terrMsg, 0, ERR_MSG_LEN); } diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 4d5ecdc320..e87ef4c00d 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -197,10 +197,6 @@ typedef struct { SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; - struct{ - int32_t len; - void* rawData; - }; }; } SMqPollRspWrapper; @@ -290,7 +286,7 @@ typedef struct { } SVgroupSaveInfo; static TdThreadOnce tmqInit = PTHREAD_ONCE_INIT; // initialize only once -volatile int32_t tmqInitRes = 0; // initialize rsp code +volatile int32_t tmqInitRes = -1; // initialize rsp code static SMqMgmt tmqMgmt = {0}; tmq_conf_t* tmq_conf_new() { @@ -1135,9 +1131,7 @@ static void tmqFreeRspWrapper(SMqRspWrapper* rspWrapper) { } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { DELETE_POLL_RSP(tDeleteMqBatchMetaRsp,&pRsp->batchMetaRsp) } else if (rspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { - SMqPollRspWrapper* pRsp = &rspWrapper->pollRsp; - taosMemoryFreeClear(pRsp->pEpset); - taosMemoryFreeClear(pRsp->rawData); + DELETE_POLL_RSP(tDeleteMqRawDataRsp, &pRsp->dataRsp) } } @@ -2051,7 +2045,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { goto END; } rspType = ((SMqRspHead*)pMsg->pData)->mqMsgType; - tqDebugC("consumer:0x%" PRIx64 " recv poll rsp, vgId:%d, type %d,QID:0x%" PRIx64, tmq->consumerId, vgId, rspType, requestId); + tqDebugC("consumer:0x%" PRIx64 " recv poll rsp, vgId:%d, type %d(%s),QID:0x%" PRIx64, tmq->consumerId, vgId, rspType, tmqMsgTypeStr[rspType], requestId); if (rspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) } else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) { @@ -2061,8 +2055,9 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { } else if (rspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) } else if (rspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { - pRspWrapper->pollRsp.len = pMsg->len; - pRspWrapper->pollRsp.rawData = pMsg->pData; + PROCESS_POLL_RSP(tDecodeMqRawDataRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.len = pMsg->len - sizeof(SMqRspHead); + pRspWrapper->pollRsp.dataRsp.rawData = POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)); pMsg->pData = NULL; } else { // invalid rspType tqErrorC("consumer:0x%" PRIx64 " invalid rsp msg received, type:%d ignored", tmq->consumerId, rspType); @@ -2085,8 +2080,8 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { taosFreeQitem(pRspWrapper); tqErrorC("consumer:0x%" PRIx64 " put poll res into mqueue failed, code:%d", tmq->consumerId, code); } else { - tqDebugC("consumer:0x%" PRIx64 " put poll res into mqueue, type:%d, vgId:%d, total in queue:%d,QID:0x%" PRIx64, - tmq ? tmq->consumerId : 0, rspType, vgId, taosQueueItemSize(tmq->mqueue), requestId); + tqDebugC("consumer:0x%" PRIx64 " put poll res into mqueue, type:%d(%s), vgId:%d, total in queue:%d,QID:0x%" PRIx64, + tmq ? tmq->consumerId : 0, rspType, tmqMsgTypeStr[rspType], vgId, taosQueueItemSize(tmq->mqueue), requestId); } } @@ -2453,8 +2448,7 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ char buf[TSDB_OFFSET_LEN] = {0}; tFormatOffset(buf, TSDB_OFFSET_LEN, &pollRspWrapper->rspOffset); - if (pollRspWrapper->dataRsp.blockNum == 0 && - pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { + if (pollRspWrapper->dataRsp.blockNum == 0) { tqDebugC("consumer:0x%" PRIx64 " empty block received, vgId:%d, offset:%s, vg total:%" PRId64 ", total:%" PRId64 ",QID:0x%" PRIx64, tmq->consumerId, pVg->vgId, buf, pVg->numOfRows, tmq->totalRows, pollRspWrapper->reqId); @@ -2471,9 +2465,6 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ if (pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP){ tmqBuildRspFromWrapperInner(pollRspWrapper, pVg, &numOfRows, pRspObj); tmq->totalRows += numOfRows; - } else { - pRspObj->rawData = pollRspWrapper->rawData; - pRspObj->len = pollRspWrapper->len; } pVg->emptyBlockReceiveTs = 0; if (tmq->replayEnable && pRspWrapper->tmqRspType != TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { @@ -2773,7 +2764,7 @@ const char* tmq_get_table_name(TAOS_RES* res) { if (res == NULL) { return NULL; } - if (TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) ) { + if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res) ) { SMqRspObj* pRspObj = (SMqRspObj*)res; SMqDataRsp* data = &pRspObj->dataRsp; if (!data->withTbName || data->blockTbName == NULL || pRspObj->resIter < 0 || diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 1b6c7add3f..cb8c98bde4 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -9270,7 +9270,13 @@ _exit: return code; } -void tDestroySMqPollReq(SMqPollReq *pReq) { tOffsetDestroy(&pReq->reqOffset); } +void tDestroySMqPollReq(SMqPollReq *pReq) { + tOffsetDestroy(&pReq->reqOffset); + if (pReq->uidHash != NULL) { + taosHashCleanup(pReq->uidHash); + pReq->uidHash = NULL; + } +} int32_t tSerializeSTaskDropReq(void *buf, int32_t bufLen, STaskDropReq *pReq) { int32_t code = 0; int32_t lino; @@ -11410,6 +11416,9 @@ int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) { if (taosArrayPush(pRsp->blockData, &data) == NULL) { TAOS_CHECK_EXIT(terrno); } +// for (int m= 0; m < 56; m++){ +// printf("decode data[%d] = %d\n", m, *((int8_t *)data+18+m)); +// } int32_t len = bLen; if (taosArrayPush(pRsp->blockDataLen, &len) == NULL) { TAOS_CHECK_EXIT(terrno); @@ -11455,6 +11464,17 @@ int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) { return 0; } +int32_t tDecodeMqRawDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) { + int32_t code = 0; + int32_t lino; + + TAOS_CHECK_EXIT(tDecodeSTqOffsetVal(pDecoder, &pRsp->reqOffset)); + TAOS_CHECK_EXIT(tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset)); + TAOS_CHECK_EXIT(tDecodeI32(pDecoder, &pRsp->blockNum)); +_exit: + return code; +} + static void tDeleteMqDataRspCommon(SMqDataRsp *pRsp) { taosArrayDestroy(pRsp->blockDataLen); pRsp->blockDataLen = NULL; @@ -11528,6 +11548,14 @@ void tDeleteSTaosxRsp(SMqDataRsp *pRsp) { pRsp->createTableReq = NULL; } +void tDeleteMqRawDataRsp(SMqDataRsp *pRsp) { + tOffsetDestroy(&pRsp->reqOffset); + tOffsetDestroy(&pRsp->rspOffset); + if (pRsp->rawData != NULL){ + taosMemoryFree(pRsp->rawData - sizeof(SMqRspHead)); + } +} + int32_t tEncodeSSingleDeleteReq(SEncoder *pEncoder, const SSingleDeleteReq *pReq) { TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pReq->tbname)); TAOS_CHECK_RETURN(tEncodeI64(pEncoder, pReq->startTs)); @@ -11688,14 +11716,13 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa uint8_t version; uint8_t* dataAfterCreate = NULL; - uint8_t* dataStart = pCoder->data; - uint32_t posStart = pCoder->pos; + uint8_t* dataStart = pCoder->data + pCoder->pos; uint32_t posAfterCreate = 0; TAOS_CHECK_EXIT(tStartDecode(pCoder)); uint32_t pos = pCoder->pos; TAOS_CHECK_EXIT(tDecodeI32v(pCoder, &flags)); - uint32_t flagsLen = pCoder->pos - posStart; + uint32_t flagsLen = pCoder->pos - pos; pSubmitTbData->flags = flags & 0xff; version = (flags >> 8) & 0xff; @@ -11716,56 +11743,35 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pSubmitTbData->uid)); TAOS_CHECK_EXIT(tDecodeI32v(pCoder, &pSubmitTbData->sver)); - if (rawData != NULL){ // no need to decode data - if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { - uint64_t nColData = 0; + if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { + uint64_t nColData = 0; - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); - for (int32_t i = 0; i < nColData; ++i) { - SColData pColData = {0}; - TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, &pColData)); - } - } else { - uint64_t nRow = 0; - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); + pSubmitTbData->aCol = taosArrayInit(nColData, sizeof(SColData)); + if (pSubmitTbData->aCol == NULL) { + TAOS_CHECK_EXIT(terrno); + } - for (int32_t iRow = 0; iRow < nRow; ++iRow) { - SRow *ppRow = NULL; - TAOS_CHECK_EXIT(tDecodeRow(pCoder, &ppRow)); - } + for (int32_t i = 0; i < nColData; ++i) { + TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1))); } } else { - if (pSubmitTbData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) { - uint64_t nColData = 0; + uint64_t nRow = 0; + TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nColData)); + pSubmitTbData->aRowP = taosArrayInit(nRow, sizeof(SRow *)); + if (pSubmitTbData->aRowP == NULL) { + TAOS_CHECK_EXIT(terrno); + } - pSubmitTbData->aCol = taosArrayInit(nColData, sizeof(SColData)); - if (pSubmitTbData->aCol == NULL) { + for (int32_t iRow = 0; iRow < nRow; ++iRow) { + SRow **ppRow = taosArrayReserve(pSubmitTbData->aRowP, 1); + if (ppRow == NULL) { TAOS_CHECK_EXIT(terrno); } - for (int32_t i = 0; i < nColData; ++i) { - TAOS_CHECK_EXIT(tDecodeColData(version, pCoder, taosArrayReserve(pSubmitTbData->aCol, 1))); - } - } else { - uint64_t nRow = 0; - TAOS_CHECK_EXIT(tDecodeU64v(pCoder, &nRow)); - - pSubmitTbData->aRowP = taosArrayInit(nRow, sizeof(SRow *)); - if (pSubmitTbData->aRowP == NULL) { - TAOS_CHECK_EXIT(terrno); - } - - for (int32_t iRow = 0; iRow < nRow; ++iRow) { - SRow **ppRow = taosArrayReserve(pSubmitTbData->aRowP, 1); - if (ppRow == NULL) { - TAOS_CHECK_EXIT(terrno); - } - - TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow)); - } + TAOS_CHECK_EXIT(tDecodeRow(pCoder, ppRow)); } } @@ -11774,7 +11780,6 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pSubmitTbData->ctimeMs)); } - tEndDecode(pCoder); if (rawData != NULL){ if (dataAfterCreate != NULL){ TAOS_MEMCPY(dataAfterCreate - INT_BYTES - flagsLen, dataStart, INT_BYTES + flagsLen); @@ -11784,7 +11789,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa *(void**)rawData = dataStart; } } - + tEndDecode(pCoder); _exit: return code; @@ -11839,12 +11844,20 @@ int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq, SArray* rawList) { goto _exit; } + bool hasCreateTable = false; for (uint64_t i = 0; i < nSubmitTbData; i++) { - if (tDecodeSSubmitTbData(pCoder, taosArrayReserve(pReq->aSubmitTbData, 1), + SSubmitTbData* data = taosArrayReserve(pReq->aSubmitTbData, 1); + if (tDecodeSSubmitTbData(pCoder, data, rawList != NULL ? taosArrayReserve(rawList, 1) : NULL) < 0) { code = TSDB_CODE_INVALID_MSG; goto _exit; } + if (data->flags & SUBMIT_REQ_AUTO_CREATE_TABLE){ + hasCreateTable = true; + } + } + if (rawList != NULL && hasCreateTable){ + taosArrayClear(rawList); } tEndDecode(pCoder); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 3bfc50fcb2..2aae3845f0 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -397,7 +397,14 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) { terrno = TSDB_CODE_INVALID_MSG; goto END; } - + if (req.rawData == 1){ + req.uidHash = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK); + if (req.uidHash == NULL) { + tqError("tq poll rawData taosHashInit failed"); + code = terrno; + goto END; + } + } int64_t consumerId = req.consumerId; int32_t reqEpoch = req.epoch; STqOffsetVal reqOffset = req.reqOffset; diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 6452f7bb5c..1ab76019a9 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -581,17 +581,17 @@ bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) { uid = pSubmitTbData->uid; void* ret = taosHashGet(filterOutUids, &pSubmitTbData->uid, sizeof(int64_t)); TSDB_CHECK_NULL(ret, code, lino, END, true); - tqDebug("iterator data block in hash continue, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); + tqDebug("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); pReader->nextBlk++; } tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE); pReader->nextBlk = 0; pReader->msg.msgStr = NULL; - tqDebug("iterator data block end, block progress:%d/%d, uid:%"PRId64, pReader->nextBlk, blockSz, uid); + tqDebug("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); END: - tqDebug("%s:%d return:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); + tqDebug("%s:%d get data:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); return code; } @@ -1117,7 +1117,7 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* block if (code != 0) { return code; } - } else if (rawList != NULL){ + } else if (rawList != NULL && taosArrayGetSize(rawList) > 0) { if (taosArrayPush(schemas, &pReader->pSchemaWrapper) == NULL){ return terrno; } diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 9501ca4099..0e697ccd8b 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -31,6 +31,9 @@ static int32_t tqAddRawDataToRsp(const void* rawData, SMqDataRsp* pRsp, int8_t p memcpy(pRetrieve->data, rawData, *(uint32_t *)rawData + INT_BYTES); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &dataStrLen), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); +// for (int m= 0; m < 56; m++){ +// printf("add data[%d] = %d\n", m, *((int8_t *)rawData+m)); +// } tqDebug("add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); END: @@ -337,6 +340,26 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int bool tmp = (pSubmitTbData->flags & pRequest->sourceExcluded) != 0; TSDB_CHECK_CONDITION(!tmp, code, lino, END, TSDB_CODE_SUCCESS); int32_t blockNum = taosArrayGetSize(pBlocks) == 0 ? 1 : taosArrayGetSize(pBlocks); + if (rawList != NULL && taosArrayGetSize(pBlocks) == 0){ + if (taosHashGet(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES) != NULL) { + tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 " is already exists", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + terrno = TSDB_CODE_TMQ_DUPLICATE_UID; + pReader->nextBlk = 0; + goto END; + } else { + code = taosHashPut(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES, &pExec->pTqReader->lastBlkUid, LONG_BYTES); + TSDB_CHECK_CODE(code, lino, END); + } + } + + // this submit data is metadata and previous data is data + if (rawList != NULL && *totalRows > 0 && pSubmitTbData->pCreateTbReq != NULL && taosArrayGetSize(pBlocks) > 0){ + tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + terrno = TSDB_CODE_TMQ_DUPLICATE_UID; + pRsp->createTableNum = 0; + pReader->nextBlk = 0; + goto END; + } if (pRsp->withTbName) { int64_t uid = pExec->pTqReader->lastBlkUid; @@ -398,6 +421,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData SArray *rawList = NULL; if (pRequest->rawData){ rawList = taosArrayInit(0, POINTER_BYTES); + TSDB_CHECK_NULL(rawList, code, lino, END, terrno); } code = tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver, rawList); TSDB_CHECK_CODE(code, lino, END); @@ -405,10 +429,16 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData if (pExec->subType == TOPIC_SUB_TYPE__TABLE) { while (tqNextBlockImpl(pReader, NULL)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); + if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ + goto END; + } } } else if (pExec->subType == TOPIC_SUB_TYPE__DB) { while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); + if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ + goto END; + } } } diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index d619e0534d..86a5bba712 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -378,10 +378,11 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if ((pRequest->rawData == 0 && totalRows >= tmqRowSize) || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout)) || - (pRequest->rawData != 0 && totalRows >= TQ_POLL_MAX_BYTES)) { - tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer + 1); + (pRequest->rawData != 0 && (totalRows >= TQ_POLL_MAX_BYTES || taosxRsp.createTableNum > 0 || terrno == TSDB_CODE_TMQ_DUPLICATE_UID))) { + tqOffsetResetToLog(&taosxRsp.rspOffset, terrno == TSDB_CODE_TMQ_DUPLICATE_UID ? fetchVer : fetchVer + 1); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, POLL_RSP_TYPE(pRequest, taosxRsp), vgId); + if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){terrno = 0;} goto END; } else { fetchVer++; diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index 8ec9032a7c..c9d1454fbc 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -723,7 +723,7 @@ int32_t tbNum) { SHashObj* pVgroupHash = taosHashInit(128, taosGetDefaultHashFun */ int32_t insMergeTableDataCxt(SHashObj* pTableHash, SArray** pVgDataBlocks, bool isRebuild) { - SHashObj* pVgroupHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false); + SHashObj* pVgroupHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); SArray* pVgroupList = taosArrayInit(8, POINTER_BYTES); if (NULL == pVgroupHash || NULL == pVgroupList) { taosHashCleanup(pVgroupHash); @@ -859,6 +859,13 @@ int32_t insBuildVgDataBlocks(SHashObj* pVgroupsHashObj, SArray* pVgDataCxtList, } if (TSDB_CODE_SUCCESS == code) { code = buildSubmitReq(src->vgId, src->pData, &dst->pData, &dst->size); + SSubmitReq2 *pSubmitReq = &(SSubmitReq2){0}; + SDecoder dc = {0}; + tDecoderInit(&dc, POINTER_SHIFT(dst->pData, sizeof(SSubmitReq2Msg)), dst->size - sizeof(SSubmitReq2Msg)); + if (tDecodeSubmitReq(&dc, pSubmitReq, NULL) < 0) { + code = TSDB_CODE_INVALID_MSG; + } + tDecoderClear(&dc); } if (TSDB_CODE_SUCCESS == code) { code = (NULL == taosArrayPush(pDataBlocks, &dst) ? terrno : TSDB_CODE_SUCCESS); diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 842d42a002..c05423e51c 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -860,6 +860,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_TABLE_QUALIFIED, "No table qualified TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_NEED_REBALANCE, "No need rebalance") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_STATUS, "Invalid status, please subscribe topic first") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_DATA, "Invalid data use here") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_DUPLICATE_UID, "Duplicate uid") // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") From 902d06777672356f4bedc51334e321ca6faf1ebc Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 24 Jan 2025 14:56:00 +0800 Subject: [PATCH 07/67] fix:[TS-5776]add raw type from consumer --- source/client/src/clientRawBlockWrite.c | 2 +- source/common/src/msg/tmsg.c | 2 +- source/dnode/vnode/inc/vnode.h | 1 + source/dnode/vnode/src/tq/tqRead.c | 20 +++++++++++--------- source/dnode/vnode/src/tq/tqScan.c | 19 ++++++++----------- source/libs/parser/src/parInsertUtil.c | 7 ------- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index f418b7e94c..f7515cc359 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -2385,7 +2385,7 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) end: uDebug(LOG_ID_TAG " write raw rawdata return, msg:%s", LOG_ID_VALUE, tstrerror(code)); - tDeleteSTaosxRsp(&rspObj.dataRsp); + tDeleteMqDataRsp(&rspObj.dataRsp); tDecoderClear(&decoder); qDestroyQuery(pQuery); taosHashCleanup(pVgroupHash); diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index cb8c98bde4..3f8e686559 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11734,7 +11734,7 @@ static int32_t tDecodeSSubmitTbData(SDecoder *pCoder, SSubmitTbData *pSubmitTbDa } TAOS_CHECK_EXIT(tDecodeSVCreateTbReq(pCoder, pSubmitTbData->pCreateTbReq)); - dataAfterCreate = pCoder->data; + dataAfterCreate = pCoder->data + pCoder->pos; posAfterCreate = pCoder->pos; } diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 5a6489d182..072db703a6 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -242,6 +242,7 @@ int64_t tqGetResultBlockTime(STqReader *pReader); int32_t extractMsgFromWal(SWalReader *pReader, void **pItem, int64_t maxVer, const char *id); int32_t tqReaderSetSubmitMsg(STqReader *pReader, void *msgStr, int32_t msgLen, int64_t ver, SArray* rawList); +void tqReaderClearSubmitMsg(STqReader *pReader); bool tqNextDataBlockFilterOut(STqReader *pReader, SHashObj *filterOutUids); int32_t tqRetrieveDataBlock(STqReader *pReader, SSDataBlock **pRes, const char *idstr); int32_t tqRetrieveTaosxBlock(STqReader *pReader, SMqDataRsp* pRsp, SArray *blocks, SArray *schemas, SSubmitTbData **pSubmitTbDataRet, SArray* rawList, int8_t fetchMeta); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 1ab76019a9..796a4a8742 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -514,6 +514,13 @@ int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, i return code; } +void tqReaderClearSubmitMsg(STqReader *pReader) { + tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE); + pReader->nextBlk = 0; + pReader->msg.msgStr = NULL; +} + + SWalReader* tqGetWalReader(STqReader* pReader) { if (pReader == NULL) { return NULL; @@ -551,14 +558,12 @@ bool tqNextBlockImpl(STqReader* pReader, const char* idstr) { void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t)); TSDB_CHECK_CONDITION(ret == NULL, code, lino, END, true); - tqDebug("iterator data block in hash continue, progress:%d/%d, total queried tables:%d, uid:%"PRId64, pReader->nextBlk, blockSz, taosHashGetSize(pReader->tbIdHash), uid); + tqDebug("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); pReader->nextBlk++; } - tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE); - pReader->nextBlk = 0; - pReader->msg.msgStr = NULL; - tqDebug("iterator data block end, block progress:%d/%d, uid:%"PRId64, pReader->nextBlk, blockSz, uid); + tqReaderClearSubmitMsg(pReader); + tqDebug("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); END: tqDebug("%s:%d return:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); @@ -584,10 +589,7 @@ bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) { tqDebug("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); pReader->nextBlk++; } - - tDestroySubmitReq(&pReader->submit, TSDB_MSG_FLG_DECODE); - pReader->nextBlk = 0; - pReader->msg.msgStr = NULL; + tqReaderClearSubmitMsg(pReader); tqDebug("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); END: diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 0e697ccd8b..5e30f07e2b 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -344,7 +344,6 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int if (taosHashGet(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES) != NULL) { tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 " is already exists", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); terrno = TSDB_CODE_TMQ_DUPLICATE_UID; - pReader->nextBlk = 0; goto END; } else { code = taosHashPut(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES, &pExec->pTqReader->lastBlkUid, LONG_BYTES); @@ -357,7 +356,6 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); terrno = TSDB_CODE_TMQ_DUPLICATE_UID; pRsp->createTableNum = 0; - pReader->nextBlk = 0; goto END; } @@ -391,26 +389,23 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int continue; } *totalRows += pBlock->info.rows; - blockDataFreeRes(pBlock); } - SSchemaWrapper* pSW = taosArrayGetP(pSchemas, i); - if (taosArrayPush(pRsp->blockSchema, &pSW) == NULL){ + void** pSW = taosArrayGet(pSchemas, i); + if (taosArrayPush(pRsp->blockSchema, pSW) == NULL){ tqError("vgId:%d, failed to add schema to rsp msg", pTq->pVnode->config.vgId); continue; } + *pSW = NULL; pRsp->blockNum++; } tqDebug("vgId:%d, process sub data success, response blocknum:%d, rows:%d", pTq->pVnode->config.vgId, pRsp->blockNum, *totalRows); END: - if (code != 0){ + if (code != 0) { tqError("%s failed at %d, failed to process sub data:%s", __FUNCTION__, lino, tstrerror(code)); - taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); - taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); - } else { - taosArrayDestroy(pBlocks); - taosArrayDestroy(pSchemas); } + taosArrayDestroyEx(pBlocks, (FDelete)blockDataFreeRes); + taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); } int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, const SMqPollReq* pRequest) { @@ -430,6 +425,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData while (tqNextBlockImpl(pReader, NULL)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ + tqReaderClearSubmitMsg(pReader); goto END; } } @@ -437,6 +433,7 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ + tqReaderClearSubmitMsg(pReader); goto END; } } diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index c9d1454fbc..0d70292501 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -859,13 +859,6 @@ int32_t insBuildVgDataBlocks(SHashObj* pVgroupsHashObj, SArray* pVgDataCxtList, } if (TSDB_CODE_SUCCESS == code) { code = buildSubmitReq(src->vgId, src->pData, &dst->pData, &dst->size); - SSubmitReq2 *pSubmitReq = &(SSubmitReq2){0}; - SDecoder dc = {0}; - tDecoderInit(&dc, POINTER_SHIFT(dst->pData, sizeof(SSubmitReq2Msg)), dst->size - sizeof(SSubmitReq2Msg)); - if (tDecodeSubmitReq(&dc, pSubmitReq, NULL) < 0) { - code = TSDB_CODE_INVALID_MSG; - } - tDecoderClear(&dc); } if (TSDB_CODE_SUCCESS == code) { code = (NULL == taosArrayPush(pDataBlocks, &dst) ? terrno : TSDB_CODE_SUCCESS); From 9074a999d0cfd5f0e6e11e8e7b952b3fe0b6a14e Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 24 Jan 2025 15:08:01 +0800 Subject: [PATCH 08/67] fix:[TS-5776]add raw type from consumer --- tests/system-test/7-tmq/tmq_taosx.py | 14 ++++++++++++++ utils/test/c/tmq_taosx_ci.c | 24 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/system-test/7-tmq/tmq_taosx.py b/tests/system-test/7-tmq/tmq_taosx.py index 5047ada1d1..3f72dfc95f 100644 --- a/tests/system-test/7-tmq/tmq_taosx.py +++ b/tests/system-test/7-tmq/tmq_taosx.py @@ -17,6 +17,8 @@ from tmqCommon import * class TDTestCase: updatecfgDict = {'debugFlag': 135, 'asynclog': 0} + clientCfgDict = {'debugFlag': 135, 'asynclog': 0} + updatecfgDict["clientCfg"] = clientCfgDict def init(self, conn, logSql, replicaVar=1): self.replicaVar = int(replicaVar) tdLog.debug(f"start to excute {__file__}") @@ -256,6 +258,17 @@ class TDTestCase: return + def checkWalMultiVgroupsRawData(self): + buildPath = tdCom.getBuildPath() + cmdStr = '%s/build/bin/tmq_taosx_ci -sv 3 -dv 5 -raw'%(buildPath) + tdLog.info(cmdStr) + os.system(cmdStr) + + self.checkData() + self.checkDropData(False) + + return + def checkWalMultiVgroupsWithDropTable(self): buildPath = tdCom.getBuildPath() cmdStr = '%s/build/bin/tmq_taosx_ci -sv 3 -dv 5 -d'%(buildPath) @@ -681,6 +694,7 @@ class TDTestCase: self.checkSnapshot1VgroupTable() self.checkWalMultiVgroups() + self.checkWalMultiVgroupsRawData() self.checkSnapshotMultiVgroups() self.checkWalMultiVgroupsWithDropTable() diff --git a/utils/test/c/tmq_taosx_ci.c b/utils/test/c/tmq_taosx_ci.c index 117f9fa2e1..7b2a90570a 100644 --- a/utils/test/c/tmq_taosx_ci.c +++ b/utils/test/c/tmq_taosx_ci.c @@ -34,6 +34,7 @@ typedef struct { int dstVgroups; char dir[256]; bool btMeta; + bool rawData; } Config; Config g_conf = {0}; @@ -424,6 +425,15 @@ int buildDatabase(TAOS* pConn, TAOS_RES* pRes) { } taos_free_result(pRes); + pRes = + taos_query(pConn, + "insert into stt1 values(now - 2s, 3, 2, 'stt1')"); + if (taos_errno(pRes) != 0) { + printf("failed to create child table stt1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + pRes = taos_query(pConn, "insert into stt1 values(now + 2s, 3, 2, 'stt1') stt3 using stt tags(23, \"stt3\", true) values(now + " @@ -436,6 +446,15 @@ int buildDatabase(TAOS* pConn, TAOS_RES* pRes) { } taos_free_result(pRes); + pRes = + taos_query(pConn, + "insert into stt1 values(now + 442s, 3, 2, 'stt1')"); + if (taos_errno(pRes) != 0) { + printf("failed to create child table stt1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + return 0; } @@ -633,6 +652,9 @@ tmq_t* build_consumer() { tmq_conf_set(conf, "enable.auto.commit", "true"); tmq_conf_set(conf, "auto.offset.reset", "earliest"); tmq_conf_set(conf, "msg.consume.excluded", "1"); + if (g_conf.rawData) { + tmq_conf_set(conf, "msg.consume.rawdata", "1"); + } // tmq_conf_set(conf, "session.timeout.ms", "1000000"); // tmq_conf_set(conf, "max.poll.interval.ms", "20000"); @@ -1238,6 +1260,8 @@ int main(int argc, char* argv[]) { g_conf.meta = 1; } else if (strcmp(argv[i], "-bt") == 0) { g_conf.btMeta = true; + } else if (strcmp(argv[i], "-raw") == 0) { + g_conf.rawData = true; } } From b5edb79d480ac7c1e5721ebb7d87670f7528b26e Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 24 Jan 2025 16:55:53 +0800 Subject: [PATCH 09/67] fix:[TS-5776]add raw type from consumer --- contrib/CMakeLists.txt | 1 - include/libs/qcom/query.h | 5 +---- source/client/src/clientMain.c | 2 +- source/client/src/clientRawBlockWrite.c | 2 +- source/client/src/clientTmq.c | 6 +----- source/common/src/msg/tmsg.c | 3 --- source/dnode/vnode/src/tq/tqScan.c | 2 +- tests/system-test/7-tmq/tmq_taosx.py | 4 ++-- utils/test/c/tmq_taosx_ci.c | 2 +- 9 files changed, 8 insertions(+), 19 deletions(-) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 6afcdd22f2..2304ad54aa 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -74,7 +74,6 @@ endif() # jemalloc if(${JEMALLOC_ENABLED}) cat("${TD_SUPPORT_DIR}/jemalloc_CMakeLists.txt.in" ${CONTRIB_TMP_FILE}) - MESSAGE("JEMALLOC_ENABLED is on") endif() # msvc regex diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 02cb96e4c7..5b28eadc4f 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -222,10 +222,7 @@ typedef struct STableDataCxt { STSchema* pSchema; SBoundColInfo boundColsInfo; SArray* pValues; - union { - SSubmitTbData* pData; - void* raw; - }; + SSubmitTbData* pData; SRowKey lastKey; bool ordered; bool duplicateTs; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 9f0706bdaf..7aabe573af 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -253,7 +253,7 @@ void taos_cleanup(void) { taosCloseRef(id); nodesDestroyAllocatorSet(); - cleanupAppInfo(); + // cleanupAppInfo(); rpcCleanup(); tscDebug("rpc cleanup"); diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index f7515cc359..68a99d2697 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -1020,7 +1020,7 @@ static int32_t taosCreateStb(TAOS* taos, void* meta, uint32_t metaLen) { return TSDB_CODE_INVALID_PARA; } SVCreateStbReq req = {0}; - SDecoder coder; + SDecoder coder = {0}; SMCreateStbReq pReq = {0}; int32_t code = TSDB_CODE_SUCCESS; SRequestObj* pRequest = NULL; diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index e87ef4c00d..c038dc0dfc 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -286,7 +286,7 @@ typedef struct { } SVgroupSaveInfo; static TdThreadOnce tmqInit = PTHREAD_ONCE_INIT; // initialize only once -volatile int32_t tmqInitRes = -1; // initialize rsp code +volatile int32_t tmqInitRes = 0; // initialize rsp code static SMqMgmt tmqMgmt = {0}; tmq_conf_t* tmq_conf_new() { @@ -2364,10 +2364,6 @@ static SMqRspObj* buildRsp(SMqPollRspWrapper* pollRspWrapper){ SMqDataRsp dataRsp; SMqMetaRsp metaRsp; SMqBatchMetaRsp batchMetaRsp; - struct{ - int32_t len; - void* rawData; - }; } MEMSIZE; SMqRspObj* pRspObj = taosMemoryCalloc(1, sizeof(SMqRspObj)); diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 3f8e686559..2abfc1213c 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11416,9 +11416,6 @@ int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) { if (taosArrayPush(pRsp->blockData, &data) == NULL) { TAOS_CHECK_EXIT(terrno); } -// for (int m= 0; m < 56; m++){ -// printf("decode data[%d] = %d\n", m, *((int8_t *)data+18+m)); -// } int32_t len = bLen; if (taosArrayPush(pRsp->blockDataLen, &len) == NULL) { TAOS_CHECK_EXIT(terrno); diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 5e30f07e2b..a33d050460 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -352,7 +352,7 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int } // this submit data is metadata and previous data is data - if (rawList != NULL && *totalRows > 0 && pSubmitTbData->pCreateTbReq != NULL && taosArrayGetSize(pBlocks) > 0){ + if (rawList != NULL && *totalRows > 0 && pSubmitTbData->pCreateTbReq != NULL && taosArrayGetSize(pBlocks) > 0 && pRsp->createTableNum <= 1){ tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); terrno = TSDB_CODE_TMQ_DUPLICATE_UID; pRsp->createTableNum = 0; diff --git a/tests/system-test/7-tmq/tmq_taosx.py b/tests/system-test/7-tmq/tmq_taosx.py index 3f72dfc95f..845e7229a8 100644 --- a/tests/system-test/7-tmq/tmq_taosx.py +++ b/tests/system-test/7-tmq/tmq_taosx.py @@ -67,7 +67,7 @@ class TDTestCase: tdSql.checkData(1, 5, "sttb4") tdSql.query("select * from stt order by ts") - tdSql.checkRows(3) + tdSql.checkRows(5) tdSql.checkData(0, 1, 1) tdSql.checkData(2, 1, 21) tdSql.checkData(0, 2, 2) @@ -98,7 +98,7 @@ class TDTestCase: tdSql.checkData(1, 5, "sttb4") tdSql.query("select * from stt order by ts") - tdSql.checkRows(3) + tdSql.checkRows(5) tdSql.checkData(0, 1, 1) tdSql.checkData(2, 1, 21) tdSql.checkData(0, 2, 2) diff --git a/utils/test/c/tmq_taosx_ci.c b/utils/test/c/tmq_taosx_ci.c index 7b2a90570a..bc4a79bf12 100644 --- a/utils/test/c/tmq_taosx_ci.c +++ b/utils/test/c/tmq_taosx_ci.c @@ -427,7 +427,7 @@ int buildDatabase(TAOS* pConn, TAOS_RES* pRes) { pRes = taos_query(pConn, - "insert into stt1 values(now - 2s, 3, 2, 'stt1')"); + "insert into stt1 values(now + 322s, 3, 2, 'stt1')"); if (taos_errno(pRes) != 0) { printf("failed to create child table stt1, reason:%s\n", taos_errstr(pRes)); return -1; From 14bc7b03bc728d17374a396dfea62d16dc985251 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Wed, 5 Feb 2025 18:20:02 +0800 Subject: [PATCH 10/67] feat:add test logic --- source/client/src/clientTmq.c | 4 ++-- source/dnode/vnode/src/inc/tq.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index c038dc0dfc..461d82b348 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1720,7 +1720,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; - pTmq->rawData = conf->rawData; + pTmq->rawData = 1; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { @@ -3663,4 +3663,4 @@ TAOS* tmq_get_connect(tmq_t* tmq) { return (TAOS*)(&(tmq->pTscObj->id)); } return NULL; -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 57e238b499..39e02d6644 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -178,7 +178,7 @@ int32_t tqExtractDropCtbDataBlock(const void* data, int32_t len, int64_t ver, vo #define TQ_SUBSCRIBE_NAME "subscribe" #define TQ_OFFSET_NAME "offset-ver0" #define TQ_POLL_MAX_TIME 1000 -#define TQ_POLL_MAX_BYTES 1048576 +#define TQ_POLL_MAX_BYTES 10485760 #ifdef __cplusplus } From fc0cf9bf7a563bf112b5351b2e682cecdafb9079 Mon Sep 17 00:00:00 2001 From: yihaoDeng Date: Wed, 5 Feb 2025 18:21:29 +0800 Subject: [PATCH 11/67] feat:add test logic --- tests/system-test/7-tmq/taosx-performance.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json index 352bdbbd6d..ff554a61d9 100644 --- a/tests/system-test/7-tmq/taosx-performance.json +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -37,7 +37,7 @@ "insert_mode": "taosc", "non_stop_mode": "no", "line_protocol": "line", - "insert_rows": 10000, + "insert_rows": 30, "childtable_limit": 0, "childtable_offset": 0, "interlace_rows": 1, From 9bde3cab9266fc50bded06c9f2879b167c820ee1 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 6 Feb 2025 16:48:55 +0800 Subject: [PATCH 12/67] fix:[TS-5776]add raw type from consumer --- source/libs/nodes/src/nodesUtilFuncs.c | 1 - source/libs/planner/src/planPhysiCreater.c | 3 ++- source/libs/scheduler/src/schRemote.c | 11 +++-------- source/libs/transport/src/trans.c | 5 +++-- tests/army/whole/checkErrorCode.py | 3 ++- tests/system-test/7-tmq/taosx-performance.json | 2 +- tests/system-test/7-tmq/taosx-performance.py | 12 +++++++----- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 3d4df385f7..24e4325fbd 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1986,7 +1986,6 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_INSERT: { SDataInserterNode* pSink = (SDataInserterNode*)pNode; destroyDataSinkNode((SDataSinkNode*)pSink); - taosMemoryFreeClear(pSink->pData); break; } case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT: { diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 31d51fad9b..884da317e3 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -2839,7 +2839,8 @@ static int32_t createDataInserter(SPhysiPlanContext* pCxt, SVgDataBlocks* pBlock pInserter->numOfTables = pBlocks->numOfTables; pInserter->size = pBlocks->size; - TSWAP(pInserter->pData, pBlocks->pData); + pInserter->pData = pBlocks->pData; + pBlocks->pData = NULL; *pSink = (SDataSinkNode*)pInserter; return TSDB_CODE_SUCCESS; diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c index a031bc08de..ec9913d6ac 100644 --- a/source/libs/scheduler/src/schRemote.c +++ b/source/libs/scheduler/src/schRemote.c @@ -1110,7 +1110,7 @@ _return: } int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, int32_t msgType, void* param) { - int32_t msgSize = 0; + int32_t msgSize = 0; void *msg = NULL; int32_t code = 0; bool isCandidateAddr = false; @@ -1136,13 +1136,8 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, case TDMT_VND_SUBMIT: case TDMT_VND_COMMIT: { msgSize = pTask->msgLen; - msg = taosMemoryCalloc(1, msgSize); - if (NULL == msg) { - SCH_TASK_ELOG("calloc %d failed", msgSize); - SCH_ERR_RET(terrno); - } - - TAOS_MEMCPY(msg, pTask->msg, msgSize); + msg = pTask->msg; + pTask->msg = NULL; break; } diff --git a/source/libs/transport/src/trans.c b/source/libs/transport/src/trans.c index d7576005d7..986fe08504 100644 --- a/source/libs/transport/src/trans.c +++ b/source/libs/transport/src/trans.c @@ -155,7 +155,7 @@ void rpcCloseImpl(void* arg) { void* rpcMallocCont(int64_t contLen) { int64_t size = contLen + TRANS_MSG_OVERHEAD; - char* start = taosMemoryCalloc(1, size); + char* start = taosMemoryMalloc(size); if (start == NULL) { tError("failed to malloc msg, size:%" PRId64, size); return NULL; @@ -163,7 +163,8 @@ void* rpcMallocCont(int64_t contLen) { tTrace("malloc mem:%p size:%" PRId64, start, size); } - return start + sizeof(STransMsgHead); + memset(start, 0, TRANS_MSG_OVERHEAD); + return start + TRANS_MSG_OVERHEAD; } void rpcFreeCont(void* cont) { transFreeMsg(cont); } diff --git a/tests/army/whole/checkErrorCode.py b/tests/army/whole/checkErrorCode.py index b2aa1fce1b..1a14269f54 100644 --- a/tests/army/whole/checkErrorCode.py +++ b/tests/army/whole/checkErrorCode.py @@ -61,7 +61,8 @@ ignoreCodes = [ '0x80003107', '0x80003108', '0x80003109', '0x80003110', '0x80003111', '0x80003112', '0x80003250', '0x80004003', '0x80004004', '0x80004005', '0x80004006', '0x80004007', '0x80004008', '0x80004009', '0x80004010', '0x80004011', '0x80004012', '0x80004013', '0x80004014', '0x80004015', '0x80004016', '0x80004102', '0x80004103', '0x80004104', '0x80004105', '0x80004106', '0x80004107', '0x80004108', '0x80004109', '0x80005100', - '0x80005101', '0x80006000', '0x80006100', '0x80006101', '0x80006102', '0x80000019', '0x80002639', '0x80002666', '0x80000237'] + '0x80005101', '0x80006000', '0x80006100', '0x80006101', '0x80006102', '0x80000019', '0x80002639', '0x80002666', '0x80000237', '0x80004018', + '0x80004019'] class TDTestCase(TBase): diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json index 352bdbbd6d..dde8d18f8c 100644 --- a/tests/system-test/7-tmq/taosx-performance.json +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -53,7 +53,7 @@ "columns": [ {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, { "type": "BOOL", "name": "phaseewe" }, - { "type": "BINARY", "name": "locatin", "len":16374 }, + { "type": "BINARY", "name": "str", "len":1024 }, { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, { "type": "DOUBLE", "name": "phase", "max": 1000, "min": 0 } ], diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 1c70b9bb6b..f1a7045b49 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -28,7 +28,7 @@ if __name__ == "__main__": if not os.path.isdir("taosx-perf"): os.system("mkdir taosx-perf") - os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") + # os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") os.chdir("taosx-perf") print(os.getcwd()) @@ -43,6 +43,7 @@ if __name__ == "__main__": tdDnodes2.deploy(1,updatecfgDict2) tdDnodes2.start(1) + os.system("taos -c ./dnode1/sim/dnode1/cfg -s \"drop topic if exists test\"") os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") if insertData : @@ -51,12 +52,13 @@ if __name__ == "__main__": print("create test in dst") print("start to run taosx") - os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") - time.sleep(10) + os.system("flamegraph -o raw.svg -- taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") + # os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") + # time.sleep(10) - print("start to run perf") + # print("start to run perf") #os.system("perf record -a -g -F 99 -p `pidof taosx` sleep 60") - #os.system("perf script | ./FlameGraph/stackcollapse-perf.pl| ./FlameGraph/flamegraph.pl > flame.svg") + #os.system("perf script | ./stackcollapse-perf.pl| ./flamegraph.pl > flame.svg") tdLog.info("Procedures for tdengine deployed in") From c81a69604613deff9fd762f3331a079c752d45a9 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 7 Feb 2025 14:04:57 +0800 Subject: [PATCH 13/67] fix:[TS-5776]add raw type from consumer --- .../system-test/7-tmq/taosx-performance.json | 9 ++++++-- tests/system-test/7-tmq/taosx-performance.py | 22 +++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json index 67355290cf..11556a94c5 100644 --- a/tests/system-test/7-tmq/taosx-performance.json +++ b/tests/system-test/7-tmq/taosx-performance.json @@ -37,7 +37,7 @@ "insert_mode": "taosc", "non_stop_mode": "no", "line_protocol": "line", - "insert_rows": 30, + "insert_rows": 1000, "childtable_limit": 0, "childtable_offset": 0, "interlace_rows": 1, @@ -53,7 +53,12 @@ "columns": [ {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, { "type": "BOOL", "name": "phaseewe" }, - { "type": "BINARY", "name": "str", "len":1024 }, + { "type": "BINARY", "name": "str", "len":16374, + "values": ["{\"key00000\": \"value00000\", \"key00001\": \"value00001\", \"key00002\": \"value00002\", \"key00003\": \"value00003\", \"key00004\": \"value00004\", \"key00005\": \"value00005\", \"key00006\": \"value00006\", \"key00007\": \"value00007\", \"key00008\": \"value00008\", \"key00009\": \"value00009\", \"key00010\": \"value00010\", \"key00011\": \"value00011\", \"key00012\": \"value00012\", \"key00013\": \"value00013\", \"key00014\": \"value00014\", \"key00015\": \"value00015\", \"key00016\": \"value00016\", \"key00017\": \"value00017\", \"key00018\": \"value00018\", \"key00019\": \"value00019\", \"key00020\": \"value00020\", \"key00021\": \"value00021\", \"key00022\": \"value00022\", \"key00023\": \"value00023\", \"key00024\": \"value00024\", \"key00025\": \"value00025\", \"key00026\": \"value00026\", \"key00027\": \"value00027\", \"key00028\": \"value00028\", \"key00029\": \"value00029\", \"key00030\": \"value00030\", \"key00031\": \"value00031\", \"key00032\": \"value00032\", \"key00033\": \"value00033\", \"key00034\": \"value00034\", \"key00035\": \"value00035\", \"key00036\": \"value00036\", \"key00037\": \"value00037\", \"key00038\": \"value00038\", \"key00039\": \"value00039\", \"key00040\": \"value00040\", \"key00041\": \"value00041\", \"key00042\": \"value00042\", \"key00043\": \"value00043\", \"key00044\": \"value00044\", \"key00045\": \"value00045\", \"key00046\": \"value00046\", \"key00047\": \"value00047\", \"key00048\": \"value00048\", \"key00049\": \"value00049\", \"key00050\": \"value00050\", \"key00051\": \"value00051\", \"key00052\": \"value00052\", \"key00053\": \"value00053\", \"key00054\": \"value00054\", \"key00055\": \"value00055\", \"key00056\": \"value00056\", \"key00057\": \"value00057\", \"key00058\": \"value00058\", \"key00059\": \"value00059\", \"key00060\": \"value00060\", \"key00061\": \"value00061\", \"key00062\": \"value00062\", \"key00063\": \"value00063\", \"key00064\": \"value00064\", \"key00065\": \"value00065\", \"key00066\": \"value00066\", \"key00067\": \"value00067\", \"key00068\": \"value00068\", \"key00069\": \"value00069\", \"key00070\": \"value00070\", \"key00071\": \"value00071\", \"key00072\": \"value00072\", \"key00073\": \"value00073\", \"key00074\": \"value00074\", \"key00075\": \"value00075\", \"key00076\": \"value00076\", \"key00077\": \"value00077\", \"key00078\": \"value00078\", \"key00079\": \"value00079\", \"key00080\": \"value00080\", \"key00081\": \"value00081\", \"key00082\": \"value00082\", \"key00083\": \"value00083\", \"key00084\": \"value00084\", \"key00085\": \"value00085\", \"key00086\": \"value00086\", \"key00087\": \"value00087\", \"key00088\": \"value00088\", \"key00089\": \"value00089\", \"key00090\": \"value00090\", \"key00091\": \"value00091\", \"key00092\": \"value00092\", \"key00093\": \"value00093\", \"key00094\": \"value00094\", \"key00095\": \"value00095\", \"key00096\": \"value00096\", \"key00097\": \"value00097\", \"key00098\": \"value00098\", \"key00099\": \"value00099\", \"key00100\": \"value00100\", \"key00101\": \"value00101\", \"key00102\": \"value00102\", \"key00103\": \"value00103\", \"key00104\": \"value00104\", \"key00105\": \"value00105\", \"key00106\": \"value00106\", \"key00107\": \"value00107\", \"key00108\": \"value00108\", \"key00109\": \"value00109\", \"key00110\": \"value00110\", \"key00111\": \"value00111\", \"key00112\": \"value00112\", \"key00113\": \"value00113\", \"key00114\": \"value00114\", \"key00115\": \"value00115\", \"key00116\": \"value00116\", \"key00117\": \"value00117\", \"key00118\": \"value00118\", \"key00119\": \"value00119\", \"key00120\": \"value00120\", \"key00121\": \"value00121\", \"key00122\": \"value00122\", \"key00123\": \"value00123\", \"key00124\": \"value00124\", \"key00125\": \"value00125\", \"key00126\": \"value00126\", \"key00127\": \"value00127\", \"key00128\": \"value00128\", \"key00129\": \"value00129\", \"key00130\": \"value00130\", \"key00131\": \"value00131\", \"key00132\": \"value00132\", \"key00133\": \"value00133\", \"key00134\": \"value00134\", \"key00135\": \"value00135\", \"key00136\": \"value00136\", \"key00137\": \"value00137\", \"key00138\": \"value00138\", \"key00139\": \"value00139\", \"key00140\": \"value00140\", \"key00141\": \"value00141\", \"key00142\": \"value00142\", \"key00143\": \"value00143\", \"key00144\": \"value00144\", \"key00145\": \"value00145\", \"key00146\": \"value00146\", \"key00147\": \"value00147\", \"key00148\": \"value00148\", \"key00149\": \"value00149\", \"key00150\": \"value00150\", \"key00151\": \"value00151\", \"key00152\": \"value00152\", \"key00153\": \"value00153\", \"key00154\": \"value00154\", \"key00155\": \"value00155\", \"key00156\": \"value00156\", \"key00157\": \"value00157\", \"key00158\": \"value00158\", \"key00159\": \"value00159\", \"key00160\": \"value00160\", \"key00161\": \"value00161\", \"key00162\": \"value00162\", \"key00163\": \"value00163\", \"key00164\": \"value00164\", \"key00165\": \"value00165\", \"key00166\": \"value00166\", \"key00167\": \"value00167\", \"key00168\": \"value00168\", \"key00169\": \"value00169\", \"key00170\": \"value00170\", \"key00171\": \"value00171\", \"key00172\": \"value00172\", \"key00173\": \"value00173\", \"key00174\": \"value00174\", \"key00175\": \"value00175\", \"key00176\": \"value00176\", \"key00177\": \"value00177\", \"key00178\": \"value00178\", \"key00179\": \"value00179\", \"key00180\": \"value00180\", \"key00181\": \"value00181\", \"key00182\": \"value00182\", \"key00183\": \"value00183\", \"key00184\": \"value00184\", \"key00185\": \"value00185\", \"key00186\": \"value00186\", \"key00187\": \"value00187\", \"key00188\": \"value00188\", \"key00189\": \"value00189\", \"key00190\": \"value00190\", \"key00191\": \"value00191\", \"key00192\": \"value00192\", \"key00193\": \"value00193\", \"key00194\": \"value00194\", \"key00195\": \"value00195\", \"key00196\": \"value00196\", \"key00197\": \"value00197\", \"key00198\": \"value00198\", \"key00199\": \"value00199\"}", + "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino", + "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino" + ] + }, { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, { "type": "DOUBLE", "name": "phase", "max": 1000, "min": 0 } ], diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index f1a7045b49..3d2fb983da 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -20,11 +20,11 @@ tdDnodes1 = TDDnodes() tdDnodes2 = TDDnodes() if __name__ == "__main__": - args = sys.argv[1:] - - insertData = False - if len(sys.argv[1:]) == 1: - insertData = True + if len(sys.argv[1:]) != 1: + print("Usage: python3 taosx-performance.py [path of taosx]") + sys.exit(1) + + taosx = sys.argv[1] if not os.path.isdir("taosx-perf"): os.system("mkdir taosx-perf") @@ -46,13 +46,11 @@ if __name__ == "__main__": os.system("taos -c ./dnode1/sim/dnode1/cfg -s \"drop topic if exists test\"") os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") - if insertData : - os.system("taosBenchmark -f ../taosx-performance.json") + os.system("taosBenchmark -f ../taosx-performance.json") - print("create test in dst") - - print("start to run taosx") - os.system("flamegraph -o raw.svg -- taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") + cmd = f"flamegraph -o raw.svg -- {taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=1s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\"" + print("taosx start to run:%s" % cmd) + os.system(cmd) # os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") # time.sleep(10) @@ -61,4 +59,4 @@ if __name__ == "__main__": #os.system("perf script | ./stackcollapse-perf.pl| ./flamegraph.pl > flame.svg") - tdLog.info("Procedures for tdengine deployed in") + tdLog.info("taosx stop") From 170d78b69fa4757999f43cb1abb1e2065a2a12dc Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 10 Feb 2025 15:22:27 +0800 Subject: [PATCH 14/67] fix:[TS-5776]add raw type from consumer --- source/client/src/clientTmq.c | 5 - .../system-test/7-tmq/taosx-performance.json | 77 ------ tests/system-test/7-tmq/taosx-performance.py | 226 +++++++++++++++--- 3 files changed, 197 insertions(+), 111 deletions(-) delete mode 100644 tests/system-test/7-tmq/taosx-performance.json diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 8fafa4ed4a..bb55eb2e31 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1649,11 +1649,6 @@ void tmqMgmtClose(void) { break; } atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__CLOSED); - - if (taosRemoveRef(tmqMgmt.rsetId, tmq->refId) != 0) { - qWarn("taosRemoveRef tmq refId:%" PRId64 " failed, error:%s", refId, tstrerror(terrno)); - } - tmq = taosIterateRef(tmqMgmt.rsetId, refId); } taosCloseRef(tmqMgmt.rsetId); diff --git a/tests/system-test/7-tmq/taosx-performance.json b/tests/system-test/7-tmq/taosx-performance.json deleted file mode 100644 index 11556a94c5..0000000000 --- a/tests/system-test/7-tmq/taosx-performance.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "filetype": "insert", - "cfgdir": "/etc/taos", - "host": "127.0.0.1", - "port": 6030, - "user": "root", - "password": "taosdata", - "connection_pool_size": 20, - "thread_bind_vgroup": "yes", - "thread_count": 20, - "create_table_thread_count": 16, - "result_file": "./insert_res.txt", - "confirm_parameter_prompt": "no", - "num_of_records_per_req": 10, - "prepared_rand": 10000, - "chinese": "no", - "escape_character": "yes", - "continue_if_fail": "no", - "databases": [ - { - "dbinfo": { - "name": "test", - "drop": "yes", - "vgroups": 8, - "precision": "ms", - "WAL_RETENTION_PERIOD": 864000 - }, - "super_tables": [ - { - "name": "meters", - "child_table_exists": "no", - "childtable_count": 10000, - "childtable_prefix": "d", - "auto_create_table": "no", - "batch_create_tbl_num": 500, - "data_source": "rand", - "insert_mode": "taosc", - "non_stop_mode": "no", - "line_protocol": "line", - "insert_rows": 1000, - "childtable_limit": 0, - "childtable_offset": 0, - "interlace_rows": 1, - "insert_interval": 0, - "partial_col_num": 0, - "timestamp_step": 10, - "start_timestamp": "2020-10-01 00:00:00.000", - "sample_format": "csv", - "sample_file": "./sample.csv", - "use_sample_ts": "no", - "tags_file": "", - "generate_row_rule": 2, - "columns": [ - {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, - { "type": "BOOL", "name": "phaseewe" }, - { "type": "BINARY", "name": "str", "len":16374, - "values": ["{\"key00000\": \"value00000\", \"key00001\": \"value00001\", \"key00002\": \"value00002\", \"key00003\": \"value00003\", \"key00004\": \"value00004\", \"key00005\": \"value00005\", \"key00006\": \"value00006\", \"key00007\": \"value00007\", \"key00008\": \"value00008\", \"key00009\": \"value00009\", \"key00010\": \"value00010\", \"key00011\": \"value00011\", \"key00012\": \"value00012\", \"key00013\": \"value00013\", \"key00014\": \"value00014\", \"key00015\": \"value00015\", \"key00016\": \"value00016\", \"key00017\": \"value00017\", \"key00018\": \"value00018\", \"key00019\": \"value00019\", \"key00020\": \"value00020\", \"key00021\": \"value00021\", \"key00022\": \"value00022\", \"key00023\": \"value00023\", \"key00024\": \"value00024\", \"key00025\": \"value00025\", \"key00026\": \"value00026\", \"key00027\": \"value00027\", \"key00028\": \"value00028\", \"key00029\": \"value00029\", \"key00030\": \"value00030\", \"key00031\": \"value00031\", \"key00032\": \"value00032\", \"key00033\": \"value00033\", \"key00034\": \"value00034\", \"key00035\": \"value00035\", \"key00036\": \"value00036\", \"key00037\": \"value00037\", \"key00038\": \"value00038\", \"key00039\": \"value00039\", \"key00040\": \"value00040\", \"key00041\": \"value00041\", \"key00042\": \"value00042\", \"key00043\": \"value00043\", \"key00044\": \"value00044\", \"key00045\": \"value00045\", \"key00046\": \"value00046\", \"key00047\": \"value00047\", \"key00048\": \"value00048\", \"key00049\": \"value00049\", \"key00050\": \"value00050\", \"key00051\": \"value00051\", \"key00052\": \"value00052\", \"key00053\": \"value00053\", \"key00054\": \"value00054\", \"key00055\": \"value00055\", \"key00056\": \"value00056\", \"key00057\": \"value00057\", \"key00058\": \"value00058\", \"key00059\": \"value00059\", \"key00060\": \"value00060\", \"key00061\": \"value00061\", \"key00062\": \"value00062\", \"key00063\": \"value00063\", \"key00064\": \"value00064\", \"key00065\": \"value00065\", \"key00066\": \"value00066\", \"key00067\": \"value00067\", \"key00068\": \"value00068\", \"key00069\": \"value00069\", \"key00070\": \"value00070\", \"key00071\": \"value00071\", \"key00072\": \"value00072\", \"key00073\": \"value00073\", \"key00074\": \"value00074\", \"key00075\": \"value00075\", \"key00076\": \"value00076\", \"key00077\": \"value00077\", \"key00078\": \"value00078\", \"key00079\": \"value00079\", \"key00080\": \"value00080\", \"key00081\": \"value00081\", \"key00082\": \"value00082\", \"key00083\": \"value00083\", \"key00084\": \"value00084\", \"key00085\": \"value00085\", \"key00086\": \"value00086\", \"key00087\": \"value00087\", \"key00088\": \"value00088\", \"key00089\": \"value00089\", \"key00090\": \"value00090\", \"key00091\": \"value00091\", \"key00092\": \"value00092\", \"key00093\": \"value00093\", \"key00094\": \"value00094\", \"key00095\": \"value00095\", \"key00096\": \"value00096\", \"key00097\": \"value00097\", \"key00098\": \"value00098\", \"key00099\": \"value00099\", \"key00100\": \"value00100\", \"key00101\": \"value00101\", \"key00102\": \"value00102\", \"key00103\": \"value00103\", \"key00104\": \"value00104\", \"key00105\": \"value00105\", \"key00106\": \"value00106\", \"key00107\": \"value00107\", \"key00108\": \"value00108\", \"key00109\": \"value00109\", \"key00110\": \"value00110\", \"key00111\": \"value00111\", \"key00112\": \"value00112\", \"key00113\": \"value00113\", \"key00114\": \"value00114\", \"key00115\": \"value00115\", \"key00116\": \"value00116\", \"key00117\": \"value00117\", \"key00118\": \"value00118\", \"key00119\": \"value00119\", \"key00120\": \"value00120\", \"key00121\": \"value00121\", \"key00122\": \"value00122\", \"key00123\": \"value00123\", \"key00124\": \"value00124\", \"key00125\": \"value00125\", \"key00126\": \"value00126\", \"key00127\": \"value00127\", \"key00128\": \"value00128\", \"key00129\": \"value00129\", \"key00130\": \"value00130\", \"key00131\": \"value00131\", \"key00132\": \"value00132\", \"key00133\": \"value00133\", \"key00134\": \"value00134\", \"key00135\": \"value00135\", \"key00136\": \"value00136\", \"key00137\": \"value00137\", \"key00138\": \"value00138\", \"key00139\": \"value00139\", \"key00140\": \"value00140\", \"key00141\": \"value00141\", \"key00142\": \"value00142\", \"key00143\": \"value00143\", \"key00144\": \"value00144\", \"key00145\": \"value00145\", \"key00146\": \"value00146\", \"key00147\": \"value00147\", \"key00148\": \"value00148\", \"key00149\": \"value00149\", \"key00150\": \"value00150\", \"key00151\": \"value00151\", \"key00152\": \"value00152\", \"key00153\": \"value00153\", \"key00154\": \"value00154\", \"key00155\": \"value00155\", \"key00156\": \"value00156\", \"key00157\": \"value00157\", \"key00158\": \"value00158\", \"key00159\": \"value00159\", \"key00160\": \"value00160\", \"key00161\": \"value00161\", \"key00162\": \"value00162\", \"key00163\": \"value00163\", \"key00164\": \"value00164\", \"key00165\": \"value00165\", \"key00166\": \"value00166\", \"key00167\": \"value00167\", \"key00168\": \"value00168\", \"key00169\": \"value00169\", \"key00170\": \"value00170\", \"key00171\": \"value00171\", \"key00172\": \"value00172\", \"key00173\": \"value00173\", \"key00174\": \"value00174\", \"key00175\": \"value00175\", \"key00176\": \"value00176\", \"key00177\": \"value00177\", \"key00178\": \"value00178\", \"key00179\": \"value00179\", \"key00180\": \"value00180\", \"key00181\": \"value00181\", \"key00182\": \"value00182\", \"key00183\": \"value00183\", \"key00184\": \"value00184\", \"key00185\": \"value00185\", \"key00186\": \"value00186\", \"key00187\": \"value00187\", \"key00188\": \"value00188\", \"key00189\": \"value00189\", \"key00190\": \"value00190\", \"key00191\": \"value00191\", \"key00192\": \"value00192\", \"key00193\": \"value00193\", \"key00194\": \"value00194\", \"key00195\": \"value00195\", \"key00196\": \"value00196\", \"key00197\": \"value00197\", \"key00198\": \"value00198\", \"key00199\": \"value00199\"}", - "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino", - "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino" - ] - }, - { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, - { "type": "DOUBLE", "name": "phase", "max": 1000, "min": 0 } - ], - "tags": [ - {"type": "TINYINT", "name": "groupid", "max": 10, "min": 1}, - {"type": "BINARY", "name": "location", "len": 16, - "values": ["San Francisco", "Los Angles", "San Diego", - "San Jose", "Palo Alto", "Campbell", "Mountain View", - "Sunnyvale", "Santa Clara", "Cupertino"] - } - ] - } - ] - } - ] -} diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 3d2fb983da..03073c7696 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -13,50 +13,218 @@ from util.cases import * from util.dnodes import * from util.common import * from taos.tmq import * + sys.path.append("./7-tmq") from tmqCommon import * tdDnodes1 = TDDnodes() tdDnodes2 = TDDnodes() +vgroups = 1 +tables = 1 +rows_of_each_table = 1 +path = "./taosx_perf" +dnode1 = "./dnode1" +dnode2 = "./dnode2" +cfg = "sim/dnode1/cfg" +taosx = "taosx" +taosd = "taosd" +insertJson = '''{ + "filetype": "insert", + "cfgdir": "/etc/taos", + "host": "127.0.0.1", + "port": 6030, + "user": "root", + "password": "taosdata", + "connection_pool_size": 20, + "thread_bind_vgroup": "yes", + "thread_count": 20, + "create_table_thread_count": 16, + "result_file": "./insert_res.txt", + "confirm_parameter_prompt": "no", + "num_of_records_per_req": 10, + "prepared_rand": 10000, + "chinese": "no", + "escape_character": "yes", + "continue_if_fail": "no", + "databases": [ + { + "dbinfo": { + "name": "test", + "drop": "yes", + "vgroups": 8, + "precision": "ms", + "WAL_RETENTION_PERIOD": 864000 + }, + "super_tables": [ + { + "name": "meters", + "child_table_exists": "no", + "childtable_count": 10000, + "childtable_prefix": "d", + "auto_create_table": "no", + "batch_create_tbl_num": 500, + "data_source": "rand", + "insert_mode": "taosc", + "non_stop_mode": "no", + "line_protocol": "line", + "insert_rows": 1000, + "childtable_limit": 0, + "childtable_offset": 0, + "interlace_rows": 1, + "insert_interval": 0, + "partial_col_num": 0, + "timestamp_step": 10, + "start_timestamp": "2020-10-01 00:00:00.000", + "sample_format": "csv", + "sample_file": "./sample.csv", + "use_sample_ts": "no", + "tags_file": "", + "generate_row_rule": 2, + "columns": [ + {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, + { "type": "BOOL", "name": "phaseewe" }, + { "type": "BINARY", "name": "str", "len":16374, + "values": ["{kkey00000k: kvalue00000k, kkey00001k: kvalue00001k, kkey00002k: kvalue00002k, kkey00003k: kvalue00003k, kkey00004k: kvalue00004k, kkey00005k: kvalue00005k, kkey00006k: kvalue00006k, kkey00007k: kvalue00007k, kkey00008k: kvalue00008k, kkey00009k: kvalue00009k, kkey00010k: kvalue00010k, kkey00011k: kvalue00011k, kkey00012k: kvalue00012k, kkey00013k: kvalue00013k, kkey00014k: kvalue00014k, kkey00015k: kvalue00015k, kkey00016k: kvalue00016k, kkey00017k: kvalue00017k, kkey00018k: kvalue00018k, kkey00019k: kvalue00019k, kkey00020k: kvalue00020k, kkey00021k: kvalue00021k, kkey00022k: kvalue00022k, kkey00023k: kvalue00023k, kkey00024k: kvalue00024k, kkey00025k: kvalue00025k, kkey00026k: kvalue00026k, kkey00027k: kvalue00027k, kkey00028k: kvalue00028k, kkey00029k: kvalue00029k, kkey00030k: kvalue00030k, kkey00031k: kvalue00031k, kkey00032k: kvalue00032k, kkey00033k: kvalue00033k, kkey00034k: kvalue00034k, kkey00035k: kvalue00035k, kkey00036k: kvalue00036k, kkey00037k: kvalue00037k, kkey00038k: kvalue00038k, kkey00039k: kvalue00039k, kkey00040k: kvalue00040k, kkey00041k: kvalue00041k, kkey00042k: kvalue00042k, kkey00043k: kvalue00043k, kkey00044k: kvalue00044k, kkey00045k: kvalue00045k, kkey00046k: kvalue00046k, kkey00047k: kvalue00047k, kkey00048k: kvalue00048k, kkey00049k: kvalue00049k, kkey00050k: kvalue00050k, kkey00051k: kvalue00051k, kkey00052k: kvalue00052k, kkey00053k: kvalue00053k, kkey00054k: kvalue00054k, kkey00055k: kvalue00055k, kkey00056k: kvalue00056k, kkey00057k: kvalue00057k, kkey00058k: kvalue00058k, kkey00059k: kvalue00059k, kkey00060k: kvalue00060k, kkey00061k: kvalue00061k, kkey00062k: kvalue00062k, kkey00063k: kvalue00063k, kkey00064k: kvalue00064k, kkey00065k: kvalue00065k, kkey00066k: kvalue00066k, kkey00067k: kvalue00067k, kkey00068k: kvalue00068k, kkey00069k: kvalue00069k, kkey00070k: kvalue00070k, kkey00071k: kvalue00071k, kkey00072k: kvalue00072k, kkey00073k: kvalue00073k, kkey00074k: kvalue00074k, kkey00075k: kvalue00075k, kkey00076k: kvalue00076k, kkey00077k: kvalue00077k, kkey00078k: kvalue00078k, kkey00079k: kvalue00079k, kkey00080k: kvalue00080k, kkey00081k: kvalue00081k, kkey00082k: kvalue00082k, kkey00083k: kvalue00083k, kkey00084k: kvalue00084k, kkey00085k: kvalue00085k, kkey00086k: kvalue00086k, kkey00087k: kvalue00087k, kkey00088k: kvalue00088k, kkey00089k: kvalue00089k, kkey00090k: kvalue00090k, kkey00091k: kvalue00091k, kkey00092k: kvalue00092k, kkey00093k: kvalue00093k, kkey00094k: kvalue00094k, kkey00095k: kvalue00095k, kkey00096k: kvalue00096k, kkey00097k: kvalue00097k, kkey00098k: kvalue00098k, kkey00099k: kvalue00099k, kkey00100k: kvalue00100k, kkey00101k: kvalue00101k, kkey00102k: kvalue00102k, kkey00103k: kvalue00103k, kkey00104k: kvalue00104k, kkey00105k: kvalue00105k, kkey00106k: kvalue00106k, kkey00107k: kvalue00107k, kkey00108k: kvalue00108k, kkey00109k: kvalue00109k, kkey00110k: kvalue00110k, kkey00111k: kvalue00111k, kkey00112k: kvalue00112k, kkey00113k: kvalue00113k, kkey00114k: kvalue00114k, kkey00115k: kvalue00115k, kkey00116k: kvalue00116k, kkey00117k: kvalue00117k, kkey00118k: kvalue00118k, kkey00119k: kvalue00119k, kkey00120k: kvalue00120k, kkey00121k: kvalue00121k, kkey00122k: kvalue00122k, kkey00123k: kvalue00123k, kkey00124k: kvalue00124k, kkey00125k: kvalue00125k, kkey00126k: kvalue00126k, kkey00127k: kvalue00127k, kkey00128k: kvalue00128k, kkey00129k: kvalue00129k, kkey00130k: kvalue00130k, kkey00131k: kvalue00131k, kkey00132k: kvalue00132k, kkey00133k: kvalue00133k, kkey00134k: kvalue00134k, kkey00135k: kvalue00135k, kkey00136k: kvalue00136k, kkey00137k: kvalue00137k, kkey00138k: kvalue00138k, kkey00139k: kvalue00139k, kkey00140k: kvalue00140k, kkey00141k: kvalue00141k, kkey00142k: kvalue00142k, kkey00143k: kvalue00143k, kkey00144k: kvalue00144k, kkey00145k: kvalue00145k, kkey00146k: kvalue00146k, kkey00147k: kvalue00147k, kkey00148k: kvalue00148k, kkey00149k: kvalue00149k, kkey00150k: kvalue00150k, kkey00151k: kvalue00151k, kkey00152k: kvalue00152k, kkey00153k: kvalue00153k, kkey00154k: kvalue00154k, kkey00155k: kvalue00155k, kkey00156k: kvalue00156k, kkey00157k: kvalue00157k, kkey00158k: kvalue00158k, kkey00159k: kvalue00159k, kkey00160k: kvalue00160k, kkey00161k: kvalue00161k, kkey00162k: kvalue00162k, kkey00163k: kvalue00163k, kkey00164k: kvalue00164k, kkey00165k: kvalue00165k, kkey00166k: kvalue00166k, kkey00167k: kvalue00167k, kkey00168k: kvalue00168k, kkey00169k: kvalue00169k, kkey00170k: kvalue00170k, kkey00171k: kvalue00171k, kkey00172k: kvalue00172k, kkey00173k: kvalue00173k, kkey00174k: kvalue00174k, kkey00175k: kvalue00175k, kkey00176k: kvalue00176k, kkey00177k: kvalue00177k, kkey00178k: kvalue00178k, kkey00179k: kvalue00179k, kkey00180k: kvalue00180k, kkey00181k: kvalue00181k, kkey00182k: kvalue00182k, kkey00183k: kvalue00183k, kkey00184k: kvalue00184k, kkey00185k: kvalue00185k, kkey00186k: kvalue00186k, kkey00187k: kvalue00187k, kkey00188k: kvalue00188k, kkey00189k: kvalue00189k, kkey00190k: kvalue00190k, kkey00191k: kvalue00191k, kkey00192k: kvalue00192k, kkey00193k: kvalue00193k, kkey00194k: kvalue00194k, kkey00195k: kvalue00195k, kkey00196k: kvalue00196k, kkey00197k: kvalue00197k, kkey00198k: kvalue00198k, kkey00199k: kvalue00199k}", + "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino", + "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino" + ] + }, + { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, + { "type": "DOUBLE", "name": "phase", "max": 1000, "min": 0 } + ], + "tags": [ + {"type": "TINYINT", "name": "groupid", "max": 10, "min": 1}, + {"type": "BINARY", "name": "location", "len": 16, + "values": ["San Francisco", "Los Angles", "San Diego", + "San Jose", "Palo Alto", "Campbell", "Mountain View", + "Sunnyvale", "Santa Clara", "Cupertino"] + } + ] + } + ] + } + ] +}''' -if __name__ == "__main__": - if len(sys.argv[1:]) != 1: - print("Usage: python3 taosx-performance.py [path of taosx]") - sys.exit(1) - - taosx = sys.argv[1] - - if not os.path.isdir("taosx-perf"): - os.system("mkdir taosx-perf") - # os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") - os.chdir("taosx-perf") - print(os.getcwd()) - - tdDnodes1.stopAll() - updatecfgDict1 = {'debugFlag': 131, 'serverPort': 6030} - tdDnodes1.init("./dnode1") - tdDnodes1.deploy(1,updatecfgDict1) - tdDnodes1.start(1) +def initEnv(): updatecfgDict2 = {'debugFlag': 131, 'serverPort': 7030} - tdDnodes2.init("./dnode2") - tdDnodes2.deploy(1,updatecfgDict2) + tdDnodes2.init(dnode2) + tdDnodes2.deploy(1, updatecfgDict2) tdDnodes2.start(1) - os.system("taos -c ./dnode1/sim/dnode1/cfg -s \"drop topic if exists test\"") - os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"drop database if exists test\"") - os.system("taos -c ./dnode2/sim/dnode1/cfg -s \"create database test vgroups 8\"") - os.system("taosBenchmark -f ../taosx-performance.json") + updatecfgDict1 = {'debugFlag': 131, 'serverPort': 6030} + tdDnodes1.init(dnode1) + tdDnodes1.deploy(1, updatecfgDict1) + tdDnodes1.start(1) - cmd = f"flamegraph -o raw.svg -- {taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=1s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\"" - print("taosx start to run:%s" % cmd) + with open('taosx-performance.json', 'w') as file: + file.write(insertJson) + + changeVgroups = f"sed -i '/vgroups/c\ \"vgroups\": {vgroups},' taosx-performance.json" + os.system(changeVgroups) + + changeTables = f"sed -i '/childtable_count/c\ \"childtable_count\": {tables},' taosx-performance.json" + os.system(changeTables) + + changeRows = f"sed -i '/insert_rows/c\ \"insert_rows\": {rows_of_each_table},' taosx-performance.json" + os.system(changeRows) + os.system("taosBenchmark -f taosx-performance.json") + +def stopTaosd(str): + psCmd = f"ps -ef | grep -w taosd | grep -v grep | grep {str}" + " | awk '{print $2}' | xargs" + processID = subprocess.check_output(psCmd, shell=True).decode("utf-8").strip() + print(f"kill taosd pid={processID}") + if processID: + cmd = f"kill -9 {processID}" + os.system(cmd) + +def cleanDb(): + dropTopic = f"taos -c {dnode1}/{cfg} -s \"drop topic if exists test\"" + print("dropTopic:%s" % dropTopic) + os.system(dropTopic) + + dropDb = f"taos -c {dnode2}/{cfg} -s \"drop database if exists test\"" + print("dropDb:%s" % dropDb) + os.system(dropDb) + + createDb = f"taos -c {dnode2}/{cfg} -s \"create database test vgroups {vgroups}\"" + print("createDb:%s" % createDb) + os.system(createDb) + + +def restartTaosd(): + cmd1 = f"{taosd} -c {dnode1}/{cfg} > /dev/null 2>&1 &" + cmd2 = f"{taosd} -c {dnode2}/{cfg} > /dev/null 2>&1 &" + print("start taosd1 :%s" % cmd1) + print("start taosd2 :%s" % cmd2) + os.system(cmd1) + os.system(cmd2) + + +def runTaosx(): + cmd = f"{taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=2s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\"" + print("run taosx:%s" % cmd) os.system(cmd) + + +def parseArgs(): + if len(sys.argv[1:]) < 6: + print( + "Usage: python3 taosx-performance.py path_to_taosx path_to_taosd init vgroups tables rows_of_each_table [path]") + sys.exit(1) + + global taosx + global taosd + global init + global vgroups + global tables + global rows_of_each_table + global path + global dnode1 + global dnode2 + taosx = sys.argv[1] + taosd = sys.argv[2] + init = sys.argv[3] + vgroups = sys.argv[4] + tables = sys.argv[5] + rows_of_each_table = sys.argv[6] + if len(sys.argv[1:]) == 7: + path = sys.argv[7] + + if not os.path.isdir(path): + mkCmd = f"mkdir {path}" + os.system(mkCmd) + # os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") + + +''' +python3 taosx-performance.py path_to_taosx path_to_taosd init vgroups tables rows_of_each_table [path] +''' +if __name__ == "__main__": + parseArgs() + + os.chdir(path) + print("current dir:" + os.getcwd()) + + stopTaosd("dnode2") + stopTaosd("dnode1") + time.sleep(2) + + if init == "true": + initEnv() + else: + restartTaosd() + + cleanDb() + runTaosx() + # os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") # time.sleep(10) # print("start to run perf") - #os.system("perf record -a -g -F 99 -p `pidof taosx` sleep 60") + # os.system("perf record -a -g -F 99 -p `pidof taosx` sleep 60") - #os.system("perf script | ./stackcollapse-perf.pl| ./flamegraph.pl > flame.svg") + # os.system("perf script | ./stackcollapse-perf.pl| ./flamegraph.pl > flame.svg") - tdLog.info("taosx stop") + tdLog.info("run performance end") From fbe65197d615ac07c3e65c7ef841072f882c473d Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Mon, 10 Feb 2025 15:58:25 +0800 Subject: [PATCH 15/67] Feat(sync):Add restore progress to the "show vnodes" command, and add the applied index to the "show vgroups" command. --- include/common/tmsg.h | 14 +++++---- include/libs/sync/sync.h | 1 + include/util/tdef.h | 7 +++-- source/common/src/msg/tmsg.c | 6 +++- source/common/src/systable.c | 6 +++- source/dnode/mnode/impl/inc/mndDef.h | 4 ++- source/dnode/mnode/impl/src/mndDnode.c | 2 ++ source/dnode/mnode/impl/src/mndVgroup.c | 39 +++++++++++++++++++++---- source/dnode/vnode/src/vnd/vnodeQuery.c | 2 ++ source/libs/sync/src/syncMain.c | 8 +++++ 10 files changed, 71 insertions(+), 18 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 82eaa2359e..cedaf223c5 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1355,10 +1355,10 @@ typedef struct { int8_t encryptAlgorithm; char dnodeListStr[TSDB_DNODE_LIST_LEN]; // 1. add auto-compact parameters - int32_t compactInterval; // minutes - int32_t compactStartTime; // minutes - int32_t compactEndTime; // minutes - int8_t compactTimeOffset; // hour + int32_t compactInterval; // minutes + int32_t compactStartTime; // minutes + int32_t compactEndTime; // minutes + int8_t compactTimeOffset; // hour } SCreateDbReq; int32_t tSerializeSCreateDbReq(void* buf, int32_t bufLen, SCreateDbReq* pReq); @@ -1777,6 +1777,8 @@ typedef struct { int64_t numOfBatchInsertSuccessReqs; int32_t numOfCachedTables; int32_t learnerProgress; // use one reservered + int64_t syncAppliedIndex; + int64_t syncCommitIndex; } SVnodeLoad; typedef struct { @@ -3937,8 +3939,8 @@ typedef struct { int8_t igExists; int8_t intervalUnit; int8_t slidingUnit; - int8_t timezone; // int8_t is not enough, timezone is unit of second - int32_t dstVgId; // for stream + int8_t timezone; // int8_t is not enough, timezone is unit of second + int32_t dstVgId; // for stream int64_t interval; int64_t offset; int64_t sliding; diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index f1f907ce37..a02634298c 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -293,6 +293,7 @@ int32_t syncBecomeAssignedLeader(SSyncNode* ths, SRpcMsg* pRpcMsg); int32_t syncUpdateArbTerm(int64_t rid, SyncTerm arbTerm); SSyncState syncGetState(int64_t rid); +void syncGetCommitIndex(int64_t rid, int64_t* syncCommitIndex); int32_t syncGetArbToken(int64_t rid, char* outToken); int32_t syncGetAssignedLogSynced(int64_t rid); void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet); diff --git a/include/util/tdef.h b/include/util/tdef.h index f08697b0d4..532592e7ff 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -328,8 +328,8 @@ typedef enum ELogicConditionType { #define TSDB_ARB_GROUP_MEMBER_NUM 2 #define TSDB_ARB_TOKEN_SIZE 32 -#define TSDB_TRANS_STAGE_LEN 12 -#define TSDB_TRANS_TYPE_LEN 16 +#define TSDB_TRANS_STAGE_LEN 12 +#define TSDB_TRANS_TYPE_LEN 16 #define TSDB_TRANS_ERROR_LEN 512 #define TSDB_TRANS_OBJTYPE_LEN 40 #define TSDB_TRANS_RESULT_LEN 100 @@ -363,6 +363,7 @@ typedef enum ELogicConditionType { #define TSDB_MAX_REPLICA 5 #define TSDB_MAX_LEARNER_REPLICA 10 +#define TSDB_SYNC_RESOTRE_lEN 8 #define TSDB_SYNC_LOG_BUFFER_SIZE 4096 #define TSDB_SYNC_LOG_BUFFER_RETENTION 256 #define TSDB_SYNC_LOG_BUFFER_THRESHOLD (1024 * 1024 * 5) @@ -678,7 +679,7 @@ typedef enum { TSDB_VERSION_END, } EVersionType; -#define MIN_RESERVE_MEM_SIZE 1024 // MB +#define MIN_RESERVE_MEM_SIZE 1024 // MB #ifdef __cplusplus } diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 7a51669d46..ba8d136a66 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -14,8 +14,8 @@ */ #define _DEFAULT_SOURCE -#include "tmsg.h" #include "tglobal.h" +#include "tmsg.h" #undef TD_MSG_NUMBER_ #undef TD_MSG_DICT_ @@ -1432,6 +1432,8 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tEncodeI32(&encoder, pload->learnerProgress)); TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->roleTimeMs)); TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->startTimeMs)); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncAppliedIndex)); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncCommitIndex)); } // mnode loads @@ -1542,6 +1544,8 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tDecodeI32(&decoder, &vload.learnerProgress)); TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.roleTimeMs)); TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.startTimeMs)); + TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.syncAppliedIndex)); + TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.syncCommitIndex)); if (taosArrayPush(pReq->pVloads, &vload) == NULL) { TAOS_CHECK_EXIT(terrno); } diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 1f018606a8..8223908663 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -290,12 +290,16 @@ static const SSysDbTableSchema vgroupsSchema[] = { {.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "tables", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v1_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, + {.name = "v1_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v1_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v2_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, + {.name = "v2_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v2_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v3_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, + {.name = "v3_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v3_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v4_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, + {.name = "v4_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v4_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "cacheload", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "cacheelements", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, @@ -366,7 +370,7 @@ static const SSysDbTableSchema vnodesSchema[] = { {.name = "status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "role_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, - {.name = "restored", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = true}, + {.name = "restored", .bytes = TSDB_SYNC_RESOTRE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, }; static const SSysDbTableSchema userUserPrivilegesSchema[] = { diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 9bed10ce99..78809a2d58 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -136,7 +136,7 @@ typedef enum { typedef enum { TRN_KILL_MODE_SKIP = 0, TRN_KILL_MODE_INTERUPT = 1, - //TRN_KILL_MODE_ROLLBACK = 2, + // TRN_KILL_MODE_ROLLBACK = 2, } ETrnKillMode; typedef enum { @@ -476,6 +476,8 @@ typedef struct { int32_t dnodeId; ESyncState syncState; int64_t syncTerm; + int64_t syncAppliedIndex; + int64_t syncCommitIndex; bool syncRestore; bool syncCanRead; int64_t roleTimeMs; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index ca119191eb..57b82fbd17 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -540,6 +540,8 @@ static bool mndUpdateVnodeState(int32_t vgId, SVnodeGid *pGid, SVnodeLoad *pVloa bool roleChanged = pGid->syncState != pVload->syncState || (pVload->syncTerm != -1 && pGid->syncTerm != pVload->syncTerm) || pGid->roleTimeMs != pVload->roleTimeMs; + pGid->syncAppliedIndex = pVload->syncAppliedIndex; + pGid->syncCommitIndex = pVload->syncCommitIndex; if (roleChanged || pGid->syncRestore != pVload->syncRestore || pGid->syncCanRead != pVload->syncCanRead || pGid->startTimeMs != pVload->startTimeMs) { mInfo( diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index e20afb7201..209961a3b8 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -244,6 +244,8 @@ static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOld, SVgObj *pNew) { pNewGid->syncState = pOldGid->syncState; pNewGid->syncRestore = pOldGid->syncRestore; pNewGid->syncCanRead = pOldGid->syncCanRead; + pNewGid->syncAppliedIndex = pOldGid->syncAppliedIndex; + pNewGid->syncCommitIndex = pOldGid->syncCommitIndex; } } } @@ -1065,6 +1067,13 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p return code; } + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->vnodeGid[i].syncAppliedIndex, false); + if (code != 0) { + mError("vgId:%d, failed to set role, since %s", pVgroup->vgId, tstrerror(code)); + return code; + } + bool exist = false; bool online = false; SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId); @@ -1126,6 +1135,8 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p colDataSetNULL(pColInfo, numOfRows); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetNULL(pColInfo, numOfRows); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetNULL(pColInfo, numOfRows); } } @@ -1232,6 +1243,14 @@ int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) { return vnodeMemory; } +double calculatePercentage(double part, double total) { + if (total == 0) { + return 0.0; + } + double percentage = (part / total) * 100; + return round(percentage * 100) / 100; +} + static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { SMnode *pMnode = pReq->info.node; SSdb *pSdb = pMnode->pSdb; @@ -1313,12 +1332,20 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB } pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->syncRestore, false); + char restoreBuf[20] = {0}; + if (pGid->syncRestore) { + sprintf(restoreBuf, "true"); + } else { + double percentage = calculatePercentage(pGid->syncAppliedIndex, pGid->syncCommitIndex); + sprintf(restoreBuf, "%.2f", percentage); + } + + STR_TO_VARSTR(buf, restoreBuf); + code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false); if (code != 0) { mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code)); return code; } - numOfRows++; sdbRelease(pSdb, pDnode); } @@ -2771,7 +2798,7 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb pVgroup->vnodeGid[0].dnodeId); // add second - if (pNewVgroup->replica == 1){ + if (pNewVgroup->replica == 1) { TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray)); } @@ -2792,8 +2819,8 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup)); // add third - if (pNewVgroup->replica == 2){ - TAOS_CHECK_RETURN (mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray)); + if (pNewVgroup->replica == 2) { + TAOS_CHECK_RETURN(mndAddVnodeToVgroup(pMnode, pTrans, pNewVgroup, pArray)); } pNewVgroup->vnodeGid[0].nodeRole = TAOS_SYNC_ROLE_VOTER; @@ -2823,7 +2850,7 @@ int32_t mndBuildAlterVgroupAction(SMnode *pMnode, STrans *pTrans, SDbObj *pOldDb TAOS_CHECK_RETURN(mndRemoveVnodeFromVgroup(pMnode, pTrans, pNewVgroup, pArray, &del2)); TAOS_CHECK_RETURN(mndAddDropVnodeAction(pMnode, pTrans, pNewDb, pNewVgroup, &del2, true)); TAOS_CHECK_RETURN( - mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId)); + mndAddAlterVnodeReplicaAction(pMnode, pTrans, pNewDb, pNewVgroup, pNewVgroup->vnodeGid[0].dnodeId)); TAOS_CHECK_RETURN(mndAddAlterVnodeConfirmAction(pMnode, pTrans, pNewDb, pNewVgroup)); } else if (pNewDb->cfg.replications == 2) { mInfo("db:%s, vgId:%d, will add 1 vnode, vn:0 dnode:%d", pVgroup->dbName, pVgroup->vgId, diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 2b07de916c..dda2e467c1 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -499,6 +499,8 @@ _exit: int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) { SSyncState state = syncGetState(pVnode->sync); + pLoad->syncAppliedIndex = pVnode->state.applied; + syncGetCommitIndex(pVnode->sync, &pLoad->syncCommitIndex); pLoad->vgId = TD_VID(pVnode); pLoad->syncState = state.state; diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index 0933fd48c7..78ae197079 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -679,6 +679,14 @@ SSyncState syncGetState(int64_t rid) { return state; } +void syncGetCommitIndex(int64_t rid, int64_t* syncCommitIndex) { + SSyncNode* pSyncNode = syncNodeAcquire(rid); + if (pSyncNode != NULL) { + *syncCommitIndex = pSyncNode->commitIndex; + syncNodeRelease(pSyncNode); + } +} + int32_t syncGetArbToken(int64_t rid, char* outToken) { int32_t code = 0; SSyncNode* pSyncNode = syncNodeAcquire(rid); From 7025be999b72c0a85f5679a0a18d3e26d81c7a7b Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Mon, 10 Feb 2025 18:32:34 +0800 Subject: [PATCH 16/67] bind async --- include/client/taos.h | 1 + source/client/inc/clientStmt2.h | 7 +++- source/client/src/clientMain.c | 20 ++++++++-- source/client/src/clientStmt2.c | 68 ++++++++++++++++++++++++++++----- 4 files changed, 80 insertions(+), 16 deletions(-) diff --git a/include/client/taos.h b/include/client/taos.h index 17f97d3d3d..59ada33d91 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -247,6 +247,7 @@ typedef struct TAOS_STMT2_BINDV { DLL_EXPORT TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option); DLL_EXPORT int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length); DLL_EXPORT int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx); +DLL_EXPORT int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, void *param); DLL_EXPORT int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows); DLL_EXPORT int taos_stmt2_close(TAOS_STMT2 *stmt); DLL_EXPORT int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert); diff --git a/source/client/inc/clientStmt2.h b/source/client/inc/clientStmt2.h index 05a4c849f8..e55d9a048f 100644 --- a/source/client/inc/clientStmt2.h +++ b/source/client/inc/clientStmt2.h @@ -153,8 +153,10 @@ typedef struct { char *db; int64_t reqid; int32_t errCode; - tsem_t asyncQuerySem; - bool semWaited; + tsem_t asyncExecSem; + bool execSemWaited; + tsem_t asyncBindSem; + bool bindSemWaited; SStmtStatInfo stat; } STscStmt2; /* @@ -226,6 +228,7 @@ int stmtGetParamNum2(TAOS_STMT2 *stmt, int *nums); int stmtIsInsert2(TAOS_STMT2 *stmt, int *insert); TAOS_RES *stmtUseResult2(TAOS_STMT2 *stmt); const char *stmtErrstr2(TAOS_STMT2 *stmt); +int stmt2AsyncBind(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, void *param); #ifdef __cplusplus } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 190a724151..2a27894fc3 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -2166,11 +2166,18 @@ int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col } STscStmt2 *pStmt = (STscStmt2 *)stmt; - if (pStmt->options.asyncExecFn && !pStmt->semWaited) { - if (tsem_wait(&pStmt->asyncQuerySem) != 0) { - tscError("wait async query sem failed"); + if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) { + if (tsem_wait(&pStmt->asyncExecSem) != 0) { + tscError("wait asyncExecSem failed"); } - pStmt->semWaited = true; + pStmt->execSemWaited = true; + } + + if (!pStmt->bindSemWaited) { + if (tsem_wait(&pStmt->asyncBindSem) != 0) { + tscError("wait asyncBindSem failed"); + } + pStmt->bindSemWaited = true; } SSHashObj *hashTbnames = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR)); @@ -2243,6 +2250,11 @@ out: return code; } +int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, + void *param) { + return stmt2AsyncBind(stmt, bindv,col_idx, fp, param); +} + int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) { if (stmt == NULL) { tscError("NULL parameter for %s", __FUNCTION__); diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 8e517eb5f2..f4e0fefb00 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -835,13 +835,13 @@ TAOS_STMT2* stmtInit2(STscObj* taos, TAOS_STMT2_OPTION* pOptions) { pStmt->sql.siInfo.tableColsReady = true; if (pStmt->options.asyncExecFn) { - if (tsem_init(&pStmt->asyncQuerySem, 0, 1) != 0) { + if (tsem_init(&pStmt->asyncExecSem, 0, 1) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); (void)stmtClose(pStmt); return NULL; } } - pStmt->semWaited = false; + pStmt->execSemWaited = false; STMT_LOG_SEQ(STMT_INIT); @@ -1656,8 +1656,8 @@ static void asyncQueryCb(void* userdata, TAOS_RES* res, int code) { (void)stmtCleanExecInfo(pStmt, (code ? false : true), false); ++pStmt->sql.runTimes; - if (tsem_post(&pStmt->asyncQuerySem) != 0) { - tscError("failed to post asyncQuerySem"); + if (tsem_post(&pStmt->asyncExecSem) != 0) { + tscError("failed to post asyncExecSem"); } } @@ -1746,7 +1746,7 @@ int stmtExec2(TAOS_STMT2* stmt, int* affected_rows) { pRequest->body.queryFp = asyncQueryCb; ((SSyncQueryParam*)(pRequest)->body.interParam)->userParam = pStmt; - pStmt->semWaited = false; + pStmt->execSemWaited = false; launchAsyncQuery(pRequest, pStmt->sql.pQuery, NULL, pWrapper); } @@ -1775,9 +1775,9 @@ int stmtClose2(TAOS_STMT2* stmt) { (void)taosThreadCondDestroy(&pStmt->queue.waitCond); (void)taosThreadMutexDestroy(&pStmt->queue.mutex); - if (pStmt->options.asyncExecFn && !pStmt->semWaited) { - if (tsem_wait(&pStmt->asyncQuerySem) != 0) { - tscError("failed to wait asyncQuerySem"); + if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) { + if (tsem_wait(&pStmt->asyncExecSem) != 0) { + tscError("failed to wait asyncExecSem"); } } @@ -1795,8 +1795,8 @@ int stmtClose2(TAOS_STMT2* stmt) { STMT_ERR_RET(stmtCleanSQLInfo(pStmt)); if (pStmt->options.asyncExecFn) { - if (tsem_destroy(&pStmt->asyncQuerySem) != 0) { - tscError("failed to destroy asyncQuerySem"); + if (tsem_destroy(&pStmt->asyncExecSem) != 0) { + tscError("failed to destroy asyncExecSem"); } } taosMemoryFree(stmt); @@ -1925,3 +1925,51 @@ TAOS_RES* stmtUseResult2(TAOS_STMT2* stmt) { return pStmt->exec.pRequest; } +typedef struct { + TAOS_STMT2* stmt; + TAOS_STMT2_BINDV* bindv; + int32_t col_idx; + __taos_async_fn_t fp; + void* param; +} ThreadArgs; + +static void* stmtAsyncBindThreadFunc(void* args) { + ThreadArgs* targs = (ThreadArgs*)args; + + int code = taos_stmt2_bind_param(targs->stmt, targs->bindv, targs->col_idx); + targs->fp(targs->param, NULL, code); + taosMemoryFree(args); + + return NULL; +} + +int stmt2AsyncBind(TAOS_STMT2* stmt, TAOS_STMT2_BINDV* bindv, int32_t col_idx, __taos_async_fn_t fp, void* param) { + STscStmt2* pStmt = (STscStmt2*)stmt; + + TdThreadAttr thAttr; + if (taosThreadAttrInit(&thAttr) != 0) { + return TSDB_CODE_TSC_INTERNAL_ERROR; + } + if (taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_DETACHED) != 0) { + return TSDB_CODE_TSC_INTERNAL_ERROR; + } + + ThreadArgs* args = (ThreadArgs*)taosMemoryMalloc(sizeof(ThreadArgs)); + args->stmt = stmt; + args->bindv = bindv; + args->col_idx = col_idx; + args->fp = fp; + args->param = param; + + if (taosThreadCreate(&pStmt->bindThread, &thAttr, stmtAsyncBindThreadFunc, args) != 0) { + (void)taosThreadAttrDestroy(&thAttr); + terrno = TAOS_SYSTEM_ERROR(errno); + STMT_ERR_RET(terrno); + } + + // pStmt->bindThreadInUse = true; + + (void)taosThreadAttrDestroy(&thAttr); + + return TSDB_CODE_SUCCESS; +} \ No newline at end of file From b62d8d37b173cc382c05bbb9056d4d5abf4a638e Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Tue, 11 Feb 2025 15:51:05 +0800 Subject: [PATCH 17/67] Feat(sync):Use remaining time to replace progress. --- include/util/tdef.h | 2 +- source/common/src/systable.c | 3 +- source/dnode/mnode/impl/inc/mndDef.h | 2 ++ source/dnode/mnode/impl/src/mndDnode.c | 24 ++++++++++++++ source/dnode/mnode/impl/src/mndVgroup.c | 42 ++++++++++++++++--------- 5 files changed, 56 insertions(+), 17 deletions(-) diff --git a/include/util/tdef.h b/include/util/tdef.h index 532592e7ff..862c18da28 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -363,7 +363,7 @@ typedef enum ELogicConditionType { #define TSDB_MAX_REPLICA 5 #define TSDB_MAX_LEARNER_REPLICA 10 -#define TSDB_SYNC_RESOTRE_lEN 8 +#define TSDB_SYNC_RESOTRE_lEN 20 #define TSDB_SYNC_LOG_BUFFER_SIZE 4096 #define TSDB_SYNC_LOG_BUFFER_RETENTION 256 #define TSDB_SYNC_LOG_BUFFER_THRESHOLD (1024 * 1024 * 5) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 8223908663..dbab7d892e 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -370,7 +370,8 @@ static const SSysDbTableSchema vnodesSchema[] = { {.name = "status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "role_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, - {.name = "restored", .bytes = TSDB_SYNC_RESOTRE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "restored", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = true}, + {.name = "restored_finish", .bytes = TSDB_SYNC_RESOTRE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, }; static const SSysDbTableSchema userUserPrivilegesSchema[] = { diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 78809a2d58..601dd28bb2 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -477,6 +477,8 @@ typedef struct { ESyncState syncState; int64_t syncTerm; int64_t syncAppliedIndex; + int64_t lastSyncAppliedIndexUpdateTime; + double appliedRate; int64_t syncCommitIndex; bool syncRestore; bool syncCanRead; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 57b82fbd17..d666b6cd9d 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -535,11 +535,35 @@ static int32_t mndCheckClusterCfgPara(SMnode *pMnode, SDnodeObj *pDnode, const S return DND_REASON_ONLINE; } +double calcAppliedRate(int64_t currentCount, int64_t lastCount, int64_t currentTimeMs, int64_t lastTimeMs) { + if ((currentTimeMs <= lastTimeMs) || (currentCount <= lastCount)) { + return 0.0; + } + + int64_t deltaCount = currentCount - lastCount; + int64_t deltaMs = currentTimeMs - lastTimeMs; + double rate = (double)deltaCount / (double)deltaMs; + return rate; +} + static bool mndUpdateVnodeState(int32_t vgId, SVnodeGid *pGid, SVnodeLoad *pVload) { bool stateChanged = false; bool roleChanged = pGid->syncState != pVload->syncState || (pVload->syncTerm != -1 && pGid->syncTerm != pVload->syncTerm) || pGid->roleTimeMs != pVload->roleTimeMs; + + if (!pVload->syncRestore) { + if (pGid->lastSyncAppliedIndexUpdateTime == 0) { + pGid->lastSyncAppliedIndexUpdateTime = taosGetTimestampMs(); + } else if (pGid->syncAppliedIndex != pVload->syncAppliedIndex) { + int64_t currentTimeMs = taosGetTimestampMs(); + pGid->appliedRate = calcAppliedRate(pVload->syncAppliedIndex, pGid->syncAppliedIndex, currentTimeMs, + pGid->lastSyncAppliedIndexUpdateTime); + + pGid->lastSyncAppliedIndexUpdateTime = currentTimeMs; + } + } + pGid->syncAppliedIndex = pVload->syncAppliedIndex; pGid->syncCommitIndex = pVload->syncCommitIndex; if (roleChanged || pGid->syncRestore != pVload->syncRestore || pGid->syncCanRead != pVload->syncCanRead || diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index 209961a3b8..f4f3866dc7 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -1243,12 +1243,19 @@ int64_t mndGetVnodesMemory(SMnode *pMnode, int32_t dnodeId) { return vnodeMemory; } -double calculatePercentage(double part, double total) { - if (total == 0) { - return 0.0; +void calculateRstoreFinishTime(double rate, int64_t applyCount, char *restoreStr, size_t restoreStrSize) { + if (rate == 0) { + snprintf(restoreStr, restoreStrSize, "0:0:0"); + return; } - double percentage = (part / total) * 100; - return round(percentage * 100) / 100; + + int64_t costTime = applyCount / rate; + int64_t totalSeconds = costTime / 1000; + int64_t hours = totalSeconds / 3600; + totalSeconds %= 3600; + int64_t minutes = totalSeconds / 60; + int64_t seconds = totalSeconds % 60; + snprintf(restoreStr, restoreStrSize, "%" PRId64 ":%" PRId64 ":%" PRId64, hours, minutes, seconds); } static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) { @@ -1332,20 +1339,25 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB } pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - char restoreBuf[20] = {0}; - if (pGid->syncRestore) { - sprintf(restoreBuf, "true"); - } else { - double percentage = calculatePercentage(pGid->syncAppliedIndex, pGid->syncCommitIndex); - sprintf(restoreBuf, "%.2f", percentage); - } - - STR_TO_VARSTR(buf, restoreBuf); - code = colDataSetVal(pColInfo, numOfRows, (const char *)buf, false); + code = colDataSetVal(pColInfo, numOfRows, (const char *)&pGid->syncRestore, false); if (code != 0) { mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code)); return code; } + + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + char restoreStr[20] = {0}; + if (!pGid->syncRestore) { + calculateRstoreFinishTime(pGid->appliedRate, pGid->syncCommitIndex - pGid->syncAppliedIndex, restoreStr, + sizeof(restoreStr)); + } + STR_TO_VARSTR(buf, restoreStr); + colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false); + if (code != 0) { + mError("vgId:%d, failed to set syncRestore finish time, since %s", pVgroup->vgId, tstrerror(code)); + return code; + } + numOfRows++; sdbRelease(pSdb, pDnode); } From 878bac1556c2f0f7b0d8568f045db42805f6de68 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 11 Feb 2025 18:04:53 +0800 Subject: [PATCH 18/67] fix:[TS-5776]avoid memcpy fo DataRspObj --- source/client/src/clientRawBlockWrite.c | 14 ++--- source/client/src/clientTmq.c | 70 +++++++++++++++---------- source/common/src/msg/tmsg.c | 8 +-- source/dnode/vnode/src/inc/tq.h | 4 +- source/dnode/vnode/src/tq/tq.c | 2 +- source/dnode/vnode/src/tq/tqScan.c | 2 +- source/dnode/vnode/src/tq/tqUtil.c | 5 +- 7 files changed, 59 insertions(+), 46 deletions(-) diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 68a99d2697..7f3a696f26 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -1948,10 +1948,10 @@ static int32_t initRawCacheHash() { } static bool needRefreshMeta(void* rawData, STableMeta* pTableMeta, SSchemaWrapper* pSW) { - if (rawData == NULL){ + if (rawData == NULL || pSW == NULL){ return false; } - if (pTableMeta == NULL || pSW == NULL) { + if (pTableMeta == NULL) { uError("invalid parameter in %s", __func__); return false; } @@ -2074,7 +2074,7 @@ static int32_t processCacheMeta(SHashObj* pVgHash, SHashObj* pNameHash, SHashObj SVCreateTbReq* pCreateReqDst, SCatalog* pCatalog, SRequestConnInfo* conn, SName* pName, STableMeta** pMeta, SSchemaWrapper* pSW, void* rawData, int32_t retry) { if (pVgHash == NULL || pNameHash == NULL || pMetaHash == NULL || pCatalog == NULL || conn == NULL || pName == NULL || - pMeta == NULL || pSW == NULL) { + pMeta == NULL) { uError("invalid parameter in %s", __func__); return TSDB_CODE_INVALID_PARA; } @@ -2337,14 +2337,8 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) RAW_NULL_CHECK(pStmt->pVgDataBlocks); while (++rspObj.resIter < rspObj.dataRsp.blockNum) { - if (!rspObj.dataRsp.withSchema) { - goto end; - } - const char* tbName = (const char*)taosArrayGetP(rspObj.dataRsp.blockTbName, rspObj.resIter); RAW_NULL_CHECK(tbName); - SSchemaWrapper* pSW = (SSchemaWrapper*)taosArrayGetP(rspObj.dataRsp.blockSchema, rspObj.resIter); - RAW_NULL_CHECK(pSW); void* pRetrieve = taosArrayGetP(rspObj.dataRsp.blockData, rspObj.resIter); RAW_NULL_CHECK(pRetrieve); void* rawData = getRawDataFromRes(pRetrieve); @@ -2358,7 +2352,7 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) // find schema data info STableMeta* pTableMeta = NULL; RAW_RETURN_CHECK(processCacheMeta(pVgHash, pNameHash, pMetaHash, NULL, pCatalog, &conn, &pName, - &pTableMeta, pSW, NULL, retry)); + &pTableMeta, NULL, NULL, retry)); char err[ERR_MSG_LEN] = {0}; code = rawBlockBindRawData(pVgroupHash, pStmt->pVgDataBlocks, pTableMeta, rawData); if (code != TSDB_CODE_SUCCESS) { diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index bb55eb2e31..15a7a9b538 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -42,18 +42,19 @@ #define PROCESS_POLL_RSP(FUNC,DATA) \ SDecoder decoder = {0}; \ - tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead)); \ + tDecoderInit(&decoder, POINTER_SHIFT(pRspWrapper->pollRsp.data, sizeof(SMqRspHead)), pRspWrapper->pollRsp.len - sizeof(SMqRspHead)); \ if (FUNC(&decoder, DATA) < 0) { \ tDecoderClear(&decoder); \ code = terrno; \ goto END;\ }\ tDecoderClear(&decoder);\ - (void)memcpy(DATA, pMsg->pData, sizeof(SMqRspHead)); + (void)memcpy(DATA, pRspWrapper->pollRsp.data, sizeof(SMqRspHead)); #define DELETE_POLL_RSP(FUNC,DATA) \ SMqPollRspWrapper* pRsp = &rspWrapper->pollRsp;\ - taosMemoryFreeClear(pRsp->pEpset);\ + taosMemoryFreeClear(pRsp->pEpset); \ + taosMemoryFreeClear(pRsp->data); \ FUNC(DATA); enum { @@ -190,6 +191,8 @@ typedef struct { SMqClientTopic* topicHandle; uint64_t reqId; SEpSet* pEpset; + void* data; + uint32_t len; union { struct{ SMqRspHead head; @@ -1742,7 +1745,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; - pTmq->rawData = 1; + pTmq->rawData = conf->rawData;; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { @@ -2068,27 +2071,13 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) { } rspType = ((SMqRspHead*)pMsg->pData)->mqMsgType; tqDebugC("consumer:0x%" PRIx64 " recv poll rsp, vgId:%d, type %d(%s),QID:0x%" PRIx64, tmq->consumerId, vgId, rspType, tmqMsgTypeStr[rspType], requestId); - if (rspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { - PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) - } else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) { - PROCESS_POLL_RSP(tDecodeMqMetaRsp, &pRspWrapper->pollRsp.metaRsp) - } else if (rspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { - PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) - } else if (rspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { - PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) - } else if (rspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { - PROCESS_POLL_RSP(tDecodeMqRawDataRsp, &pRspWrapper->pollRsp.dataRsp) - pRspWrapper->pollRsp.dataRsp.len = pMsg->len - sizeof(SMqRspHead); - pRspWrapper->pollRsp.dataRsp.rawData = POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)); - pMsg->pData = NULL; - } else { // invalid rspType - tqErrorC("consumer:0x%" PRIx64 " invalid rsp msg received, type:%d ignored", tmq->consumerId, rspType); - code = TSDB_CODE_TSC_INTERNAL_ERROR; - goto END; - } + pRspWrapper->tmqRspType = rspType; pRspWrapper->pollRsp.reqId = requestId; pRspWrapper->pollRsp.pEpset = pMsg->pEpSet; + pRspWrapper->pollRsp.data = pMsg->pData; + pRspWrapper->pollRsp.len = pMsg->len; + pMsg->pData = NULL; pMsg->pEpSet = NULL; END: @@ -2519,6 +2508,29 @@ END: return pRspObj; } +static int32_t processWrapperData(SMqRspWrapper* pRspWrapper){ + int32_t code = 0; + if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { + PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { + PROCESS_POLL_RSP(tDecodeMqMetaRsp, &pRspWrapper->pollRsp.metaRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { + PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { + PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { + PROCESS_POLL_RSP(tDecodeMqRawDataRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.len = pRspWrapper->pollRsp.len - sizeof(SMqRspHead); + pRspWrapper->pollRsp.dataRsp.rawData = POINTER_SHIFT(pRspWrapper->pollRsp.data, sizeof(SMqRspHead)); + pRspWrapper->pollRsp.data = NULL; + } else { + tqErrorC("invalid rsp msg received, type:%d ignored", pRspWrapper->tmqRspType); + code = TSDB_CODE_TSC_INTERNAL_ERROR; + goto END; + } +END: + return code; +} static void* tmqHandleAllRsp(tmq_t* tmq) { tqDebugC("consumer:0x%" PRIx64 " start to handle the rsp, total:%d", tmq->consumerId, taosQallItemSize(tmq->qall)); @@ -2538,12 +2550,16 @@ static void* tmqHandleAllRsp(tmq_t* tmq) { } tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%s", tmq->consumerId, tmqMsgTypeStr[pRspWrapper->tmqRspType]); - if (pRspWrapper->code != 0) { - code = processMqRspError(tmq, pRspWrapper); - }else{ - returnVal = processMqRsp(tmq, pRspWrapper); - code = terrno; + code = processWrapperData(pRspWrapper); + if (code == 0){ + if (pRspWrapper->code != 0) { + code = processMqRspError(tmq, pRspWrapper); + }else{ + returnVal = processMqRsp(tmq, pRspWrapper); + code = terrno; + } } + tmqFreeRspWrapper(pRspWrapper); taosFreeQitem(pRspWrapper); if(returnVal != NULL || code != 0){ diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 22bf3a529c..d7c793df33 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11445,9 +11445,9 @@ int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) { } for (int32_t i = 0; i < pRsp->blockNum; i++) { - void *data; - uint64_t bLen; - TAOS_CHECK_EXIT(tDecodeBinaryAlloc(pDecoder, &data, &bLen)); + void *data = NULL; + uint32_t bLen = 0; + TAOS_CHECK_EXIT(tDecodeBinary(pDecoder, (uint8_t**)&data, &bLen)); if (taosArrayPush(pRsp->blockData, &data) == NULL) { TAOS_CHECK_EXIT(terrno); } @@ -11510,7 +11510,7 @@ _exit: static void tDeleteMqDataRspCommon(SMqDataRsp *pRsp) { taosArrayDestroy(pRsp->blockDataLen); pRsp->blockDataLen = NULL; - taosArrayDestroyP(pRsp->blockData, NULL); + taosArrayDestroy(pRsp->blockData); pRsp->blockData = NULL; taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper); pRsp->blockSchema = NULL; diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index f5410659b1..ec82fd8e71 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -118,7 +118,7 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, uint64_t // tqExec int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, const SMqPollReq* pRequest); -int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, +int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, SMqDataRsp* pRsp, int32_t type, int32_t vgId); void tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId); @@ -147,7 +147,7 @@ int32_t tqOffsetRestoreFromFile(STQ* pTq, char* name); // tq util int32_t tqExtractDelDataBlock(const void* pData, int32_t len, int64_t ver, void** pRefBlock, int32_t type, EStreamType blockType); int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg); -int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, +int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, int32_t type, int64_t sver, int64_t ever); int32_t tqInitDataRsp(SMqDataRsp* pRsp, STqOffsetVal pOffset); void tqUpdateNodeStage(STQ* pTq, bool isLeader); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index cdedda3e9c..daf4fa65f3 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -208,7 +208,7 @@ void tqPushEmptyDataRsp(STqHandle* pHandle, int32_t vgId) { tDeleteMqDataRsp(&dataRsp); } -int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type, +int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, SMqDataRsp* pRsp, int32_t type, int32_t vgId) { if (pHandle == NULL || pMsg == NULL || pReq == NULL || pRsp == NULL) { return TSDB_CODE_INVALID_PARA; diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index a33d050460..941e74fd9b 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -263,7 +263,7 @@ int32_t tqScanTaosx(STQ* pTq, const STqHandle* pHandle, SMqDataRsp* pRsp, SMqBat tbName = NULL; } if (pRsp->withSchema) { - SSchemaWrapper* pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task)); + pSW = tCloneSSchemaWrapper(qExtractSchemaFromTask(task)); TSDB_CHECK_NULL(pSW, code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockSchema, &pSW), code, lino, END, terrno); pSW = NULL; diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 86a5bba712..bb6751c883 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -533,7 +533,7 @@ int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPoll return 0; } -int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, +int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId, int32_t type, int64_t sver, int64_t ever) { if (pRpcHandleInfo == NULL || pRsp == NULL) { return TSDB_CODE_TMQ_INVALID_MSG; @@ -541,6 +541,9 @@ int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* int32_t len = 0; int32_t code = 0; + if (type == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP){ + pRsp->withSchema = 0; + } if (type == TMQ_MSG_TYPE__POLL_DATA_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP || type == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { From f0b9e7b5f4a1e9dda69570f9c3069262d825b710 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 11 Feb 2025 18:44:56 +0800 Subject: [PATCH 19/67] fix:[TS-5776]avoid memcpy fo DataRspObj --- include/common/tmsg.h | 1 + source/client/src/clientTmq.c | 6 +++++- source/common/src/msg/tmsg.c | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index b4606ffe86..97955c0c49 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -4267,6 +4267,7 @@ typedef struct { void* rawData; }; }; + void* data; //for free, only effected if type is data or metadata. raw data not effected } SMqDataRsp; diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 15a7a9b538..d2b6aff2bf 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1745,7 +1745,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; - pTmq->rawData = conf->rawData;; + pTmq->rawData = conf->rawData; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { @@ -2512,10 +2512,14 @@ static int32_t processWrapperData(SMqRspWrapper* pRspWrapper){ int32_t code = 0; if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; + pRspWrapper->pollRsp.data = NULL; } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { PROCESS_POLL_RSP(tDecodeMqMetaRsp, &pRspWrapper->pollRsp.metaRsp) } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; + pRspWrapper->pollRsp.data = NULL; } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index d7c793df33..e5926dcb24 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11518,6 +11518,7 @@ static void tDeleteMqDataRspCommon(SMqDataRsp *pRsp) { pRsp->blockTbName = NULL; tOffsetDestroy(&pRsp->reqOffset); tOffsetDestroy(&pRsp->rspOffset); + taosMemoryFreeClear(pRsp->data); } void tDeleteMqDataRsp(SMqDataRsp *rsp) { tDeleteMqDataRspCommon(rsp); } From 020840bd12c11ac6577479bb5d0735b11c04673c Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 12 Feb 2025 09:09:05 +0800 Subject: [PATCH 20/67] fix:[TS-5776]avoid memcpy fo DataRspObj --- tests/system-test/7-tmq/taosx-performance.py | 96 +++++++++++++++----- 1 file changed, 71 insertions(+), 25 deletions(-) diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 03073c7696..4471415e28 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -28,6 +28,9 @@ dnode2 = "./dnode2" cfg = "sim/dnode1/cfg" taosx = "taosx" taosd = "taosd" +taosxLog = "taosx.log" +taosxTimeout = 2 +timeCost = [] insertJson = '''{ "filetype": "insert", "cfgdir": "/etc/taos", @@ -84,9 +87,10 @@ insertJson = '''{ {"type": "TINYINT", "name": "current", "max": 128, "min": 1 }, { "type": "BOOL", "name": "phaseewe" }, { "type": "BINARY", "name": "str", "len":16374, - "values": ["{kkey00000k: kvalue00000k, kkey00001k: kvalue00001k, kkey00002k: kvalue00002k, kkey00003k: kvalue00003k, kkey00004k: kvalue00004k, kkey00005k: kvalue00005k, kkey00006k: kvalue00006k, kkey00007k: kvalue00007k, kkey00008k: kvalue00008k, kkey00009k: kvalue00009k, kkey00010k: kvalue00010k, kkey00011k: kvalue00011k, kkey00012k: kvalue00012k, kkey00013k: kvalue00013k, kkey00014k: kvalue00014k, kkey00015k: kvalue00015k, kkey00016k: kvalue00016k, kkey00017k: kvalue00017k, kkey00018k: kvalue00018k, kkey00019k: kvalue00019k, kkey00020k: kvalue00020k, kkey00021k: kvalue00021k, kkey00022k: kvalue00022k, kkey00023k: kvalue00023k, kkey00024k: kvalue00024k, kkey00025k: kvalue00025k, kkey00026k: kvalue00026k, kkey00027k: kvalue00027k, kkey00028k: kvalue00028k, kkey00029k: kvalue00029k, kkey00030k: kvalue00030k, kkey00031k: kvalue00031k, kkey00032k: kvalue00032k, kkey00033k: kvalue00033k, kkey00034k: kvalue00034k, kkey00035k: kvalue00035k, kkey00036k: kvalue00036k, kkey00037k: kvalue00037k, kkey00038k: kvalue00038k, kkey00039k: kvalue00039k, kkey00040k: kvalue00040k, kkey00041k: kvalue00041k, kkey00042k: kvalue00042k, kkey00043k: kvalue00043k, kkey00044k: kvalue00044k, kkey00045k: kvalue00045k, kkey00046k: kvalue00046k, kkey00047k: kvalue00047k, kkey00048k: kvalue00048k, kkey00049k: kvalue00049k, kkey00050k: kvalue00050k, kkey00051k: kvalue00051k, kkey00052k: kvalue00052k, kkey00053k: kvalue00053k, kkey00054k: kvalue00054k, kkey00055k: kvalue00055k, kkey00056k: kvalue00056k, kkey00057k: kvalue00057k, kkey00058k: kvalue00058k, kkey00059k: kvalue00059k, kkey00060k: kvalue00060k, kkey00061k: kvalue00061k, kkey00062k: kvalue00062k, kkey00063k: kvalue00063k, kkey00064k: kvalue00064k, kkey00065k: kvalue00065k, kkey00066k: kvalue00066k, kkey00067k: kvalue00067k, kkey00068k: kvalue00068k, kkey00069k: kvalue00069k, kkey00070k: kvalue00070k, kkey00071k: kvalue00071k, kkey00072k: kvalue00072k, kkey00073k: kvalue00073k, kkey00074k: kvalue00074k, kkey00075k: kvalue00075k, kkey00076k: kvalue00076k, kkey00077k: kvalue00077k, kkey00078k: kvalue00078k, kkey00079k: kvalue00079k, kkey00080k: kvalue00080k, kkey00081k: kvalue00081k, kkey00082k: kvalue00082k, kkey00083k: kvalue00083k, kkey00084k: kvalue00084k, kkey00085k: kvalue00085k, kkey00086k: kvalue00086k, kkey00087k: kvalue00087k, kkey00088k: kvalue00088k, kkey00089k: kvalue00089k, kkey00090k: kvalue00090k, kkey00091k: kvalue00091k, kkey00092k: kvalue00092k, kkey00093k: kvalue00093k, kkey00094k: kvalue00094k, kkey00095k: kvalue00095k, kkey00096k: kvalue00096k, kkey00097k: kvalue00097k, kkey00098k: kvalue00098k, kkey00099k: kvalue00099k, kkey00100k: kvalue00100k, kkey00101k: kvalue00101k, kkey00102k: kvalue00102k, kkey00103k: kvalue00103k, kkey00104k: kvalue00104k, kkey00105k: kvalue00105k, kkey00106k: kvalue00106k, kkey00107k: kvalue00107k, kkey00108k: kvalue00108k, kkey00109k: kvalue00109k, kkey00110k: kvalue00110k, kkey00111k: kvalue00111k, kkey00112k: kvalue00112k, kkey00113k: kvalue00113k, kkey00114k: kvalue00114k, kkey00115k: kvalue00115k, kkey00116k: kvalue00116k, kkey00117k: kvalue00117k, kkey00118k: kvalue00118k, kkey00119k: kvalue00119k, kkey00120k: kvalue00120k, kkey00121k: kvalue00121k, kkey00122k: kvalue00122k, kkey00123k: kvalue00123k, kkey00124k: kvalue00124k, kkey00125k: kvalue00125k, kkey00126k: kvalue00126k, kkey00127k: kvalue00127k, kkey00128k: kvalue00128k, kkey00129k: kvalue00129k, kkey00130k: kvalue00130k, kkey00131k: kvalue00131k, kkey00132k: kvalue00132k, kkey00133k: kvalue00133k, kkey00134k: kvalue00134k, kkey00135k: kvalue00135k, kkey00136k: kvalue00136k, kkey00137k: kvalue00137k, kkey00138k: kvalue00138k, kkey00139k: kvalue00139k, kkey00140k: kvalue00140k, kkey00141k: kvalue00141k, kkey00142k: kvalue00142k, kkey00143k: kvalue00143k, kkey00144k: kvalue00144k, kkey00145k: kvalue00145k, kkey00146k: kvalue00146k, kkey00147k: kvalue00147k, kkey00148k: kvalue00148k, kkey00149k: kvalue00149k, kkey00150k: kvalue00150k, kkey00151k: kvalue00151k, kkey00152k: kvalue00152k, kkey00153k: kvalue00153k, kkey00154k: kvalue00154k, kkey00155k: kvalue00155k, kkey00156k: kvalue00156k, kkey00157k: kvalue00157k, kkey00158k: kvalue00158k, kkey00159k: kvalue00159k, kkey00160k: kvalue00160k, kkey00161k: kvalue00161k, kkey00162k: kvalue00162k, kkey00163k: kvalue00163k, kkey00164k: kvalue00164k, kkey00165k: kvalue00165k, kkey00166k: kvalue00166k, kkey00167k: kvalue00167k, kkey00168k: kvalue00168k, kkey00169k: kvalue00169k, kkey00170k: kvalue00170k, kkey00171k: kvalue00171k, kkey00172k: kvalue00172k, kkey00173k: kvalue00173k, kkey00174k: kvalue00174k, kkey00175k: kvalue00175k, kkey00176k: kvalue00176k, kkey00177k: kvalue00177k, kkey00178k: kvalue00178k, kkey00179k: kvalue00179k, kkey00180k: kvalue00180k, kkey00181k: kvalue00181k, kkey00182k: kvalue00182k, kkey00183k: kvalue00183k, kkey00184k: kvalue00184k, kkey00185k: kvalue00185k, kkey00186k: kvalue00186k, kkey00187k: kvalue00187k, kkey00188k: kvalue00188k, kkey00189k: kvalue00189k, kkey00190k: kvalue00190k, kkey00191k: kvalue00191k, kkey00192k: kvalue00192k, kkey00193k: kvalue00193k, kkey00194k: kvalue00194k, kkey00195k: kvalue00195k, kkey00196k: kvalue00196k, kkey00197k: kvalue00197k, kkey00198k: kvalue00198k, kkey00199k: kvalue00199k}", - "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino", - "Los Angles", "San Diego", "San Jose", "Palo Alto", "Campbell", "Mountain View", "Sunnyvale", "Santa Clara", "Cupertino" + "values": [ + "{kkey00000k: kvalue00000k, kkey00001k: kvalue00001k, kkey00002k: kvalue00002k, kkey00003k: kvalue00003k, kkey00004k: kvalue00004k, kkey00005k: kvalue00005k, kkey00006k: kvalue00006k, kkey00007k: kvalue00007k, kkey00008k: kvalue00008k, kkey00009k: kvalue00009k, kkey00010k: kvalue00010k, kkey00011k: kvalue00011k, kkey00012k: kvalue00012k, kkey00013k: kvalue00013k, kkey00014k: kvalue00014k, kkey00015k: kvalue00015k, kkey00016k: kvalue00016k, kkey00017k: kvalue00017k, kkey00018k: kvalue00018k, kkey00019k: kvalue00019k, kkey00020k: kvalue00020k, kkey00021k: kvalue00021k, kkey00022k: kvalue00022k, kkey00023k: kvalue00023k, kkey00024k: kvalue00024k, kkey00025k: kvalue00025k, kkey00026k: kvalue00026k, kkey00027k: kvalue00027k, kkey00028k: kvalue00028k, kkey00029k: kvalue00029k, kkey00030k: kvalue00030k, kkey00031k: kvalue00031k, kkey00032k: kvalue00032k, kkey00033k: kvalue00033k, kkey00034k: kvalue00034k, kkey00035k: kvalue00035k, kkey00036k: kvalue00036k, kkey00037k: kvalue00037k, kkey00038k: kvalue00038k, kkey00039k: kvalue00039k, kkey00040k: kvalue00040k, kkey00041k: kvalue00041k, kkey00042k: kvalue00042k, kkey00043k: kvalue00043k, kkey00044k: kvalue00044k, kkey00045k: kvalue00045k, kkey00046k: kvalue00046k, kkey00047k: kvalue00047k, kkey00048k: kvalue00048k, kkey00049k: kvalue00049k, kkey00050k: kvalue00050k, kkey00051k: kvalue00051k, kkey00052k: kvalue00052k, kkey00053k: kvalue00053k, kkey00054k: kvalue00054k, kkey00055k: kvalue00055k, kkey00056k: kvalue00056k, kkey00057k: kvalue00057k, kkey00058k: kvalue00058k, kkey00059k: kvalue00059k, kkey00060k: kvalue00060k, kkey00061k: kvalue00061k, kkey00062k: kvalue00062k, kkey00063k: kvalue00063k, kkey00064k: kvalue00064k, kkey00065k: kvalue00065k, kkey00066k: kvalue00066k, kkey00067k: kvalue00067k, kkey00068k: kvalue00068k, kkey00069k: kvalue00069k, kkey00070k: kvalue00070k, kkey00071k: kvalue00071k, kkey00072k: kvalue00072k, kkey00073k: kvalue00073k, kkey00074k: kvalue00074k, kkey00075k: kvalue00075k, kkey00076k: kvalue00076k, kkey00077k: kvalue00077k, kkey00078k: kvalue00078k, kkey00079k: kvalue00079k, kkey00080k: kvalue00080k, kkey00081k: kvalue00081k, kkey00082k: kvalue00082k, kkey00083k: kvalue00083k, kkey00084k: kvalue00084k, kkey00085k: kvalue00085k, kkey00086k: kvalue00086k, kkey00087k: kvalue00087k, kkey00088k: kvalue00088k, kkey00089k: kvalue00089k, kkey00090k: kvalue00090k, kkey00091k: kvalue00091k, kkey00092k: kvalue00092k, kkey00093k: kvalue00093k, kkey00094k: kvalue00094k, kkey00095k: kvalue00095k, kkey00096k: kvalue00096k, kkey00097k: kvalue00097k, kkey00098k: kvalue00098k, kkey00099k: kvalue00099k, kkey00100k: kvalue00100k, kkey00101k: kvalue00101k, kkey00102k: kvalue00102k, kkey00103k: kvalue00103k, kkey00104k: kvalue00104k, kkey00105k: kvalue00105k, kkey00106k: kvalue00106k, kkey00107k: kvalue00107k, kkey00108k: kvalue00108k, kkey00109k: kvalue00109k, kkey00110k: kvalue00110k, kkey00111k: kvalue00111k, kkey00112k: kvalue00112k, kkey00113k: kvalue00113k, kkey00114k: kvalue00114k, kkey00115k: kvalue00115k, kkey00116k: kvalue00116k, kkey00117k: kvalue00117k, kkey00118k: kvalue00118k, kkey00119k: kvalue00119k, kkey00120k: kvalue00120k, kkey00121k: kvalue00121k, kkey00122k: kvalue00122k, kkey00123k: kvalue00123k, kkey00124k: kvalue00124k, kkey00125k: kvalue00125k, kkey00126k: kvalue00126k, kkey00127k: kvalue00127k, kkey00128k: kvalue00128k, kkey00129k: kvalue00129k, kkey00130k: kvalue00130k, kkey00131k: kvalue00131k, kkey00132k: kvalue00132k, kkey00133k: kvalue00133k, kkey00134k: kvalue00134k, kkey00135k: kvalue00135k, kkey00136k: kvalue00136k, kkey00137k: kvalue00137k, kkey00138k: kvalue00138k, kkey00139k: kvalue00139k, kkey00140k: kvalue00140k, kkey00141k: kvalue00141k, kkey00142k: kvalue00142k, kkey00143k: kvalue00143k, kkey00144k: kvalue00144k, kkey00145k: kvalue00145k, kkey00146k: kvalue00146k, kkey00147k: kvalue00147k, kkey00148k: kvalue00148k, kkey00149k: kvalue00149k, kkey00150k: kvalue00150k, kkey00151k: kvalue00151k, kkey00152k: kvalue00152k, kkey00153k: kvalue00153k, kkey00154k: kvalue00154k, kkey00155k: kvalue00155k, kkey00156k: kvalue00156k, kkey00157k: kvalue00157k, kkey00158k: kvalue00158k, kkey00159k: kvalue00159k, kkey00160k: kvalue00160k, kkey00161k: kvalue00161k, kkey00162k: kvalue00162k, kkey00163k: kvalue00163k, kkey00164k: kvalue00164k, kkey00165k: kvalue00165k, kkey00166k: kvalue00166k, kkey00167k: kvalue00167k, kkey00168k: kvalue00168k, kkey00169k: kvalue00169k, kkey00170k: kvalue00170k, kkey00171k: kvalue00171k, kkey00172k: kvalue00172k, kkey00173k: kvalue00173k, kkey00174k: kvalue00174k, kkey00175k: kvalue00175k, kkey00176k: kvalue00176k, kkey00177k: kvalue00177k, kkey00178k: kvalue00178k, kkey00179k: kvalue00179k, kkey00180k: kvalue00180k, kkey00181k: kvalue00181k, kkey00182k: kvalue00182k, kkey00183k: kvalue00183k, kkey00184k: kvalue00184k, kkey00185k: kvalue00185k, kkey00186k: kvalue00186k, kkey00187k: kvalue00187k, kkey00188k: kvalue00188k, kkey00189k: kvalue00189k, kkey00190k: kvalue00190k, kkey00191k: kvalue00191k, kkey00192k: kvalue00192k, kkey00193k: kvalue00193k, kkey00194k: kvalue00194k, kkey00195k: kvalue00195k, kkey00196k: kvalue00196k, kkey00197k: kvalue00197k, kkey00198k: kvalue00198k, kkey00199k: kvalue00199k}", + "NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL","NULL", + "NULerL","NdrerULL","NU232LL","NUL23L","NU23LL","NU23LL","NUL23L","NUL32L" ] }, { "type": "BIGINT", "name": "cnt", "max" : 2563332323232, "min":1 }, @@ -163,13 +167,13 @@ def restartTaosd(): def runTaosx(): - cmd = f"{taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=2s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\"" + cmd = f"{taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout={taosxTimeout}s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > {taosxLog}" print("run taosx:%s" % cmd) os.system(cmd) -def parseArgs(): - if len(sys.argv[1:]) < 6: +def parseArgs(argv): + if len(argv) < 6: print( "Usage: python3 taosx-performance.py path_to_taosx path_to_taosd init vgroups tables rows_of_each_table [path]") sys.exit(1) @@ -183,26 +187,26 @@ def parseArgs(): global path global dnode1 global dnode2 - taosx = sys.argv[1] - taosd = sys.argv[2] - init = sys.argv[3] - vgroups = sys.argv[4] - tables = sys.argv[5] - rows_of_each_table = sys.argv[6] - if len(sys.argv[1:]) == 7: - path = sys.argv[7] + taosx = argv[0] + taosd = argv[1] + init = argv[2] + vgroups = argv[3] + tables = argv[4] + rows_of_each_table = argv[5] + if len(argv) == 7: + path = argv[6] if not os.path.isdir(path): mkCmd = f"mkdir {path}" os.system(mkCmd) # os.system("git clone https://github.com/brendangregg/FlameGraph.git taosx-perf") +def getCost(): + costCmd = f"cat {taosxLog}| grep 'time cost'" + "| awk '{print $3}' | xargs" + cost = subprocess.check_output(costCmd, shell=True).decode("utf-8").strip() + return cost - -''' -python3 taosx-performance.py path_to_taosx path_to_taosd init vgroups tables rows_of_each_table [path] -''' -if __name__ == "__main__": - parseArgs() +def runOnce(argv): + parseArgs(argv) os.chdir(path) print("current dir:" + os.getcwd()) @@ -219,12 +223,54 @@ if __name__ == "__main__": cleanDb() runTaosx() - # os.system("taosx run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout=50s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > /dev/null 2>&1 &") - # time.sleep(10) + cost = getCost() + print("cost:%s" % cost) + timeCost.append(cost) - # print("start to run perf") - # os.system("perf record -a -g -F 99 -p `pidof taosx` sleep 60") +''' +python3 taosx-performance.py once path_to_taosx path_to_taosd init vgroups tables rows_of_each_table [path] +''' +paras = [ + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 1, 5000, 200, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 1, 5000, 200, "/tmp/taosx_perf"), - # os.system("perf script | ./stackcollapse-perf.pl| ./flamegraph.pl > flame.svg") + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 1, 5000, 1000, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 1, 5000, 1000, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 1, 5000, 2000, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 1, 5000, 2000, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 2, 10000, 100, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 2, 10000, 100, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 2, 10000, 500, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 2, 10000, 500, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 2, 10000, 1000, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 2, 10000, 1000, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 4, 20000, 500, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 4, 20000, 500, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 8, 40000, 250, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 8, 40000, 250, "/tmp/taosx_perf"), + + ("/root/taosx/taosx/target/release/taosx", "~/TDinternal/community/debug/build/bin/taosd", "true", 16, 100000, 100, "/tmp/taosx_perf"), + ("/root/taosx/taosx/target/release/taosx", "~/TDengine/debug/build/bin/taosd", "false", 16, 100000, 100, "/tmp/taosx_perf"), +] +if __name__ == "__main__": + print("run performance start") + + once = sys.argv[1] + if once == "once": + runOnce(sys.argv[2:]) + else: + for i in range(len(paras)): + runOnce(paras[i]) + if i % 2 == 1 : + print(f"opti cost:{float(timeCost[0]) - taosxTimeout}") + print(f"old cost:{float(timeCost[1]) - taosxTimeout}") + print(str(paras[i]) + f" speedup:{(float(timeCost[1]) - taosxTimeout)/(float(timeCost[0]) - taosxTimeout)}\n\n\n") + timeCost.clear() tdLog.info("run performance end") From a1a3f8328357cb7ddaf1372392c48350beaec828 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Wed, 12 Feb 2025 09:55:36 +0800 Subject: [PATCH 21/67] Add unapplied to show vnodes. --- source/common/src/systable.c | 1 + source/dnode/mnode/impl/src/mndVgroup.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index dbab7d892e..0a9ca8f884 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -372,6 +372,7 @@ static const SSysDbTableSchema vnodesSchema[] = { {.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "restored", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = true}, {.name = "restored_finish", .bytes = TSDB_SYNC_RESOTRE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "unapplied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, }; static const SSysDbTableSchema userUserPrivilegesSchema[] = { diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index f4f3866dc7..1f295af62f 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -1345,11 +1345,11 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB return code; } + int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex; pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); char restoreStr[20] = {0}; if (!pGid->syncRestore) { - calculateRstoreFinishTime(pGid->appliedRate, pGid->syncCommitIndex - pGid->syncAppliedIndex, restoreStr, - sizeof(restoreStr)); + calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr)); } STR_TO_VARSTR(buf, restoreStr); colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false); @@ -1358,6 +1358,13 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB return code; } + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + code = colDataSetVal(pColInfo, numOfRows, (const char *)&unappliedCount, false); + if (code != 0) { + mError("vgId:%d, failed to set syncRestore, since %s", pVgroup->vgId, tstrerror(code)); + return code; + } + numOfRows++; sdbRelease(pSdb, pDnode); } From 2f67ebbd5083602c6f7d30a4a509ff832bec05dd Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Wed, 12 Feb 2025 10:27:58 +0800 Subject: [PATCH 22/67] add test --- source/client/test/stmt2Test.cpp | 107 +++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index 91f884941f..cb5afedec0 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -1543,4 +1543,111 @@ TEST(stmt2Case, errcode) { code = taos_stmt_prepare(stmt, sql, 0); checkError(stmt, code); } + +void stmtAsyncBindCb(void* param, TAOS_RES* pRes, int code) { + if (code != TSDB_CODE_SUCCESS) { + taos_errstr(pRes); + } + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + return; +} + +TEST(stmt2Case, async_order) { + int CTB_NUMS = 3; + int ROW_NUMS = 3; + int CYC_NUMS = 3; + + TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb, NULL}; + char* sql = "insert into ? values(?,?)"; + + do_query(taos, "drop database if exists stmt2_testdb_15"); + do_query(taos, "create database IF NOT EXISTS stmt2_testdb_15"); + do_query(taos, "create stable stmt2_testdb_15.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); + do_query(taos, "use stmt2_testdb_15"); + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code); + int total_affected = 0; + + // tbname + char** tbs = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*)); + for (int i = 0; i < CTB_NUMS; i++) { + tbs[i] = (char*)taosMemoryMalloc(sizeof(char) * 20); + sprintf(tbs[i], "ctb_%d", i); + char* tmp = (char*)taosMemoryMalloc(sizeof(char) * 100); + sprintf(tmp, "create table stmt2_testdb_15.%s using stmt2_testdb_15.stb tags(0, 'after')", tbs[i]); + do_query(taos, tmp); + } + + // case 1 : bind_a->exec_a->bind_a->exec_a->... + for (int r = 0; r < CYC_NUMS; r++) { + // col params + int64_t** ts = (int64_t**)taosMemoryMalloc(CTB_NUMS * sizeof(int64_t*)); + char** b = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*)); + int* ts_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); + int* b_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); + for (int i = 0; i < ROW_NUMS; i++) { + ts_len[i] = sizeof(int64_t); + b_len[i] = 1; + } + for (int i = 0; i < CTB_NUMS; i++) { + ts[i] = (int64_t*)taosMemoryMalloc(ROW_NUMS * sizeof(int64_t)); + b[i] = (char*)taosMemoryMalloc(ROW_NUMS * sizeof(char)); + for (int j = 0; j < ROW_NUMS; j++) { + ts[i][j] = 1591060628000 + r * 100000 + j; + b[i][j] = 'a' + j; + } + } + + // bind params + TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); + + for (int i = 0; i < CTB_NUMS; i++) { + // create col params + paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); + paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS}; + paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS}; + } + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + // code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, NULL); + code = taos_stmt2_bind_param(stmt, &bindv, -1); + + checkError(stmt, code); + + // exec + int affected = 0; + code = taos_stmt2_exec(stmt, &affected); + total_affected += affected; + checkError(stmt, code); + + for (int i = 0; i < CTB_NUMS; i++) { + taosMemoryFree(paramv[i]); + taosMemoryFree(ts[i]); + taosMemoryFree(b[i]); + } + taosMemoryFree(ts); + taosMemoryFree(b); + taosMemoryFree(ts_len); + taosMemoryFree(b_len); + taosMemoryFree(paramv); + } + ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS); + + // case 2 : bind_a->bind_a->bind_a->exec_a->... + // case 3 : bind->exec_a->bind->exec_a->... + // case 4 : bind_a->exec->bind_a->exec->... + // case 5 : bind_a->close + // case 6 : exec_a->close + + for (int i = 0; i < CTB_NUMS; i++) { + taosMemoryFree(tbs[i]); + } + taosMemoryFree(tbs); + + taos_stmt2_close(stmt); +} #pragma GCC diagnostic pop From 891a6057caed721b878e1e7cf1b576ff7f01c32f Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 12 Feb 2025 11:09:32 +0800 Subject: [PATCH 23/67] fix:[TS-5776]avoid memcpy fo DataRspObj --- source/client/src/clientTmq.c | 73 ++++++++++---------- tests/system-test/7-tmq/taosx-performance.py | 6 +- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index d2b6aff2bf..4b2360ea27 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -2420,6 +2420,35 @@ static int32_t processMqRspError(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ return code; } + +static int32_t processWrapperData(SMqRspWrapper* pRspWrapper){ + int32_t code = 0; + if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { + PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; + pRspWrapper->pollRsp.data = NULL; + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { + PROCESS_POLL_RSP(tDecodeMqMetaRsp, &pRspWrapper->pollRsp.metaRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { + PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; + pRspWrapper->pollRsp.data = NULL; + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { + PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) + } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { + PROCESS_POLL_RSP(tDecodeMqRawDataRsp, &pRspWrapper->pollRsp.dataRsp) + pRspWrapper->pollRsp.dataRsp.len = pRspWrapper->pollRsp.len - sizeof(SMqRspHead); + pRspWrapper->pollRsp.dataRsp.rawData = POINTER_SHIFT(pRspWrapper->pollRsp.data, sizeof(SMqRspHead)); + pRspWrapper->pollRsp.data = NULL; + } else { + tqErrorC("invalid rsp msg received, type:%d ignored", pRspWrapper->tmqRspType); + code = TSDB_CODE_TSC_INTERNAL_ERROR; + goto END; + } + END: + return code; +} + static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ int32_t code = 0; SMqRspObj* pRspObj = NULL; @@ -2432,6 +2461,10 @@ static SMqRspObj* processMqRsp(tmq_t* tmq, SMqRspWrapper* pRspWrapper){ return pRspObj; } + code = processWrapperData(pRspWrapper); + if (code != 0) { + goto END; + } SMqPollRspWrapper* pollRspWrapper = &pRspWrapper->pollRsp; taosWLockLatch(&tmq->lock); SMqClientVg* pVg = NULL; @@ -2508,33 +2541,6 @@ END: return pRspObj; } -static int32_t processWrapperData(SMqRspWrapper* pRspWrapper){ - int32_t code = 0; - if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_RSP) { - PROCESS_POLL_RSP(tDecodeMqDataRsp, &pRspWrapper->pollRsp.dataRsp) - pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; - pRspWrapper->pollRsp.data = NULL; - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) { - PROCESS_POLL_RSP(tDecodeMqMetaRsp, &pRspWrapper->pollRsp.metaRsp) - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_DATA_META_RSP) { - PROCESS_POLL_RSP(tDecodeSTaosxRsp, &pRspWrapper->pollRsp.dataRsp) - pRspWrapper->pollRsp.dataRsp.data = pRspWrapper->pollRsp.data; - pRspWrapper->pollRsp.data = NULL; - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_BATCH_META_RSP) { - PROCESS_POLL_RSP(tSemiDecodeMqBatchMetaRsp, &pRspWrapper->pollRsp.batchMetaRsp) - } else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_RAW_DATA_RSP) { - PROCESS_POLL_RSP(tDecodeMqRawDataRsp, &pRspWrapper->pollRsp.dataRsp) - pRspWrapper->pollRsp.dataRsp.len = pRspWrapper->pollRsp.len - sizeof(SMqRspHead); - pRspWrapper->pollRsp.dataRsp.rawData = POINTER_SHIFT(pRspWrapper->pollRsp.data, sizeof(SMqRspHead)); - pRspWrapper->pollRsp.data = NULL; - } else { - tqErrorC("invalid rsp msg received, type:%d ignored", pRspWrapper->tmqRspType); - code = TSDB_CODE_TSC_INTERNAL_ERROR; - goto END; - } -END: - return code; -} static void* tmqHandleAllRsp(tmq_t* tmq) { tqDebugC("consumer:0x%" PRIx64 " start to handle the rsp, total:%d", tmq->consumerId, taosQallItemSize(tmq->qall)); @@ -2554,14 +2560,11 @@ static void* tmqHandleAllRsp(tmq_t* tmq) { } tqDebugC("consumer:0x%" PRIx64 " handle rsp, type:%s", tmq->consumerId, tmqMsgTypeStr[pRspWrapper->tmqRspType]); - code = processWrapperData(pRspWrapper); - if (code == 0){ - if (pRspWrapper->code != 0) { - code = processMqRspError(tmq, pRspWrapper); - }else{ - returnVal = processMqRsp(tmq, pRspWrapper); - code = terrno; - } + if (pRspWrapper->code != 0) { + code = processMqRspError(tmq, pRspWrapper); + }else{ + returnVal = processMqRsp(tmq, pRspWrapper); + code = terrno; } tmqFreeRspWrapper(pRspWrapper); diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 4471415e28..997c6ec096 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -31,6 +31,7 @@ taosd = "taosd" taosxLog = "taosx.log" taosxTimeout = 2 timeCost = [] +speedupStr = [] insertJson = '''{ "filetype": "insert", "cfgdir": "/etc/taos", @@ -270,7 +271,10 @@ if __name__ == "__main__": if i % 2 == 1 : print(f"opti cost:{float(timeCost[0]) - taosxTimeout}") print(f"old cost:{float(timeCost[1]) - taosxTimeout}") - print(str(paras[i]) + f" speedup:{(float(timeCost[1]) - taosxTimeout)/(float(timeCost[0]) - taosxTimeout)}\n\n\n") + tmp = str(paras[i]) + f" speedup:{(float(timeCost[1]) - taosxTimeout)/(float(timeCost[0]) - taosxTimeout)}" + speedupStr.append(tmp) + print(tmp + "\n\n\n") timeCost.clear() + print("performance result:\n" + str(speedupStr)) tdLog.info("run performance end") From 359399f1cd924858de959ba2def8ca031b10efed Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Wed, 12 Feb 2025 14:49:59 +0800 Subject: [PATCH 24/67] feat rename some names. --- include/util/tdef.h | 3 ++- source/common/src/systable.c | 10 +++++----- source/dnode/mnode/impl/src/mndDnode.c | 4 ++-- source/dnode/mnode/impl/src/mndVgroup.c | 22 ++++++++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/include/util/tdef.h b/include/util/tdef.h index 862c18da28..ee3284991f 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -363,7 +363,8 @@ typedef enum ELogicConditionType { #define TSDB_MAX_REPLICA 5 #define TSDB_MAX_LEARNER_REPLICA 10 -#define TSDB_SYNC_RESOTRE_lEN 20 +#define TSDB_SYNC_RESTORE_lEN 20 +#define TSDB_SYNC_APPLY_COMMIT_LEN 27 #define TSDB_SYNC_LOG_BUFFER_SIZE 4096 #define TSDB_SYNC_LOG_BUFFER_RETENTION 256 #define TSDB_SYNC_LOG_BUFFER_THRESHOLD (1024 * 1024 * 5) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 0a9ca8f884..636ac4da7e 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -290,17 +290,17 @@ static const SSysDbTableSchema vgroupsSchema[] = { {.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "tables", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v1_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, - {.name = "v1_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v1_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v1_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v2_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, - {.name = "v2_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v2_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v2_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v3_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, - {.name = "v3_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v3_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v3_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v4_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, - {.name = "v4_applied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v4_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v4_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "cacheload", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "cacheelements", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "tsma", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT, .sysInfo = true}, @@ -371,7 +371,7 @@ static const SSysDbTableSchema vnodesSchema[] = { {.name = "role_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "start_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = true}, {.name = "restored", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = true}, - {.name = "restored_finish", .bytes = TSDB_SYNC_RESOTRE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "apply_finish_time", .bytes = TSDB_SYNC_RESTORE_lEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "unapplied", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, }; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index d666b6cd9d..1a74573490 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -539,7 +539,7 @@ double calcAppliedRate(int64_t currentCount, int64_t lastCount, int64_t currentT if ((currentTimeMs <= lastTimeMs) || (currentCount <= lastCount)) { return 0.0; } - + int64_t deltaCount = currentCount - lastCount; int64_t deltaMs = currentTimeMs - lastTimeMs; double rate = (double)deltaCount / (double)deltaMs; @@ -552,7 +552,7 @@ static bool mndUpdateVnodeState(int32_t vgId, SVnodeGid *pGid, SVnodeLoad *pVloa (pVload->syncTerm != -1 && pGid->syncTerm != pVload->syncTerm) || pGid->roleTimeMs != pVload->roleTimeMs; - if (!pVload->syncRestore) { + if (pVload->syncCommitIndex > pVload->syncAppliedIndex) { if (pGid->lastSyncAppliedIndexUpdateTime == 0) { pGid->lastSyncAppliedIndexUpdateTime = taosGetTimestampMs(); } else if (pGid->syncAppliedIndex != pVload->syncAppliedIndex) { diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index 1f295af62f..ca48b23e6f 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -1067,13 +1067,6 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p return code; } - pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); - code = colDataSetVal(pColInfo, numOfRows, (const char *)&pVgroup->vnodeGid[i].syncAppliedIndex, false); - if (code != 0) { - mError("vgId:%d, failed to set role, since %s", pVgroup->vgId, tstrerror(code)); - return code; - } - bool exist = false; bool online = false; SDnodeObj *pDnode = mndAcquireDnode(pMnode, pVgroup->vnodeGid[i].dnodeId); @@ -1131,6 +1124,19 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p mError("vgId:%d, failed to set role, since %s", pVgroup->vgId, tstrerror(code)); return code; } + + char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN] = {0}; + char buf[TSDB_SYNC_APPLY_COMMIT_LEN] = {0}; + snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex, + pVgroup->vnodeGid[i].syncCommitIndex); + STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes); + + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + code = colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false); + if (code != 0) { + mError("vgId:%d, failed to set role, since %s", pVgroup->vgId, tstrerror(code)); + return code; + } } else { colDataSetNULL(pColInfo, numOfRows); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); @@ -1348,7 +1354,7 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB int64_t unappliedCount = pGid->syncCommitIndex - pGid->syncAppliedIndex; pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); char restoreStr[20] = {0}; - if (!pGid->syncRestore) { + if (unappliedCount > 0) { calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr)); } STR_TO_VARSTR(buf, restoreStr); From b38ac6abbf004395de0577452f3cc2d6e26dca0c Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Wed, 12 Feb 2025 15:32:47 +0800 Subject: [PATCH 25/67] Fix ci problems. --- tests/army/frame/clusterCommonCheck.py | 4 ++-- tests/system-test/3-enterprise/restore/restoreBasic.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/army/frame/clusterCommonCheck.py b/tests/army/frame/clusterCommonCheck.py index 9cbac776b9..02e97612b0 100644 --- a/tests/army/frame/clusterCommonCheck.py +++ b/tests/army/frame/clusterCommonCheck.py @@ -291,9 +291,9 @@ class ClusterComCheck: return True elif self.db_replica == 3 : - vgroup_status_first=[tdSql.res[0][4],tdSql.res[0][6],tdSql.res[0][8]] + vgroup_status_first=[tdSql.res[0][4],tdSql.res[0][7],tdSql.res[0][10]] - vgroup_status_last=[tdSql.res[last_number][4],tdSql.res[last_number][6],tdSql.res[last_number][8]] + vgroup_status_last=[tdSql.res[last_number][4],tdSql.res[last_number][7],tdSql.res[last_number][10]] 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: tdSql.query(f"select `replica` from information_schema.ins_databases where `name`='{db_name}';") diff --git a/tests/system-test/3-enterprise/restore/restoreBasic.py b/tests/system-test/3-enterprise/restore/restoreBasic.py index 74cf572018..9ca48ed7e8 100644 --- a/tests/system-test/3-enterprise/restore/restoreBasic.py +++ b/tests/system-test/3-enterprise/restore/restoreBasic.py @@ -80,7 +80,7 @@ class RestoreBasic: for i in range(8): leader = False for j in range(3): - status = tdSql.getData(i, 4 + j*2) + status = tdSql.getData(i, 4 + j*3) if status == "leader": leader = True elif status == "follower": From c3f4c4cf279b37c3f82fcb3d66c74ef5b8b6bbb1 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 12 Feb 2025 16:02:14 +0800 Subject: [PATCH 26/67] fix:[TS-5776]add raw type from consumer --- source/client/src/clientTmq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 4b2360ea27..1e9533ef69 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1745,7 +1745,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; - pTmq->rawData = conf->rawData; + pTmq->rawData = 1; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { From d1ef88eba431b0a008915ffa7d879a2e9813bee0 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Wed, 12 Feb 2025 18:29:07 +0800 Subject: [PATCH 27/67] Fix ci problems. --- tests/army/cluster/arbitrator.py | 6 +++--- tests/army/frame/clusterCommonCheck.py | 12 ++++++++++++ tests/system-test/6-cluster/clusterCommonCheck.py | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/army/cluster/arbitrator.py b/tests/army/cluster/arbitrator.py index 385358e5cc..25f955e7d1 100644 --- a/tests/army/cluster/arbitrator.py +++ b/tests/army/cluster/arbitrator.py @@ -57,11 +57,11 @@ class TDTestCase(TBase): tdSql.query("show db.vgroups;") - if(tdSql.getData(0, 4) == "follower") and (tdSql.getData(0, 6) == "leader"): + if(tdSql.getData(0, 4) == "follower") and (tdSql.getData(0, 7) == "leader"): tdLog.info("stop dnode2") sc.dnodeStop(2) - if(tdSql.getData(0, 6) == "follower") and (tdSql.getData(0, 4) == "leader"): + if(tdSql.getData(0, 7) == "follower") and (tdSql.getData(0, 4) == "leader"): tdLog.info("stop dnode 3") sc.dnodeStop(3) @@ -70,7 +70,7 @@ class TDTestCase(TBase): while count < 100: tdSql.query("show db.vgroups;") - if(tdSql.getData(0, 4) == "assigned ") or (tdSql.getData(0, 6) == "assigned "): + if(tdSql.getData(0, 4) == "assigned ") or (tdSql.getData(0, 7) == "assigned "): break tdLog.info("wait 1 seconds for set assigned") diff --git a/tests/army/frame/clusterCommonCheck.py b/tests/army/frame/clusterCommonCheck.py index 02e97612b0..75b82d2101 100644 --- a/tests/army/frame/clusterCommonCheck.py +++ b/tests/army/frame/clusterCommonCheck.py @@ -301,6 +301,18 @@ class ClusterComCheck: if tdSql.res[0][0] == db_replica: tdLog.success(f"elections of {db_name}.vgroups with replica {self.db_replica} are ready in {count} s") return True + + vgruop_apply_commit_first = [tdSql.res[0][5],tdSql.res[0][8],tdSql.res[0][11]] + vgruop_apply_commit_end = [tdSql.res[last_number][5],tdSql.res[last_number][8],tdSql.res[last_number][11]] + for i in range(3): + v = vgruop_apply_commit_first[i].split('/') + assert (int(v[0]) <= int(v[1])) ,f"apply {v[0]} > commit {v[1]}" + + v = vgruop_apply_commit_end[i].split('/') + assert (int(v[0]) <= int(v[1])) ,f"apply {v[0]} > commit {v[1]}" + + + else: tdLog.debug(tdSql.res) tdLog.notice(f"elections of {db_name} all vgroups with replica {self.db_replica} are failed in {count} s ") diff --git a/tests/system-test/6-cluster/clusterCommonCheck.py b/tests/system-test/6-cluster/clusterCommonCheck.py index f3e2b5d5bc..c42e3d918d 100644 --- a/tests/system-test/6-cluster/clusterCommonCheck.py +++ b/tests/system-test/6-cluster/clusterCommonCheck.py @@ -251,9 +251,9 @@ class ClusterComCheck: return True elif self.db_replica == 3 : - vgroup_status_first=[tdSql.queryResult[0][4],tdSql.queryResult[0][6],tdSql.queryResult[0][8]] + vgroup_status_first=[tdSql.queryResult[0][4],tdSql.queryResult[0][7],tdSql.queryResult[0][10]] - vgroup_status_last=[tdSql.queryResult[last_number][4],tdSql.queryResult[last_number][6],tdSql.queryResult[last_number][8]] + vgroup_status_last=[tdSql.queryResult[last_number][4],tdSql.queryResult[last_number][7],tdSql.queryResult[last_number][10]] 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: tdSql.query(f"select `replica` from information_schema.ins_databases where `name`='{db_name}';") From 540f8dc95d1431f1014e6862acd6deb19e66efee Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Thu, 13 Feb 2025 10:06:47 +0800 Subject: [PATCH 28/67] Fix ci problems. --- tests/script/tsim/dnode/balance3.sim | 8 +- .../drop_dnode_has_multi_vnode_replica3.sim | 32 ++-- .../dnode/drop_dnode_has_vnode_replica3.sim | 8 +- ...distribute_vgroup_replica3_v1_follower.sim | 4 +- ...redistribute_vgroup_replica3_v1_leader.sim | 4 +- tests/script/tsim/sync/3Replica1VgElect.sim | 36 ++-- tests/script/tsim/sync/3Replica5VgElect.sim | 180 +++++++++--------- .../tsim/sync/vnodesnapshot-rsma-test.sim | 12 +- tests/script/tsim/vnode/replica3_basic.sim | 24 +-- tests/script/tsim/vnode/replica3_import.sim | 20 +- tests/script/tsim/vnode/replica3_vgroup.sim | 8 +- .../0-others/information_schema.py | 2 +- tests/system-test/1-insert/alter_replica.py | 4 +- .../4dnode1mnode_basic_replica3_vgroups.py | 6 +- 14 files changed, 173 insertions(+), 175 deletions(-) diff --git a/tests/script/tsim/dnode/balance3.sim b/tests/script/tsim/dnode/balance3.sim index d0235e096e..f2363fb0f3 100644 --- a/tests/script/tsim/dnode/balance3.sim +++ b/tests/script/tsim/dnode/balance3.sim @@ -70,10 +70,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -98,10 +98,10 @@ endi if $data(3)[4] == leader then $leaderExist = 1 endi -if $data(3)[6] == leader then +if $data(3)[7] == leader then $leaderExist = 1 endi -if $data(3)[8] == leader then +if $data(3)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim index ef5001dcee..4425865bba 100644 --- a/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim +++ b/tests/script/tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim @@ -70,10 +70,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -100,10 +100,10 @@ endi if $data(3)[4] == leader then $leaderExist = 1 endi -if $data(3)[6] == leader then +if $data(3)[7] == leader then $leaderExist = 1 endi -if $data(3)[8] == leader then +if $data(3)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -130,10 +130,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -160,10 +160,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -256,10 +256,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -286,10 +286,10 @@ endi if $data(3)[4] == leader then $leaderExist = 1 endi -if $data(3)[6] == leader then +if $data(3)[7] == leader then $leaderExist = 1 endi -if $data(3)[8] == leader then +if $data(3)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -316,10 +316,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -346,10 +346,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim index 2510692846..fd99fc10ea 100644 --- a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim +++ b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim @@ -73,13 +73,13 @@ if $data(2)[4] == leader then $follower1 = 3 $follower2 = 4 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 $leaderVnode = 3 $follower1 = 2 $follower2 = 4 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 $leaderVnode = 4 $follower1 = 2 @@ -199,10 +199,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim index a576969697..ff34a8884e 100644 --- a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim +++ b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim @@ -137,13 +137,13 @@ if $data(2)[4] == leader then $follower1 = 3 $follower2 = 4 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 $leaderVnode = 3 $follower1 = 2 $follower2 = 4 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 $leaderVnode = 4 $follower1 = 2 diff --git a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim index 739e3f2984..c6ee0dfeea 100644 --- a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim +++ b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim @@ -116,13 +116,13 @@ if $data(2)[4] == leader then $follower1 = 3 $follower2 = 4 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 $leaderVnode = 3 $follower1 = 2 $follower2 = 4 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 $leaderVnode = 4 $follower1 = 2 diff --git a/tests/script/tsim/sync/3Replica1VgElect.sim b/tests/script/tsim/sync/3Replica1VgElect.sim index aae1b25636..6ebee885a8 100644 --- a/tests/script/tsim/sync/3Replica1VgElect.sim +++ b/tests/script/tsim/sync/3Replica1VgElect.sim @@ -89,20 +89,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi elif $data[0][6] == leader then - if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi @@ -225,20 +225,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi @@ -437,20 +437,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi diff --git a/tests/script/tsim/sync/3Replica5VgElect.sim b/tests/script/tsim/sync/3Replica5VgElect.sim index 37e4199e23..01bd41af42 100644 --- a/tests/script/tsim/sync/3Replica5VgElect.sim +++ b/tests/script/tsim/sync/3Replica5VgElect.sim @@ -92,20 +92,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi @@ -114,20 +114,20 @@ else endi if $data[1][4] == leader then - if $data[1][6] == follower then - if $data[1][8] == follower then + if $data[1][7] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][3] endi endi -elif $data[1][6] == leader then +elif $data[1][7] == leader then if $data[1][4] == follower then - if $data[1][8] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][5] endi endi -elif $data[1][8] == leader then +elif $data[1][10] == leader then if $data[1][4] == follower then - if $data[1][6] == follower then + if $data[1][7] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][7] endi endi @@ -136,20 +136,20 @@ else endi if $data[2][4] == leader then - if $data[2][6] == follower then - if $data[2][8] == follower then + if $data[2][7] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][3] endi endi -elif $data[2][6] == leader then +elif $data[2][7] == leader then if $data[2][4] == follower then - if $data[2][8] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][5] endi endi -elif $data[2][8] == leader then +elif $data[2][10] == leader then if $data[2][4] == follower then - if $data[2][6] == follower then + if $data[2][7] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][7] endi endi @@ -158,20 +158,20 @@ else endi if $data[3][4] == leader then - if $data[3][6] == follower then - if $data[3][8] == follower then + if $data[3][7] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][3] endi endi -elif $data[3][6] == leader then +elif $data[3][7] == leader then if $data[3][4] == follower then - if $data[3][8] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][5] endi endi -elif $data[3][8] == leader then +elif $data[3][10] == leader then if $data[3][4] == follower then - if $data[3][6] == follower then + if $data[3][7] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][7] endi endi @@ -180,20 +180,20 @@ else endi if $data[4][4] == leader then - if $data[4][6] == follower then - if $data[4][8] == follower then + if $data[4][7] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][3] endi endi -elif $data[4][6] == leader then +elif $data[4][7] == leader then if $data[4][4] == follower then - if $data[4][8] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][5] endi endi -elif $data[4][8] == leader then +elif $data[4][10] == leader then if $data[4][4] == follower then - if $data[4][6] == follower then + if $data[4][7] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][7] endi endi @@ -305,20 +305,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi @@ -327,20 +327,20 @@ else endi if $data[1][4] == leader then - if $data[1][6] == follower then - if $data[1][8] == follower then + if $data[1][7] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][3] endi endi -elif $data[1][6] == leader then +elif $data[1][7] == leader then if $data[1][4] == follower then - if $data[1][8] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][5] endi endi -elif $data[1][8] == leader then +elif $data[1][10] == leader then if $data[1][4] == follower then - if $data[1][6] == follower then + if $data[1][7] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][7] endi endi @@ -349,20 +349,20 @@ else endi if $data[2][4] == leader then - if $data[2][6] == follower then - if $data[2][8] == follower then + if $data[2][7] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][3] endi endi -elif $data[2][6] == leader then +elif $data[2][7] == leader then if $data[2][4] == follower then - if $data[2][8] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][5] endi endi -elif $data[2][8] == leader then +elif $data[2][10] == leader then if $data[2][4] == follower then - if $data[2][6] == follower then + if $data[2][7] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][7] endi endi @@ -371,20 +371,20 @@ else endi if $data[3][4] == leader then - if $data[3][6] == follower then - if $data[3][8] == follower then + if $data[3][7] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][3] endi endi -elif $data[3][6] == leader then +elif $data[3][7] == leader then if $data[3][4] == follower then - if $data[3][8] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][5] endi endi -elif $data[3][8] == leader then +elif $data[3][10] == leader then if $data[3][4] == follower then - if $data[3][6] == follower then + if $data[3][7] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][7] endi endi @@ -393,20 +393,20 @@ else endi if $data[4][4] == leader then - if $data[4][6] == follower then - if $data[4][8] == follower then + if $data[4][7] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][3] endi endi -elif $data[4][6] == leader then +elif $data[4][7] == leader then if $data[4][4] == follower then - if $data[4][8] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][5] endi endi -elif $data[4][8] == leader then +elif $data[4][10] == leader then if $data[4][4] == follower then - if $data[4][6] == follower then + if $data[4][7] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][7] endi endi @@ -607,20 +607,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi @@ -629,20 +629,20 @@ else endi if $data[1][4] == leader then - if $data[1][6] == follower then - if $data[1][8] == follower then + if $data[1][7] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][3] endi endi -elif $data[1][6] == leader then +elif $data[1][7] == leader then if $data[1][4] == follower then - if $data[1][8] == follower then + if $data[1][10] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][5] endi endi -elif $data[1][8] == leader then +elif $data[1][10] == leader then if $data[1][4] == follower then - if $data[1][6] == follower then + if $data[1][7] == follower then print ---- vgroup $data[1][0] leader locate on dnode $data[1][7] endi endi @@ -651,20 +651,20 @@ else endi if $data[2][4] == leader then - if $data[2][6] == follower then - if $data[2][8] == follower then + if $data[2][7] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][3] endi endi -elif $data[2][6] == leader then +elif $data[2][7] == leader then if $data[2][4] == follower then - if $data[2][8] == follower then + if $data[2][10] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][5] endi endi -elif $data[2][8] == leader then +elif $data[2][10] == leader then if $data[2][4] == follower then - if $data[2][6] == follower then + if $data[2][7] == follower then print ---- vgroup $data[2][0] leader locate on dnode $data[2][7] endi endi @@ -673,20 +673,20 @@ else endi if $data[3][4] == leader then - if $data[3][6] == follower then - if $data[3][8] == follower then + if $data[3][7] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][3] endi endi -elif $data[3][6] == leader then +elif $data[3][7] == leader then if $data[3][4] == follower then - if $data[3][8] == follower then + if $data[3][10] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][5] endi endi -elif $data[3][8] == leader then +elif $data[3][10] == leader then if $data[3][4] == follower then - if $data[3][6] == follower then + if $data[3][7] == follower then print ---- vgroup $data[3][0] leader locate on dnode $data[3][7] endi endi @@ -695,20 +695,20 @@ else endi if $data[4][4] == leader then - if $data[4][6] == follower then - if $data[4][8] == follower then + if $data[4][7] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][3] endi endi -elif $data[4][6] == leader then +elif $data[4][7] == leader then if $data[4][4] == follower then - if $data[4][8] == follower then + if $data[4][10] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][5] endi endi -elif $data[4][8] == leader then +elif $data[4][10] == leader then if $data[4][4] == follower then - if $data[4][6] == follower then + if $data[4][7] == follower then print ---- vgroup $data[4][0] leader locate on dnode $data[4][7] endi endi diff --git a/tests/script/tsim/sync/vnodesnapshot-rsma-test.sim b/tests/script/tsim/sync/vnodesnapshot-rsma-test.sim index 8b1720d213..d07c66bc53 100644 --- a/tests/script/tsim/sync/vnodesnapshot-rsma-test.sim +++ b/tests/script/tsim/sync/vnodesnapshot-rsma-test.sim @@ -90,20 +90,20 @@ if $rows != $vgroups then endi if $data[0][4] == leader then - if $data[0][6] == follower then - if $data[0][8] == follower then + if $data[0][7] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][3] endi endi -elif $data[0][6] == leader then +elif $data[0][7] == leader then if $data[0][4] == follower then - if $data[0][8] == follower then + if $data[0][10] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][5] endi endi -elif $data[0][8] == leader then +elif $data[0][10] == leader then if $data[0][4] == follower then - if $data[0][6] == follower then + if $data[0][7] == follower then print ---- vgroup $data[0][0] leader locate on dnode $data[0][7] endi endi diff --git a/tests/script/tsim/vnode/replica3_basic.sim b/tests/script/tsim/vnode/replica3_basic.sim index 473e53e84b..45db0df0d2 100644 --- a/tests/script/tsim/vnode/replica3_basic.sim +++ b/tests/script/tsim/vnode/replica3_basic.sim @@ -96,10 +96,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -180,10 +180,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -220,10 +220,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -260,10 +260,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -300,10 +300,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -340,10 +340,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/vnode/replica3_import.sim b/tests/script/tsim/vnode/replica3_import.sim index 99608c72e2..2840fd45a1 100644 --- a/tests/script/tsim/vnode/replica3_import.sim +++ b/tests/script/tsim/vnode/replica3_import.sim @@ -71,10 +71,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -157,10 +157,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -227,10 +227,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -275,10 +275,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -313,10 +313,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/vnode/replica3_vgroup.sim b/tests/script/tsim/vnode/replica3_vgroup.sim index 6643966344..a7a8b725b9 100644 --- a/tests/script/tsim/vnode/replica3_vgroup.sim +++ b/tests/script/tsim/vnode/replica3_vgroup.sim @@ -70,10 +70,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -83,10 +83,10 @@ $leaderExist = 0 if $data(3)[4] == leader then $leaderExist = 1 endi -if $data(3)[6] == leader then +if $data(3)[7] == leader then $leaderExist = 1 endi -if $data(3)[8] == leader then +if $data(3)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/system-test/0-others/information_schema.py b/tests/system-test/0-others/information_schema.py index 390bf3d9dd..012f5d6eec 100644 --- a/tests/system-test/0-others/information_schema.py +++ b/tests/system-test/0-others/information_schema.py @@ -222,7 +222,7 @@ class TDTestCase: tdSql.query("select * from information_schema.ins_columns where db_name ='information_schema'") tdLog.info(len(tdSql.queryResult)) - tdSql.checkEqual(True, len(tdSql.queryResult) in range(312, 313)) + tdSql.checkEqual(True, len(tdSql.queryResult) in range(318, 319)) tdSql.query("select * from information_schema.ins_columns where db_name ='performance_schema'") tdSql.checkEqual(61, len(tdSql.queryResult)) diff --git a/tests/system-test/1-insert/alter_replica.py b/tests/system-test/1-insert/alter_replica.py index 900b64d943..6d364618ee 100644 --- a/tests/system-test/1-insert/alter_replica.py +++ b/tests/system-test/1-insert/alter_replica.py @@ -27,8 +27,8 @@ class TDTestCase: flag = 0 for vgid in range (vgNum) : v1_status = tdSql.queryResult[vgid][4] - v2_status = tdSql.queryResult[vgid][6] - v3_status = tdSql.queryResult[vgid][8] + v2_status = tdSql.queryResult[vgid][7] + v3_status = tdSql.queryResult[vgid][10] if ((v1_status == 'leader') and (v2_status == 'follower') and (v3_status == 'follower')) \ or ((v2_status == 'leader') and (v1_status == 'follower') and (v3_status == 'follower')) \ or ((v3_status == 'leader') and (v2_status == 'follower') and (v1_status == 'follower')): diff --git a/tests/system-test/6-cluster/vnode/4dnode1mnode_basic_replica3_vgroups.py b/tests/system-test/6-cluster/vnode/4dnode1mnode_basic_replica3_vgroups.py index 4f3b2e2def..5f2a54739c 100644 --- a/tests/system-test/6-cluster/vnode/4dnode1mnode_basic_replica3_vgroups.py +++ b/tests/system-test/6-cluster/vnode/4dnode1mnode_basic_replica3_vgroups.py @@ -135,11 +135,9 @@ class TDTestCase: vgroup_id = vgroup_info[0] vgroup_status = [] for ind , role in enumerate(vgroup_info[3:-4]): - - if ind%2==0: - continue - else: + if role in ['leader', 'leader*', 'leader**', 'follower']: vgroup_status.append(role) + if vgroup_status.count("leader")!=1 or vgroup_status.count("follower")!=2: status = False return status From b55980d71dc4c70b04f2c5940f0e35d6338fc543 Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Thu, 13 Feb 2025 10:16:09 +0800 Subject: [PATCH 29/67] fix some thread sync problem --- source/client/inc/clientStmt2.h | 21 ++++++++----- source/client/src/clientMain.c | 27 +++++++++++----- source/client/src/clientStmt2.c | 52 ++++++++++++++++++++++++++++--- source/client/test/stmt2Test.cpp | 53 +++++++++++++++----------------- 4 files changed, 104 insertions(+), 49 deletions(-) diff --git a/source/client/inc/clientStmt2.h b/source/client/inc/clientStmt2.h index e55d9a048f..feec9ec337 100644 --- a/source/client/inc/clientStmt2.h +++ b/source/client/inc/clientStmt2.h @@ -134,6 +134,12 @@ uint64_t qRemainNum; } SStmtQueue; */ +typedef struct AsyncBindParam { + TdThreadMutex mutex; + TdThreadCond waitCond; + uint8_t asyncBindNum; +} AsyncBindParam; + typedef struct { STscObj *taos; SCatalog *pCatalog; @@ -150,14 +156,13 @@ typedef struct { SStmtExecInfo exec; SStmtBindInfo bInfo; - char *db; - int64_t reqid; - int32_t errCode; - tsem_t asyncExecSem; - bool execSemWaited; - tsem_t asyncBindSem; - bool bindSemWaited; - SStmtStatInfo stat; + char *db; + int64_t reqid; + int32_t errCode; + tsem_t asyncExecSem; + bool execSemWaited; + AsyncBindParam asyncBindParam; + SStmtStatInfo stat; } STscStmt2; /* extern char *gStmtStatusStr[]; diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index c472be8bc8..ba67ff7f76 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -2166,6 +2166,11 @@ int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col } STscStmt2 *pStmt = (STscStmt2 *)stmt; + if( atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum)>1) { + tscError("async bind param is still working, please try again later"); + return TSDB_CODE_TSC_STMT_API_ERROR; + } + if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) { if (tsem_wait(&pStmt->asyncExecSem) != 0) { tscError("wait asyncExecSem failed"); @@ -2173,13 +2178,6 @@ int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col pStmt->execSemWaited = true; } - if (!pStmt->bindSemWaited) { - if (tsem_wait(&pStmt->asyncBindSem) != 0) { - tscError("wait asyncBindSem failed"); - } - pStmt->bindSemWaited = true; - } - SSHashObj *hashTbnames = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR)); if (NULL == hashTbnames) { tscError("stmt2 bind failed: %s", tstrerror(terrno)); @@ -2252,7 +2250,20 @@ out: int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, void *param) { - return stmt2AsyncBind(stmt, bindv,col_idx, fp, param); + if (stmt == NULL || bindv == NULL || fp == NULL) { + terrno = TSDB_CODE_INVALID_PARA; + return terrno; + } + + STscStmt2 *pStmt = (STscStmt2 *)stmt; + (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1); + int code = stmt2AsyncBind(stmt, bindv, col_idx, fp, param); + if (code != TSDB_CODE_SUCCESS) { + (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1); + // terrno = TAOS_SYSTEM_ERROR(errno); + } + + return code; } int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) { diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 5c8e2655e6..597ec95f23 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -752,6 +752,14 @@ static int32_t stmtInitQueue(STscStmt2* pStmt) { return TSDB_CODE_SUCCESS; } +static int32_t stmtIniAsyncBind(STscStmt2* pStmt) { + (void)taosThreadCondInit(&pStmt->asyncBindParam.waitCond, NULL); + (void)taosThreadMutexInit(&pStmt->asyncBindParam.mutex, NULL); + pStmt->asyncBindParam.asyncBindNum = 0; + + return TSDB_CODE_SUCCESS; +} + static int32_t stmtInitTableBuf(STableBufInfo* pTblBuf) { pTblBuf->buffUnit = sizeof(SStmtQNode); pTblBuf->buffSize = pTblBuf->buffUnit * 1000; @@ -812,13 +820,13 @@ TAOS_STMT2* stmtInit2(STscObj* taos, TAOS_STMT2_OPTION* pOptions) { pStmt->sql.siInfo.mgmtEpSet = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp); pStmt->sql.siInfo.pTableHash = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY)); if (NULL == pStmt->sql.siInfo.pTableHash) { - (void)stmtClose(pStmt); + (void)stmtClose2(pStmt); return NULL; } pStmt->sql.siInfo.pTableCols = taosArrayInit(STMT_TABLE_COLS_NUM, POINTER_BYTES); if (NULL == pStmt->sql.siInfo.pTableCols) { terrno = terrno; - (void)stmtClose(pStmt); + (void)stmtClose2(pStmt); return NULL; } @@ -831,7 +839,7 @@ TAOS_STMT2* stmtInit2(STscObj* taos, TAOS_STMT2_OPTION* pOptions) { } if (TSDB_CODE_SUCCESS != code) { terrno = code; - (void)stmtClose(pStmt); + (void)stmtClose2(pStmt); return NULL; } } @@ -840,10 +848,17 @@ TAOS_STMT2* stmtInit2(STscObj* taos, TAOS_STMT2_OPTION* pOptions) { if (pStmt->options.asyncExecFn) { if (tsem_init(&pStmt->asyncExecSem, 0, 1) != 0) { terrno = TAOS_SYSTEM_ERROR(errno); - (void)stmtClose(pStmt); + (void)stmtClose2(pStmt); return NULL; } } + code = stmtIniAsyncBind(pStmt); + if (TSDB_CODE_SUCCESS != code) { + terrno = code; + (void)stmtClose2(pStmt); + return NULL; + } + pStmt->execSemWaited = false; STMT_LOG_SEQ(STMT_INIT); @@ -1675,6 +1690,12 @@ int stmtExec2(TAOS_STMT2* stmt, int* affected_rows) { return pStmt->errCode; } + taosThreadMutexLock(&pStmt->asyncBindParam.mutex); + if (atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum) > 0) { + (void)taosThreadCondWait(&pStmt->asyncBindParam.waitCond, &pStmt->asyncBindParam.mutex); + } + taosThreadMutexUnlock(&pStmt->asyncBindParam.mutex); + if (pStmt->sql.stbInterlaceMode) { STMT_ERR_RET(stmtAddBatch2(pStmt)); } @@ -1775,9 +1796,17 @@ int stmtClose2(TAOS_STMT2* stmt) { pStmt->bindThreadInUse = false; } + taosThreadMutexLock(&pStmt->asyncBindParam.mutex); + if (atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum) > 0) { + (void)taosThreadCondWait(&pStmt->asyncBindParam.waitCond, &pStmt->asyncBindParam.mutex); + } + taosThreadMutexUnlock(&pStmt->asyncBindParam.mutex); (void)taosThreadCondDestroy(&pStmt->queue.waitCond); (void)taosThreadMutexDestroy(&pStmt->queue.mutex); + (void)taosThreadCondDestroy(&pStmt->asyncBindParam.waitCond); + (void)taosThreadMutexDestroy(&pStmt->asyncBindParam.mutex); + if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) { if (tsem_wait(&pStmt->asyncExecSem) != 0) { tscError("failed to wait asyncExecSem"); @@ -1937,17 +1966,32 @@ typedef struct { } ThreadArgs; static void* stmtAsyncBindThreadFunc(void* args) { + setThreadName("stmtAsyncBind"); + + qInfo("async stmt bind thread started"); + ThreadArgs* targs = (ThreadArgs*)args; + STscStmt2* pStmt = (STscStmt2*)targs->stmt; int code = taos_stmt2_bind_param(targs->stmt, targs->bindv, targs->col_idx); targs->fp(targs->param, NULL, code); + (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex)); + (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1); + (void)taosThreadCondSignal(&(pStmt->asyncBindParam.waitCond)); + (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex)); taosMemoryFree(args); + qInfo("async stmt bind thread stopped"); + return NULL; } int stmt2AsyncBind(TAOS_STMT2* stmt, TAOS_STMT2_BINDV* bindv, int32_t col_idx, __taos_async_fn_t fp, void* param) { STscStmt2* pStmt = (STscStmt2*)stmt; + if (atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum) > 1) { + tscError("async bind param is still working, please try again later"); + return TSDB_CODE_TSC_STMT_API_ERROR; + } TdThreadAttr thAttr; if (taosThreadAttrInit(&thAttr) != 0) { diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index 95a7ecd8f7..6062189602 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -255,48 +255,41 @@ TEST(stmt2Case, stmt2_test_limit) { do_query(taos, "create database IF NOT EXISTS stmt2_testdb_7"); do_query(taos, "create stable stmt2_testdb_7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); do_query(taos, - "insert into stmt2_testdb_7.tb2 using stmt2_testdb_7.stb tags(2,'xyz') values(1591060628000, " - "'abc'),(1591060628001,'def'),(1591060628004, 'hij')"); + "insert into stmt2_testdb_7.tb2 using stmt2_testdb_7.stb tags(2,'xyz') values(1591060628000, " + "'abc'),(1591060628001,'def'),(1591060628004, 'hij')"); do_query(taos, "use stmt2_testdb_7"); - TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); ASSERT_NE(stmt, nullptr); - const char* sql = "select * from stmt2_testdb_7.tb2 where ts > ? and ts < ? limit ?"; - int code = taos_stmt2_prepare(stmt, sql, 0); + int code = taos_stmt2_prepare(stmt, sql, 0); checkError(stmt, code); - - int t64_len[1] = {sizeof(int64_t)}; - int b_len[1] = {3}; - int x = 2; - int x_len = sizeof(int); - int64_t ts[2] = {1591060627000, 1591060628005}; - TAOS_STMT2_BIND params[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], t64_len, NULL, 1}, - {TSDB_DATA_TYPE_TIMESTAMP, &ts[1], t64_len, NULL, 1}, - {TSDB_DATA_TYPE_INT, &x, &x_len, NULL, 1}}; + int t64_len[1] = {sizeof(int64_t)}; + int b_len[1] = {3}; + int x = 2; + int x_len = sizeof(int); + int64_t ts[2] = {1591060627000, 1591060628005}; + TAOS_STMT2_BIND params[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], t64_len, NULL, 1}, + {TSDB_DATA_TYPE_TIMESTAMP, &ts[1], t64_len, NULL, 1}, + {TSDB_DATA_TYPE_INT, &x, &x_len, NULL, 1}}; TAOS_STMT2_BIND* paramv = ¶ms[0]; TAOS_STMT2_BINDV bindv = {1, NULL, NULL, ¶mv}; code = taos_stmt2_bind_param(stmt, &bindv, -1); checkError(stmt, code); - taos_stmt2_exec(stmt, NULL); checkError(stmt, code); - TAOS_RES* pRes = taos_stmt2_result(stmt); ASSERT_NE(pRes, nullptr); - int getRecordCounts = 0; while ((taos_fetch_row(pRes))) { - getRecordCounts++; + getRecordCounts++; } ASSERT_EQ(getRecordCounts, 2); taos_stmt2_close(stmt); @@ -304,7 +297,6 @@ TEST(stmt2Case, stmt2_test_limit) { taos_close(taos); } - TEST(stmt2Case, insert_stb_get_fields_Test) { TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(taos, nullptr); @@ -1619,20 +1611,24 @@ TEST(stmt2Case, errcode) { } void stmtAsyncBindCb(void* param, TAOS_RES* pRes, int code) { - if (code != TSDB_CODE_SUCCESS) { - taos_errstr(pRes); - } ASSERT_EQ(code, TSDB_CODE_SUCCESS); + taosMsleep(500); + return; +} + +void stmtAsyncQueryCb2(void* param, TAOS_RES* pRes, int code) { + ASSERT_EQ(code, TSDB_CODE_SUCCESS); + taosMsleep(500); return; } TEST(stmt2Case, async_order) { int CTB_NUMS = 3; int ROW_NUMS = 3; - int CYC_NUMS = 3; + int CYC_NUMS = 1; TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); - TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb, NULL}; + TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb2, NULL}; char* sql = "insert into ? values(?,?)"; do_query(taos, "drop database if exists stmt2_testdb_15"); @@ -1687,15 +1683,14 @@ TEST(stmt2Case, async_order) { } // bind TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; - // code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, NULL); - code = taos_stmt2_bind_param(stmt, &bindv, -1); + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, NULL); + // code = taos_stmt2_bind_param(stmt, &bindv, -1); checkError(stmt, code); // exec int affected = 0; code = taos_stmt2_exec(stmt, &affected); - total_affected += affected; checkError(stmt, code); for (int i = 0; i < CTB_NUMS; i++) { @@ -1709,7 +1704,7 @@ TEST(stmt2Case, async_order) { taosMemoryFree(b_len); taosMemoryFree(paramv); } - ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS); + // ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS); // case 2 : bind_a->bind_a->bind_a->exec_a->... // case 3 : bind->exec_a->bind->exec_a->... From b0bf9bb5020fb9cd8e936d8cf22a219d190f3232 Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Thu, 13 Feb 2025 11:02:11 +0800 Subject: [PATCH 30/67] add unit test async stmt order --- source/client/test/stmt2Test.cpp | 239 +++++++++++++++++++++++-------- 1 file changed, 179 insertions(+), 60 deletions(-) diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index 6062189602..407c8745a5 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -37,7 +37,7 @@ namespace { void checkError(TAOS_STMT2* stmt, int code) { if (code != TSDB_CODE_SUCCESS) { STscStmt2* pStmt = (STscStmt2*)stmt; - if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr) { + if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr || pStmt->exec.pRequest == nullptr) { printf("stmt api error\n stats : %d\n errstr : %s\n", pStmt->sql.status, taos_stmt_errstr(stmt)); } else { printf("stmt api error\n sql : %s\n stats : %d\n errstr : %s\n", pStmt->sql.sqlStr, pStmt->sql.status, @@ -1611,8 +1611,10 @@ TEST(stmt2Case, errcode) { } void stmtAsyncBindCb(void* param, TAOS_RES* pRes, int code) { + bool* finish = (bool*)param; ASSERT_EQ(code, TSDB_CODE_SUCCESS); taosMsleep(500); + *finish = true; return; } @@ -1622,10 +1624,17 @@ void stmtAsyncQueryCb2(void* param, TAOS_RES* pRes, int code) { return; } +void stmtAsyncBindCb2(void* param, TAOS_RES* pRes, int code) { + bool* finish = (bool*)param; + taosMsleep(500); + *finish = true; + return; +} + TEST(stmt2Case, async_order) { - int CTB_NUMS = 3; - int ROW_NUMS = 3; - int CYC_NUMS = 1; + int CTB_NUMS = 2; + int ROW_NUMS = 2; + int CYC_NUMS = 2; TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb2, NULL}; @@ -1651,72 +1660,182 @@ TEST(stmt2Case, async_order) { sprintf(tmp, "create table stmt2_testdb_15.%s using stmt2_testdb_15.stb tags(0, 'after')", tbs[i]); do_query(taos, tmp); } + // params + TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); + // col params + int64_t** ts = (int64_t**)taosMemoryMalloc(CTB_NUMS * sizeof(int64_t*)); + char** b = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*)); + int* ts_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); + int* b_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); + for (int i = 0; i < ROW_NUMS; i++) { + ts_len[i] = sizeof(int64_t); + b_len[i] = 1; + } + for (int i = 0; i < CTB_NUMS; i++) { + ts[i] = (int64_t*)taosMemoryMalloc(ROW_NUMS * sizeof(int64_t)); + b[i] = (char*)taosMemoryMalloc(ROW_NUMS * sizeof(char)); + for (int j = 0; j < ROW_NUMS; j++) { + ts[i][j] = 1591060628000 + 100000 + j; + b[i][j] = 'a' + j; + } + } + // bind params + for (int i = 0; i < CTB_NUMS; i++) { + // create col params + paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); + paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS}; + paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS}; + } // case 1 : bind_a->exec_a->bind_a->exec_a->... - for (int r = 0; r < CYC_NUMS; r++) { - // col params - int64_t** ts = (int64_t**)taosMemoryMalloc(CTB_NUMS * sizeof(int64_t*)); - char** b = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*)); - int* ts_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); - int* b_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int)); - for (int i = 0; i < ROW_NUMS; i++) { - ts_len[i] = sizeof(int64_t); - b_len[i] = 1; + { + printf("case 1 : bind_a->exec_a->bind_a->exec_a->...\n"); + for (int r = 0; r < CYC_NUMS; r++) { + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish); + + checkError(stmt, code); + + // exec + code = taos_stmt2_exec(stmt, NULL); + checkError(stmt, code); } - for (int i = 0; i < CTB_NUMS; i++) { - ts[i] = (int64_t*)taosMemoryMalloc(ROW_NUMS * sizeof(int64_t)); - b[i] = (char*)taosMemoryMalloc(ROW_NUMS * sizeof(char)); - for (int j = 0; j < ROW_NUMS; j++) { - ts[i][j] = 1591060628000 + r * 100000 + j; - b[i][j] = 'a' + j; - } - } - - // bind params - TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); - - for (int i = 0; i < CTB_NUMS; i++) { - // create col params - paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); - paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS}; - paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS}; - } - // bind - TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; - code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, NULL); - // code = taos_stmt2_bind_param(stmt, &bindv, -1); - - checkError(stmt, code); - - // exec - int affected = 0; - code = taos_stmt2_exec(stmt, &affected); - checkError(stmt, code); - - for (int i = 0; i < CTB_NUMS; i++) { - taosMemoryFree(paramv[i]); - taosMemoryFree(ts[i]); - taosMemoryFree(b[i]); - } - taosMemoryFree(ts); - taosMemoryFree(b); - taosMemoryFree(ts_len); - taosMemoryFree(b_len); - taosMemoryFree(paramv); } - // ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS); // case 2 : bind_a->bind_a->bind_a->exec_a->... - // case 3 : bind->exec_a->bind->exec_a->... - // case 4 : bind_a->exec->bind_a->exec->... - // case 5 : bind_a->close - // case 6 : exec_a->close + { + printf("case 2 : bind_a->bind_a->bind_a->exec_a->...\n"); + for (int r = 0; r < CYC_NUMS; r++) { + // bind params + TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); + for (int i = 0; i < CTB_NUMS; i++) { + // create col params + paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); + paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS}; + paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS}; + } + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish); + while (!finish) { + taosMsleep(100); + } + checkError(stmt, code); + } + // exec + code = taos_stmt2_exec(stmt, NULL); + checkError(stmt, code); + } + // case 3 : bind->exec_a->bind->exec_a->... + { + printf("case 3 : bind->exec_a->bind->exec_a->...\n"); + for (int r = 0; r < CYC_NUMS; r++) { + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + + checkError(stmt, code); + + // exec + code = taos_stmt2_exec(stmt, NULL); + checkError(stmt, code); + } + } + + // case 4 : bind_a->close + { + printf("case 4 : bind_a->close\n"); + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish); + checkError(stmt, code); + taos_stmt2_close(stmt); + checkError(stmt, code); + } + + // case 5 : bind_a->exec_a->close + { + printf("case 5 : bind_a->exec_a->close\n"); + // init + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code); + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish); + checkError(stmt, code); + // exec + code = taos_stmt2_exec(stmt, NULL); + checkError(stmt, code); + // close + taos_stmt2_close(stmt); + checkError(stmt, code); + } + + option = {0, false, false, NULL, NULL}; + stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code); + + // case 6 : bind_a->exec->bind_a->exec->... + { + printf("case 6 : bind_a->exec->bind_a->exec->...\n"); + // init + + checkError(stmt, code); + for (int r = 0; r < CYC_NUMS; r++) { + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish); + checkError(stmt, code); + // exec + code = taos_stmt2_exec(stmt, NULL); + checkError(stmt, code); + } + } + + // case 7 (error:no wait error) : bind_a->bind_a + { + printf("case 7 (error:no wait error) : bind_a->bind_a\n"); + // bind + TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv}; + bool finish = false; + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb2, (void*)&finish); + checkError(stmt, code); + taosMsleep(200); + code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb2, (void*)&finish); + ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR); + while (!finish) { + taosMsleep(100); + } + } + // close + taos_stmt2_close(stmt); + + // free memory + for (int i = 0; i < CTB_NUMS; i++) { + taosMemoryFree(paramv[i]); + taosMemoryFree(ts[i]); + taosMemoryFree(b[i]); + } + taosMemoryFree(ts); + taosMemoryFree(b); + taosMemoryFree(ts_len); + taosMemoryFree(b_len); + taosMemoryFree(paramv); for (int i = 0; i < CTB_NUMS; i++) { taosMemoryFree(tbs[i]); } taosMemoryFree(tbs); - - taos_stmt2_close(stmt); } #pragma GCC diagnostic pop From daea0ec61aa38aa2cb2b9352f375b4ee4d0752f5 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 13 Feb 2025 13:54:54 +0800 Subject: [PATCH 31/67] fix:[TS-5776]add raw type from consumer --- source/client/src/clientRawBlockWrite.c | 6 +++--- source/dnode/vnode/src/inc/tq.h | 2 +- source/dnode/vnode/src/tq/tqRead.c | 26 ++++++++++++------------- source/dnode/vnode/src/tq/tqScan.c | 9 +++------ source/dnode/vnode/src/tq/tqUtil.c | 5 ++++- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 7f3a696f26..1ae4bd195c 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -2173,7 +2173,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) { void* rawData = getRawDataFromRes(pRetrieve); RAW_NULL_CHECK(rawData); - uDebug(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); + uTrace(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); SName pName = {TSDB_TABLE_NAME_T, pRequest->pTscObj->acctId, {0}, {0}}; tstrncpy(pName.dbname, pRequest->pDb, TSDB_DB_NAME_LEN); tstrncpy(pName.tname, tbName, TSDB_TABLE_NAME_LEN); @@ -2256,7 +2256,7 @@ static int32_t tmqWriteRawMetaDataImpl(TAOS* taos, void* data, uint32_t dataLen) void* rawData = getRawDataFromRes(pRetrieve); RAW_NULL_CHECK(rawData); - uDebug(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); + uTrace(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); SName pName = {TSDB_TABLE_NAME_T, pRequest->pTscObj->acctId, {0}, {0}}; tstrncpy(pName.dbname, pRequest->pDb, TSDB_DB_NAME_LEN); tstrncpy(pName.tname, tbName, TSDB_TABLE_NAME_LEN); @@ -2344,7 +2344,7 @@ static int32_t tmqWriteRawRawDataImpl(TAOS* taos, void* data, uint32_t dataLen) void* rawData = getRawDataFromRes(pRetrieve); RAW_NULL_CHECK(rawData); - uDebug(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); + uTrace(LOG_ID_TAG " write raw data block tbname:%s", LOG_ID_VALUE, tbName); SName pName = {TSDB_TABLE_NAME_T, pRequest->pTscObj->acctId, {0}, {0}}; tstrncpy(pName.dbname, pRequest->pDb, TSDB_DB_NAME_LEN); tstrncpy(pName.tname, tbName, TSDB_TABLE_NAME_LEN); diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index ec82fd8e71..2c06ff1f07 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -183,7 +183,7 @@ int32_t tqSendAllNotifyEvents(const SArray* pBlocks, SStreamTask* pTask, SVnode* #define TQ_SUBSCRIBE_NAME "subscribe" #define TQ_OFFSET_NAME "offset-ver0" #define TQ_POLL_MAX_TIME 1000 -#define TQ_POLL_MAX_BYTES 10485760 +#define TQ_POLL_MAX_BYTES 1048576 #ifdef __cplusplus } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 796a4a8742..792763862b 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -500,7 +500,7 @@ int32_t tqReaderSetSubmitMsg(STqReader* pReader, void* msgStr, int32_t msgLen, i pReader->msg.msgLen = msgLen; pReader->msg.ver = ver; - tqDebug("tq reader set msg pointer:%p, msg len:%d", msgStr, msgLen); + tqTrace("tq reader set msg pointer:%p, msg len:%d", msgStr, msgLen); SDecoder decoder = {0}; tDecoderInit(&decoder, pReader->msg.msgStr, pReader->msg.msgLen); @@ -558,15 +558,15 @@ bool tqNextBlockImpl(STqReader* pReader, const char* idstr) { void* ret = taosHashGet(pReader->tbIdHash, &pSubmitTbData->uid, sizeof(int64_t)); TSDB_CHECK_CONDITION(ret == NULL, code, lino, END, true); - tqDebug("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); + tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); pReader->nextBlk++; } tqReaderClearSubmitMsg(pReader); - tqDebug("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); + tqTrace("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); END: - tqDebug("%s:%d return:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); + tqTrace("%s:%d return:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); return code; } @@ -586,14 +586,14 @@ bool tqNextDataBlockFilterOut(STqReader* pReader, SHashObj* filterOutUids) { uid = pSubmitTbData->uid; void* ret = taosHashGet(filterOutUids, &pSubmitTbData->uid, sizeof(int64_t)); TSDB_CHECK_NULL(ret, code, lino, END, true); - tqDebug("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); + tqTrace("iterator data block in hash jump block, progress:%d/%d, uid:%" PRId64 "", pReader->nextBlk, blockSz, uid); pReader->nextBlk++; } tqReaderClearSubmitMsg(pReader); - tqDebug("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); + tqTrace("iterator data block end, total block num:%d, uid:%"PRId64, blockSz, uid); END: - tqDebug("%s:%d get data:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); + tqTrace("%s:%d get data:%s, uid:%"PRId64, __FUNCTION__, lino, code?"true":"false", uid); return code; } @@ -936,7 +936,7 @@ static int32_t tqProcessColData(STqReader* pReader, SSubmitTbData* pSubmitTbData TQ_NULL_GO_TO_END(pCol); int32_t numOfRows = pCol->nVal; int32_t numOfCols = taosArrayGetSize(pCols); - tqDebug("vgId:%d, tqProcessColData start, col num: %d, rows:%d", pReader->pWalReader->pWal->cfg.vgId, numOfCols, numOfRows); + tqTrace("vgId:%d, tqProcessColData start, col num: %d, rows:%d", pReader->pWalReader->pWal->cfg.vgId, numOfCols, numOfRows); for (int32_t i = 0; i < numOfRows; i++) { bool buildNew = false; @@ -976,7 +976,7 @@ static int32_t tqProcessColData(STqReader* pReader, SSubmitTbData* pSubmitTbData } SSDataBlock* pLastBlock = taosArrayGetLast(blocks); pLastBlock->info.rows = curRow - lastRow; - tqDebug("vgId:%d, tqProcessColData end, col num: %d, rows:%d, block num:%d", pReader->pWalReader->pWal->cfg.vgId, numOfCols, numOfRows, (int)taosArrayGetSize(blocks)); + tqTrace("vgId:%d, tqProcessColData end, col num: %d, rows:%d, block num:%d", pReader->pWalReader->pWal->cfg.vgId, numOfCols, numOfRows, (int)taosArrayGetSize(blocks)); END: if (code != TSDB_CODE_SUCCESS) { tqError("vgId:%d, process col data failed, code:%d", pReader->pWalReader->pWal->cfg.vgId, code); @@ -999,7 +999,7 @@ int32_t tqProcessRowData(STqReader* pReader, SSubmitTbData* pSubmitTbData, SArra int32_t numOfRows = taosArrayGetSize(pRows); pTSchema = tBuildTSchema(pSchemaWrapper->pSchema, pSchemaWrapper->nCols, pSchemaWrapper->version); TQ_NULL_GO_TO_END(pTSchema); - tqDebug("vgId:%d, tqProcessRowData start, rows:%d", pReader->pWalReader->pWal->cfg.vgId, numOfRows); + tqTrace("vgId:%d, tqProcessRowData start, rows:%d", pReader->pWalReader->pWal->cfg.vgId, numOfRows); for (int32_t i = 0; i < numOfRows; i++) { bool buildNew = false; @@ -1038,7 +1038,7 @@ int32_t tqProcessRowData(STqReader* pReader, SSubmitTbData* pSubmitTbData, SArra SSDataBlock* pLastBlock = taosArrayGetLast(blocks); pLastBlock->info.rows = curRow - lastRow; - tqDebug("vgId:%d, tqProcessRowData end, rows:%d, block num:%d", pReader->pWalReader->pWal->cfg.vgId, numOfRows, (int)taosArrayGetSize(blocks)); + tqTrace("vgId:%d, tqProcessRowData end, rows:%d, block num:%d", pReader->pWalReader->pWal->cfg.vgId, numOfRows, (int)taosArrayGetSize(blocks)); END: if (code != TSDB_CODE_SUCCESS) { tqError("vgId:%d, process row data failed, code:%d", pReader->pWalReader->pWal->cfg.vgId, code); @@ -1076,7 +1076,7 @@ static int32_t buildCreateTbInfo(SMqDataRsp* pRsp, SVCreateTbReq* pCreateTbReq){ TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableLen, &len), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->createTableReq, &createReq), code, lino, END, terrno); pRsp->createTableNum++; - tqDebug("build create table info msg success"); + tqTrace("build create table info msg success"); END: if (code != 0){ @@ -1087,7 +1087,7 @@ static int32_t buildCreateTbInfo(SMqDataRsp* pRsp, SVCreateTbReq* pCreateTbReq){ } int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* blocks, SArray* schemas, SSubmitTbData** pSubmitTbDataRet, SArray* rawList, int8_t fetchMeta) { - tqDebug("tq reader retrieve data block msg pointer:%p, index:%d", pReader->msg.msgStr, pReader->nextBlk); + tqTrace("tq reader retrieve data block msg pointer:%p, index:%d", pReader->msg.msgStr, pReader->nextBlk); SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, pReader->nextBlk); if (pSubmitTbData == NULL) { return terrno; diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 941e74fd9b..265e165038 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -31,11 +31,8 @@ static int32_t tqAddRawDataToRsp(const void* rawData, SMqDataRsp* pRsp, int8_t p memcpy(pRetrieve->data, rawData, *(uint32_t *)rawData + INT_BYTES); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &dataStrLen), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); -// for (int m= 0; m < 56; m++){ -// printf("add data[%d] = %d\n", m, *((int8_t *)rawData+m)); -// } - tqDebug("add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); + tqTrace("add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); END: if (code != TSDB_CODE_SUCCESS) { taosMemoryFree(buf); @@ -95,7 +92,7 @@ static int32_t tqAddTbNameToRsp(const STQ* pTq, int64_t uid, SMqDataRsp* pRsp, i tqError("failed to push tbName to blockTbName:%s, uid:%"PRId64, tbName, uid); continue; } - tqDebug("add tbName to response success tbname:%s, uid:%"PRId64, tbName, uid); + tqTrace("add tbName to response success tbname:%s, uid:%"PRId64, tbName, uid); } END: @@ -399,7 +396,7 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int *pSW = NULL; pRsp->blockNum++; } - tqDebug("vgId:%d, process sub data success, response blocknum:%d, rows:%d", pTq->pVnode->config.vgId, pRsp->blockNum, *totalRows); + tqTrace("vgId:%d, process sub data success, response blocknum:%d, rows:%d", pTq->pVnode->config.vgId, pRsp->blockNum, *totalRows); END: if (code != 0) { tqError("%s failed at %d, failed to process sub data:%s", __FUNCTION__, lino, tstrerror(code)); diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index bb6751c883..5dd8de9429 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -378,7 +378,10 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if ((pRequest->rawData == 0 && totalRows >= tmqRowSize) || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout)) || - (pRequest->rawData != 0 && (totalRows >= TQ_POLL_MAX_BYTES || taosxRsp.createTableNum > 0 || terrno == TSDB_CODE_TMQ_DUPLICATE_UID))) { + (pRequest->rawData != 0 && (totalRows >= TQ_POLL_MAX_BYTES || + taosxRsp.createTableNum > 0 || + taosArrayGetSize(taosxRsp.blockData) > tmqRowSize || + terrno == TSDB_CODE_TMQ_DUPLICATE_UID))) { tqOffsetResetToLog(&taosxRsp.rspOffset, terrno == TSDB_CODE_TMQ_DUPLICATE_UID ? fetchVer : fetchVer + 1); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, POLL_RSP_TYPE(pRequest, taosxRsp), vgId); From 3440006c8435914d6c8863f118eaf4ad2bb7bf53 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 13 Feb 2025 13:57:08 +0800 Subject: [PATCH 32/67] fix:[TS-5776]add raw type from consumer --- tests/system-test/7-tmq/taosx-performance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 997c6ec096..8a9e2bbe83 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -65,7 +65,7 @@ insertJson = '''{ "child_table_exists": "no", "childtable_count": 10000, "childtable_prefix": "d", - "auto_create_table": "no", + "auto_create_table": "yes", "batch_create_tbl_num": 500, "data_source": "rand", "insert_mode": "taosc", From 0cd153aa887430c67d8cec3ee54b2e8a835ee50b Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Thu, 13 Feb 2025 14:10:24 +0800 Subject: [PATCH 33/67] Fix ci problems. --- .../tsim/dnode/drop_dnode_has_vnode_replica3.sim | 4 ++-- .../dnode/redistribute_vgroup_replica3_v2.sim | 4 ++-- tests/script/tsim/vnode/replica3_many.sim | 16 ++++++++-------- tests/script/tsim/vnode/replica3_repeat.sim | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim index fd99fc10ea..9c6abe536b 100644 --- a/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim +++ b/tests/script/tsim/dnode/drop_dnode_has_vnode_replica3.sim @@ -109,10 +109,10 @@ endi if $data(2)[3] != 2 then return -1 endi -if $data(2)[5] != 3 then +if $data(2)[6] != 3 then return -1 endi -if $data(2)[7] != 4 then +if $data(2)[9] != 4 then return -1 endi diff --git a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v2.sim b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v2.sim index 652f0c14b4..ae0b60c943 100644 --- a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v2.sim +++ b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v2.sim @@ -122,13 +122,13 @@ if $data(2)[4] == leader then $follower1 = 3 $follower2 = 4 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 $leaderVnode = 3 $follower1 = 2 $follower2 = 4 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 $leaderVnode = 4 $follower1 = 2 diff --git a/tests/script/tsim/vnode/replica3_many.sim b/tests/script/tsim/vnode/replica3_many.sim index e3c73b2018..930eebc688 100644 --- a/tests/script/tsim/vnode/replica3_many.sim +++ b/tests/script/tsim/vnode/replica3_many.sim @@ -68,10 +68,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -96,10 +96,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -121,10 +121,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -146,10 +146,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/vnode/replica3_repeat.sim b/tests/script/tsim/vnode/replica3_repeat.sim index 10e18d01d0..defee0fe0a 100644 --- a/tests/script/tsim/vnode/replica3_repeat.sim +++ b/tests/script/tsim/vnode/replica3_repeat.sim @@ -62,10 +62,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then From f09dd39f8999ce64ecbdea0baadd753f252f70b2 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Thu, 13 Feb 2025 18:24:14 +0800 Subject: [PATCH 34/67] Fix ci problems. --- tests/script/tsim/dnode/balance_replica3.sim | 28 ++++++++++---------- tests/script/tsim/vnode/replica3_basic.sim | 4 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/script/tsim/dnode/balance_replica3.sim b/tests/script/tsim/dnode/balance_replica3.sim index afd7603b16..37b4a6beca 100644 --- a/tests/script/tsim/dnode/balance_replica3.sim +++ b/tests/script/tsim/dnode/balance_replica3.sim @@ -75,10 +75,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -105,10 +105,10 @@ endi if $data(3)[4] == leader then $leaderExist = 1 endi -if $data(3)[6] == leader then +if $data(3)[7] == leader then $leaderExist = 1 endi -if $data(3)[8] == leader then +if $data(3)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -135,10 +135,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -165,10 +165,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -247,10 +247,10 @@ endi if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -307,10 +307,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then @@ -337,10 +337,10 @@ endi if $data(4)[4] == leader then $leaderExist = 1 endi -if $data(4)[6] == leader then +if $data(4)[7] == leader then $leaderExist = 1 endi -if $data(4)[8] == leader then +if $data(4)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then diff --git a/tests/script/tsim/vnode/replica3_basic.sim b/tests/script/tsim/vnode/replica3_basic.sim index 45db0df0d2..5da9fe6b38 100644 --- a/tests/script/tsim/vnode/replica3_basic.sim +++ b/tests/script/tsim/vnode/replica3_basic.sim @@ -141,10 +141,10 @@ $leaderExist = 0 if $data(2)[4] == leader then $leaderExist = 1 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 endi if $leaderExist != 1 then From d67de02a3142f59851d2d4dd529f619f648f25c1 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 14 Feb 2025 15:09:32 +0800 Subject: [PATCH 35/67] fix:[TS-5776]add raw type from consumer --- include/util/taoserror.h | 2 +- source/client/src/clientTmq.c | 2 +- source/common/src/msg/tmsg.c | 17 +---- source/dnode/vnode/src/inc/tq.h | 1 + source/dnode/vnode/src/inc/vnodeInt.h | 3 +- source/dnode/vnode/src/meta/metaQuery.c | 47 ++++++++++-- source/dnode/vnode/src/meta/metaSnapshot.c | 2 +- source/dnode/vnode/src/tq/tq.c | 1 + source/dnode/vnode/src/tq/tqMeta.c | 1 + source/dnode/vnode/src/tq/tqRead.c | 14 ++-- source/dnode/vnode/src/tq/tqScan.c | 89 +++++++++++++++------- source/dnode/vnode/src/tq/tqUtil.c | 8 +- source/dnode/vnode/src/vnd/vnodeQuery.c | 2 +- source/dnode/vnode/src/vnd/vnodeSvr.c | 17 +++-- source/libs/parser/src/parInsertUtil.c | 2 +- source/util/src/terror.c | 2 +- 16 files changed, 137 insertions(+), 73 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 793ffa17bc..397118411c 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -1017,7 +1017,7 @@ int32_t taosGetErrSize(); #define TSDB_CODE_TMQ_NO_NEED_REBALANCE TAOS_DEF_ERROR_CODE(0, 0x4016) #define TSDB_CODE_TMQ_INVALID_STATUS TAOS_DEF_ERROR_CODE(0, 0x4017) #define TSDB_CODE_TMQ_INVALID_DATA TAOS_DEF_ERROR_CODE(0, 0x4018) -#define TSDB_CODE_TMQ_DUPLICATE_UID TAOS_DEF_ERROR_CODE(0, 0x4019) +#define TSDB_CODE_TMQ_RAW_DATA_SPLIT TAOS_DEF_ERROR_CODE(0, 0x4019) // stream #define TSDB_CODE_STREAM_TASK_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x4100) diff --git a/source/client/src/clientTmq.c b/source/client/src/clientTmq.c index 1e9533ef69..4b2360ea27 100644 --- a/source/client/src/clientTmq.c +++ b/source/client/src/clientTmq.c @@ -1745,7 +1745,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) { pTmq->resetOffsetCfg = conf->resetOffset; pTmq->replayEnable = conf->replayEnable; pTmq->sourceExcluded = conf->sourceExcluded; - pTmq->rawData = 1; + pTmq->rawData = conf->rawData; pTmq->enableBatchMeta = conf->enableBatchMeta; tstrncpy(pTmq->user, user, TSDB_USER_LEN); if (taosGetFqdn(pTmq->fqdn) != 0) { diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index e5926dcb24..fbf721993b 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11877,32 +11877,17 @@ int32_t tDecodeSubmitReq(SDecoder *pCoder, SSubmitReq2 *pReq, SArray* rawList) { goto _exit; } - bool hasCreateTable = false; for (uint64_t i = 0; i < nSubmitTbData; i++) { SSubmitTbData* data = taosArrayReserve(pReq->aSubmitTbData, 1); - if (tDecodeSSubmitTbData(pCoder, data, - rawList != NULL ? taosArrayReserve(rawList, 1) : NULL) < 0) { + if (tDecodeSSubmitTbData(pCoder, data, rawList != NULL ? taosArrayReserve(rawList, 1) : NULL) < 0) { code = TSDB_CODE_INVALID_MSG; goto _exit; } - if (data->flags & SUBMIT_REQ_AUTO_CREATE_TABLE){ - hasCreateTable = true; - } - } - if (rawList != NULL && hasCreateTable){ - taosArrayClear(rawList); } tEndDecode(pCoder); _exit: - if (code) { - if (pReq->aSubmitTbData) { - // todo - taosArrayDestroy(pReq->aSubmitTbData); - pReq->aSubmitTbData = NULL; - } - } return code; } diff --git a/source/dnode/vnode/src/inc/tq.h b/source/dnode/vnode/src/inc/tq.h index 2c06ff1f07..50d6eb0090 100644 --- a/source/dnode/vnode/src/inc/tq.h +++ b/source/dnode/vnode/src/inc/tq.h @@ -90,6 +90,7 @@ typedef struct { // for replay SSDataBlock* block; int64_t blockTime; + SHashObj* tableCreateTimeHash; // for process create table msg in submit if fetch raw data } STqHandle; struct STQ { diff --git a/source/dnode/vnode/src/inc/vnodeInt.h b/source/dnode/vnode/src/inc/vnodeInt.h index 5a61c1c124..402ab8da7e 100644 --- a/source/dnode/vnode/src/inc/vnodeInt.h +++ b/source/dnode/vnode/src/inc/vnodeInt.h @@ -167,7 +167,8 @@ int32_t metaDropMultipleTables(SMeta* pMeta, int64_t version, SArray* tb int metaTtlFindExpired(SMeta* pMeta, int64_t timePointMs, SArray* tbUids, int32_t ttlDropMaxCount); int metaAlterTable(SMeta* pMeta, int64_t version, SVAlterTbReq* pReq, STableMetaRsp* pMetaRsp); int metaUpdateChangeTimeWithLock(SMeta* pMeta, tb_uid_t uid, int64_t changeTimeMs); -SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock, int64_t* createTime); +SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock); +int64_t metaGetTableCreateTime(SMeta *pMeta, tb_uid_t uid, int lock); int32_t metaGetTbTSchemaNotNull(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock, STSchema** ppTSchema); int32_t metaGetTbTSchemaMaybeNull(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock, STSchema** ppTSchema); STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, int lock); diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index c19a2e3ce2..3dcfa1e4fd 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -371,7 +371,7 @@ int32_t metaTbCursorPrev(SMTbCursor *pTbCur, ETableType jumpTableType) { return 0; } -SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock, int64_t *createTime) { +SSchemaWrapper *metaGetTableSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) { void *pData = NULL; int nData = 0; int64_t version; @@ -407,9 +407,6 @@ _query: } } else if (me.type == TSDB_CHILD_TABLE) { uid = me.ctbEntry.suid; - if (createTime != NULL){ - *createTime = me.ctbEntry.btime; - } tDecoderClear(&dc); goto _query; } else { @@ -448,6 +445,46 @@ _err: return NULL; } +int64_t metaGetTableCreateTime(SMeta *pMeta, tb_uid_t uid, int lock) { + void *pData = NULL; + int nData = 0; + int64_t version = 0; + SDecoder dc = {0}; + int64_t createTime = 0; + if (lock) { + metaRLock(pMeta); + } + + if (tdbTbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pData, &nData) < 0) { + goto _exit; + } + + version = ((SUidIdxVal *)pData)[0].version; + + if (tdbTbGet(pMeta->pTbDb, &(STbDbKey){.uid = uid, .version = version}, sizeof(STbDbKey), &pData, &nData) != 0) { + goto _exit; + } + + SMetaEntry me = {0}; + tDecoderInit(&dc, pData, nData); + int32_t code = metaDecodeEntry(&dc, &me); + if (code) { + tDecoderClear(&dc); + goto _exit; + } + if (me.type == TSDB_CHILD_TABLE) { + createTime = me.ctbEntry.btime; + } + tDecoderClear(&dc); + + _exit: + if (lock) { + metaULock(pMeta); + } + tdbFree(pData); + return createTime; +} + SMCtbCursor *metaOpenCtbCursor(void *pVnode, tb_uid_t uid, int lock) { SMeta *pMeta = ((SVnode *)pVnode)->pMeta; SMCtbCursor *pCtbCur = NULL; @@ -620,7 +657,7 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver, int lock) { STSchema *pTSchema = NULL; SSchemaWrapper *pSW = NULL; - pSW = metaGetTableSchema(pMeta, uid, sver, lock, NULL); + pSW = metaGetTableSchema(pMeta, uid, sver, lock); if (!pSW) return NULL; pTSchema = tBuildTSchema(pSW->pSchema, pSW->nCols, pSW->version); diff --git a/source/dnode/vnode/src/meta/metaSnapshot.c b/source/dnode/vnode/src/meta/metaSnapshot.c index 7374b9ceb5..b227653e5e 100644 --- a/source/dnode/vnode/src/meta/metaSnapshot.c +++ b/source/dnode/vnode/src/meta/metaSnapshot.c @@ -548,7 +548,7 @@ int32_t setForSnapShot(SSnapContext* ctx, int64_t uid) { void taosXSetTablePrimaryKey(SSnapContext* ctx, int64_t uid) { bool ret = false; - SSchemaWrapper* schema = metaGetTableSchema(ctx->pMeta, uid, -1, 1, NULL); + SSchemaWrapper* schema = metaGetTableSchema(ctx->pMeta, uid, -1, 1); if (schema && schema->nCols >= 2 && schema->pSchema[1].flags & COL_IS_KEY) { ret = true; } diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index daf4fa65f3..a015f13091 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -57,6 +57,7 @@ void tqDestroyTqHandle(void* data) { if (pData->pRef) { walCloseRef(pData->pRef->pWal, pData->pRef->refId); } + taosHashCleanup(pData->tableCreateTimeHash); } static bool tqOffsetEqual(const STqOffset* pLeft, const STqOffset* pRight) { diff --git a/source/dnode/vnode/src/tq/tqMeta.c b/source/dnode/vnode/src/tq/tqMeta.c index 580828b089..b84dcc4703 100644 --- a/source/dnode/vnode/src/tq/tqMeta.c +++ b/source/dnode/vnode/src/tq/tqMeta.c @@ -343,6 +343,7 @@ static int tqMetaInitHandle(STQ* pTq, STqHandle* handle) { tqReaderSetTbUidList(handle->execHandle.pTqReader, tbUidList, NULL); taosArrayDestroy(tbUidList); } + handle->tableCreateTimeHash = (SHashObj*)taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK); END: return code; diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 792763862b..f01a35d58f 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -283,7 +283,7 @@ void tqSetTablePrimaryKey(STqReader* pReader, int64_t uid) { return; } bool ret = false; - SSchemaWrapper* schema = metaGetTableSchema(pReader->pVnodeMeta, uid, -1, 1, NULL); + SSchemaWrapper* schema = metaGetTableSchema(pReader->pVnodeMeta, uid, -1, 1); if (schema && schema->nCols >= 2 && schema->pSchema[1].flags & COL_IS_KEY) { ret = true; } @@ -742,7 +742,7 @@ int32_t tqRetrieveDataBlock(STqReader* pReader, SSDataBlock** pRes, const char* (pReader->cachedSchemaVer != sversion)) { tDeleteSchemaWrapper(pReader->pSchemaWrapper); - pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1, NULL); + pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1); if (pReader->pSchemaWrapper == NULL) { tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", uid:%" PRId64 "version %d, possibly dropped table", @@ -1102,9 +1102,9 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* block int64_t uid = pSubmitTbData->uid; pReader->lastBlkUid = uid; - int64_t createTime = INT64_MAX; + int64_t createTime = 0; tDeleteSchemaWrapper(pReader->pSchemaWrapper); - pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1, &createTime); + pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1); if (pReader->pSchemaWrapper == NULL) { tqWarn("vgId:%d, cannot found schema wrapper for table: suid:%" PRId64 ", version %d, possibly dropped table", pReader->pWalReader->pWal->cfg.vgId, uid, pReader->cachedSchemaVer); @@ -1112,14 +1112,12 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* block return TSDB_CODE_TQ_TABLE_SCHEMA_NOT_FOUND; } - if (fetchMeta != WITH_DATA && - pSubmitTbData->pCreateTbReq != NULL && - pSubmitTbData->ctimeMs - createTime <= 0) { // judge if table is already created to avoid sending crateTbReq + if (pSubmitTbData->pCreateTbReq != NULL) { int32_t code = buildCreateTbInfo(pRsp, pSubmitTbData->pCreateTbReq); if (code != 0) { return code; } - } else if (rawList != NULL && taosArrayGetSize(rawList) > 0) { + } else if (rawList != NULL) { if (taosArrayPush(schemas, &pReader->pSchemaWrapper) == NULL){ return terrno; } diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 265e165038..faf1954667 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -336,26 +336,9 @@ static void tqProcessSubData(STQ* pTq, STqHandle* pHandle, SMqDataRsp* pRsp, int TSDB_CHECK_CODE(code, lino, END); bool tmp = (pSubmitTbData->flags & pRequest->sourceExcluded) != 0; TSDB_CHECK_CONDITION(!tmp, code, lino, END, TSDB_CODE_SUCCESS); + + int32_t blockNum = taosArrayGetSize(pBlocks) == 0 ? 1 : taosArrayGetSize(pBlocks); - if (rawList != NULL && taosArrayGetSize(pBlocks) == 0){ - if (taosHashGet(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES) != NULL) { - tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 " is already exists", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); - terrno = TSDB_CODE_TMQ_DUPLICATE_UID; - goto END; - } else { - code = taosHashPut(pRequest->uidHash, &pExec->pTqReader->lastBlkUid, LONG_BYTES, &pExec->pTqReader->lastBlkUid, LONG_BYTES); - TSDB_CHECK_CODE(code, lino, END); - } - } - - // this submit data is metadata and previous data is data - if (rawList != NULL && *totalRows > 0 && pSubmitTbData->pCreateTbReq != NULL && taosArrayGetSize(pBlocks) > 0 && pRsp->createTableNum <= 1){ - tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); - terrno = TSDB_CODE_TMQ_DUPLICATE_UID; - pRsp->createTableNum = 0; - goto END; - } - if (pRsp->withTbName) { int64_t uid = pExec->pTqReader->lastBlkUid; code = tqAddTbNameToRsp(pTq, uid, pRsp, blockNum); @@ -405,6 +388,52 @@ END: taosArrayDestroyP(pSchemas, (FDelete)tDeleteSchemaWrapper); } +static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, SArray** rawList){ + STqExecHandle* pExec = &pHandle->execHandle; + STqReader* pReader = pExec->pTqReader; + int32_t blockSz = taosArrayGetSize(pReader->submit.aSubmitTbData); + for (int32_t i = 0; i < blockSz; i++){ + SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, i); + if (pSubmitTbData== NULL){ + tqReaderClearSubmitMsg(pReader); + taosArrayDestroy(*rawList); + *rawList = NULL; + return; + } + if (pSubmitTbData->pCreateTbReq == NULL){ + continue; + } + int64_t createTime = 0; + int64_t uid = pSubmitTbData->uid; + if (taosHashGet(pRequest->uidHash, &uid, LONG_BYTES) != NULL) { + tqDebug("poll rawdata split,uid:%" PRId64 " is already exists", uid); + terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; + return; + } else { + if (taosHashPut(pRequest->uidHash, &uid, LONG_BYTES, &uid, LONG_BYTES) != 0){ + tqError("failed to add table create time to hash, uid:%"PRId64, uid); + } + } + + int64_t *cTime = (int64_t*)taosHashGet(pHandle->tableCreateTimeHash, &uid, LONG_BYTES); + if (cTime != NULL){ + createTime = *cTime; + } else{ + createTime = metaGetTableCreateTime(pReader->pVnodeMeta, uid, 1); + if (taosHashPut(pHandle->tableCreateTimeHash, &uid, LONG_BYTES, &createTime, LONG_BYTES) != 0){ + tqError("failed to add table create time to hash, uid:%"PRId64, uid); + } + } + if (pHandle->fetchMeta == WITH_DATA || pSubmitTbData->ctimeMs > createTime){ + tDestroySVCreateTbReq(pSubmitTbData->pCreateTbReq, TSDB_MSG_FLG_DECODE); + pSubmitTbData->pCreateTbReq = NULL; + } else{ + taosArrayDestroy(*rawList); + *rawList = NULL; + } + } +} + int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqDataRsp* pRsp, int32_t* totalRows, const SMqPollReq* pRequest) { int32_t code = 0; int32_t lino = 0; @@ -417,26 +446,32 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData } code = tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver, rawList); TSDB_CHECK_CODE(code, lino, END); + preProcessSubmitMsg(pHandle, pRequest, &rawList); + + // data could not contains same uid data in rawdata mode + if (pRequest->rawData != 0 && terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT){ + goto END; + } + + // this submit data is metadata and previous data is rawdata + if (pRequest->rawData != 0 && *totalRows > 0 && rawList == NULL){ + tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; + goto END; + } if (pExec->subType == TOPIC_SUB_TYPE__TABLE) { while (tqNextBlockImpl(pReader, NULL)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); - if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ - tqReaderClearSubmitMsg(pReader); - goto END; - } } } else if (pExec->subType == TOPIC_SUB_TYPE__DB) { while (tqNextDataBlockFilterOut(pReader, pExec->execDb.pFilterOutTbUid)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); - if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){ - tqReaderClearSubmitMsg(pReader); - goto END; - } } } END: + tqReaderClearSubmitMsg(pReader); taosArrayDestroy(rawList); if (code != 0){ tqError("%s failed at %d, failed to scan log:%s", __FUNCTION__, lino, tstrerror(code)); diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index 5dd8de9429..b0f5515339 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -381,11 +381,13 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, (pRequest->rawData != 0 && (totalRows >= TQ_POLL_MAX_BYTES || taosxRsp.createTableNum > 0 || taosArrayGetSize(taosxRsp.blockData) > tmqRowSize || - terrno == TSDB_CODE_TMQ_DUPLICATE_UID))) { - tqOffsetResetToLog(&taosxRsp.rspOffset, terrno == TSDB_CODE_TMQ_DUPLICATE_UID ? fetchVer : fetchVer + 1); + terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT))) { + tqDebug("start to send rsp, block num:%d, totalRows:%d, createTableNum:%d, terrno:%d", + (int)taosArrayGetSize(taosxRsp.blockData), totalRows, taosxRsp.createTableNum, terrno); + tqOffsetResetToLog(&taosxRsp.rspOffset, terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT ? fetchVer : fetchVer + 1); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, POLL_RSP_TYPE(pRequest, taosxRsp), vgId); - if (terrno == TSDB_CODE_TMQ_DUPLICATE_UID){terrno = 0;} + if (terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT){terrno = 0;} goto END; } else { fetchVer++; diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 2b07de916c..58a57c1949 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -708,7 +708,7 @@ int32_t vnodeGetCtbNum(SVnode *pVnode, int64_t suid, int64_t *num) { } int32_t vnodeGetStbColumnNum(SVnode *pVnode, tb_uid_t suid, int *num) { - SSchemaWrapper *pSW = metaGetTableSchema(pVnode->pMeta, suid, -1, 0, NULL); + SSchemaWrapper *pSW = metaGetTableSchema(pVnode->pMeta, suid, -1, 0); if (pSW) { *num = pSW->nCols; tDeleteSchemaWrapper(pSW); diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index 3fb7b597ce..e1bef30d32 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -314,25 +314,25 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int uint64_t nColData; if (tDecodeU64v(pCoder, &nColData) < 0) { code = TSDB_CODE_INVALID_MSG; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } SColData colData = {0}; code = tDecodeColData(version, pCoder, &colData); if (code) { code = TSDB_CODE_INVALID_MSG; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } if (colData.flag != HAS_VALUE) { code = TSDB_CODE_INVALID_MSG; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } for (int32_t iRow = 0; iRow < colData.nVal; iRow++) { if (((TSKEY *)colData.pData)[iRow] < minKey || ((TSKEY *)colData.pData)[iRow] > maxKey) { code = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } } @@ -340,14 +340,14 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int code = tDecodeColData(version, pCoder, &colData); if (code) { code = TSDB_CODE_INVALID_MSG; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } } } else { uint64_t nRow; if (tDecodeU64v(pCoder, &nRow) < 0) { code = TSDB_CODE_INVALID_MSG; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } for (int32_t iRow = 0; iRow < nRow; ++iRow) { @@ -356,7 +356,7 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int if (pRow->ts < minKey || pRow->ts > maxKey) { code = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE; - goto _exit; + TSDB_CHECK_CODE(code, lino, _exit); } } } @@ -369,6 +369,9 @@ static int32_t vnodePreProcessSubmitTbData(SVnode *pVnode, SDecoder *pCoder, int tEndDecode(pCoder); _exit: + if (code) { + vError("vgId:%d, %s:%d failed to vnodePreProcessSubmitTbData submit request since %s", TD_VID(pVnode), __func__, lino, tstrerror(code)); + } return code; } static int32_t vnodePreProcessSubmitMsg(SVnode *pVnode, SRpcMsg *pMsg) { diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index 0d70292501..a77964bb4f 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -1100,7 +1100,7 @@ int rawBlockBindRawData(SHashObj* pVgroupHash, SArray* pVgroupList, STableMeta* return terrno; } - qDebug("add raw data to vgId:%d", pTableMeta->vgId); + qDebug("add raw data to vgId:%d, len:%d", pTableMeta->vgId, *(int32_t*)data); return 0; } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index c05423e51c..f34b00bec5 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -860,7 +860,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_TABLE_QUALIFIED, "No table qualified TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_NO_NEED_REBALANCE, "No need rebalance") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_STATUS, "Invalid status, please subscribe topic first") TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_INVALID_DATA, "Invalid data use here") -TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_DUPLICATE_UID, "Duplicate uid") +TAOS_DEFINE_ERROR(TSDB_CODE_TMQ_RAW_DATA_SPLIT, "Split submit data for rawdata") // stream TAOS_DEFINE_ERROR(TSDB_CODE_STREAM_TASK_NOT_EXIST, "Stream task not exist") From f16f21897e1296615203e1d8eff4bd25bb36f257 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 14 Feb 2025 16:12:00 +0800 Subject: [PATCH 36/67] fix:[TS-5776]add raw type from consumer --- source/dnode/vnode/src/tq/tqScan.c | 10 ++++++---- source/libs/parser/src/parInsertUtil.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index faf1954667..9a1e188045 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -400,10 +400,7 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, *rawList = NULL; return; } - if (pSubmitTbData->pCreateTbReq == NULL){ - continue; - } - int64_t createTime = 0; + int64_t uid = pSubmitTbData->uid; if (taosHashGet(pRequest->uidHash, &uid, LONG_BYTES) != NULL) { tqDebug("poll rawdata split,uid:%" PRId64 " is already exists", uid); @@ -415,6 +412,11 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, } } + if (pSubmitTbData->pCreateTbReq == NULL){ + continue; + } + + int64_t createTime = 0; int64_t *cTime = (int64_t*)taosHashGet(pHandle->tableCreateTimeHash, &uid, LONG_BYTES); if (cTime != NULL){ createTime = *cTime; diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index a77964bb4f..f3ca87e9bc 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -1100,7 +1100,7 @@ int rawBlockBindRawData(SHashObj* pVgroupHash, SArray* pVgroupList, STableMeta* return terrno; } - qDebug("add raw data to vgId:%d, len:%d", pTableMeta->vgId, *(int32_t*)data); + uTrace("add raw data to vgId:%d, len:%d", pTableMeta->vgId, *(int32_t*)data); return 0; } From 39f77e45fccc395d63533c52ae41c87f523dc0de Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 14 Feb 2025 16:54:53 +0800 Subject: [PATCH 37/67] fix:[TS-5776]add raw type from consumer --- source/dnode/vnode/src/tq/tqScan.c | 7 +++++++ source/dnode/vnode/src/tq/tqUtil.c | 5 ++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 9a1e188045..9b04653d3b 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -462,6 +462,13 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData goto END; } + // this submit data is rawdata and previous data is metadata + if (pRequest->rawData != 0 && pRsp->createTableNum > 0 && rawList != NULL){ + tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; + goto END; + } + if (pExec->subType == TOPIC_SUB_TYPE__TABLE) { while (tqNextBlockImpl(pReader, NULL)) { tqProcessSubData(pTq, pHandle, pRsp, totalRows, pRequest, rawList); diff --git a/source/dnode/vnode/src/tq/tqUtil.c b/source/dnode/vnode/src/tq/tqUtil.c index b0f5515339..44d9ffda83 100644 --- a/source/dnode/vnode/src/tq/tqUtil.c +++ b/source/dnode/vnode/src/tq/tqUtil.c @@ -379,11 +379,10 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, if ((pRequest->rawData == 0 && totalRows >= tmqRowSize) || (taosGetTimestampMs() - st > TMIN(TQ_POLL_MAX_TIME, pRequest->timeout)) || (pRequest->rawData != 0 && (totalRows >= TQ_POLL_MAX_BYTES || - taosxRsp.createTableNum > 0 || taosArrayGetSize(taosxRsp.blockData) > tmqRowSize || terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT))) { - tqDebug("start to send rsp, block num:%d, totalRows:%d, createTableNum:%d, terrno:%d", - (int)taosArrayGetSize(taosxRsp.blockData), totalRows, taosxRsp.createTableNum, terrno); +// tqDebug("start to send rsp, block num:%d, totalRows:%d, createTableNum:%d, terrno:%d", +// (int)taosArrayGetSize(taosxRsp.blockData), totalRows, taosxRsp.createTableNum, terrno); tqOffsetResetToLog(&taosxRsp.rspOffset, terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT ? fetchVer : fetchVer + 1); code = tqSendDataRsp(pHandle, pMsg, pRequest, &taosxRsp, POLL_RSP_TYPE(pRequest, taosxRsp), vgId); From 47a6836c273f4eceb1f7e57602fd8d7d602e0895 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sun, 16 Feb 2025 00:15:01 +0800 Subject: [PATCH 38/67] fix:[TS-5776]add raw type from consumer --- source/dnode/vnode/src/tq/tqScan.c | 7 +++---- tests/system-test/7-tmq/taosx-performance.py | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 9b04653d3b..0de5803881 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -395,7 +395,6 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, for (int32_t i = 0; i < blockSz; i++){ SSubmitTbData* pSubmitTbData = taosArrayGet(pReader->submit.aSubmitTbData, i); if (pSubmitTbData== NULL){ - tqReaderClearSubmitMsg(pReader); taosArrayDestroy(*rawList); *rawList = NULL; return; @@ -456,15 +455,15 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData } // this submit data is metadata and previous data is rawdata - if (pRequest->rawData != 0 && *totalRows > 0 && rawList == NULL){ - tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + if (pRequest->rawData != 0 && *totalRows > 0 && pRsp->createTableNum == 0 && rawList == NULL){ + tqDebug("poll rawdata split,vgId:%d, this wal submit data contains metadata and previous data is data", pTq->pVnode->config.vgId); terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; goto END; } // this submit data is rawdata and previous data is metadata if (pRequest->rawData != 0 && pRsp->createTableNum > 0 && rawList != NULL){ - tqDebug("poll rawdata split,vgId:%d, uid:%" PRId64 ", this submit data is metadata and previous data is data", pTq->pVnode->config.vgId, pExec->pTqReader->lastBlkUid); + tqDebug("poll rawdata split,vgId:%d, this wal submit data is data and previous data is metadata", pTq->pVnode->config.vgId); terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; goto END; } diff --git a/tests/system-test/7-tmq/taosx-performance.py b/tests/system-test/7-tmq/taosx-performance.py index 8a9e2bbe83..5f7c6c3e07 100755 --- a/tests/system-test/7-tmq/taosx-performance.py +++ b/tests/system-test/7-tmq/taosx-performance.py @@ -145,22 +145,22 @@ def stopTaosd(str): os.system(cmd) def cleanDb(): - dropTopic = f"taos -c {dnode1}/{cfg} -s \"drop topic if exists test\"" + dropTopic = f"{taosd}/bin/taos -c {dnode1}/{cfg} -s \"drop topic if exists test\"" print("dropTopic:%s" % dropTopic) os.system(dropTopic) - dropDb = f"taos -c {dnode2}/{cfg} -s \"drop database if exists test\"" + dropDb = f"{taosd}/bin/taos -c {dnode2}/{cfg} -s \"drop database if exists test\"" print("dropDb:%s" % dropDb) os.system(dropDb) - createDb = f"taos -c {dnode2}/{cfg} -s \"create database test vgroups {vgroups}\"" + createDb = f"{taosd}/bin/taos -c {dnode2}/{cfg} -s \"create database test vgroups {vgroups}\"" print("createDb:%s" % createDb) os.system(createDb) def restartTaosd(): - cmd1 = f"{taosd} -c {dnode1}/{cfg} > /dev/null 2>&1 &" - cmd2 = f"{taosd} -c {dnode2}/{cfg} > /dev/null 2>&1 &" + cmd1 = f"{taosd}/bin/taosd -c {dnode1}/{cfg} > /dev/null 2>&1 &" + cmd2 = f"{taosd}/bin/taosd -c {dnode2}/{cfg} > /dev/null 2>&1 &" print("start taosd1 :%s" % cmd1) print("start taosd2 :%s" % cmd2) os.system(cmd1) @@ -168,7 +168,7 @@ def restartTaosd(): def runTaosx(): - cmd = f"{taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout={taosxTimeout}s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw\" -t \"taos://root:taosdata@localhost:7030/test\" > {taosxLog}" + cmd = f"{taosx} run -f \"tmq://root:taosdata@localhost:6030/test?group.id=taosx-new-`date +%s`&timeout={taosxTimeout}s&experimental.snapshot.enable=false&auto.offset.reset=earliest&prefer=raw&libraryPath={taosd}/lib/libtaos.so\" -t \"taos://root:taosdata@localhost:7030/test?libraryPath={taosd}/lib/libtaos.so\" > {taosxLog}" print("run taosx:%s" % cmd) os.system(cmd) From 3da00b7c7452fe680908b460a7a120c560b31f71 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 17 Feb 2025 10:13:49 +0800 Subject: [PATCH 39/67] fix:[TS-5776]add raw type from consumer --- include/common/tmsg.h | 3 ++- source/common/src/msg/tmsg.c | 8 +++++++- source/dnode/vnode/src/tq/tqScan.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 97955c0c49..0446ca7dee 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -4267,7 +4267,8 @@ typedef struct { void* rawData; }; }; - void* data; //for free, only effected if type is data or metadata. raw data not effected + void* data; //for free in client, only effected if type is data or metadata. raw data not effected + bool blockDataElementFree; // if true, free blockDataElement in blockData,(true in server, false in client) } SMqDataRsp; diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index fbf721993b..75791ed0ce 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11451,6 +11451,8 @@ int32_t tDecodeMqDataRspCommon(SDecoder *pDecoder, SMqDataRsp *pRsp) { if (taosArrayPush(pRsp->blockData, &data) == NULL) { TAOS_CHECK_EXIT(terrno); } + pRsp->blockDataElementFree = false; + int32_t len = bLen; if (taosArrayPush(pRsp->blockDataLen, &len) == NULL) { TAOS_CHECK_EXIT(terrno); @@ -11510,7 +11512,11 @@ _exit: static void tDeleteMqDataRspCommon(SMqDataRsp *pRsp) { taosArrayDestroy(pRsp->blockDataLen); pRsp->blockDataLen = NULL; - taosArrayDestroy(pRsp->blockData); + if (pRsp->blockDataElementFree){ + taosArrayDestroyP(pRsp->blockData) + } else { + taosArrayDestroy(pRsp->blockData); + } pRsp->blockData = NULL; taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSchemaWrapper); pRsp->blockSchema = NULL; diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index 0de5803881..ead040b7a5 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -62,7 +62,7 @@ static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, actualLen += sizeof(SRetrieveTableRspForTmq); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &actualLen), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); - + pRsp->blockDataElementFree = true; buf = NULL; END: if (code != 0){ From 43fffd644bc768f5636bcfa08f3443c6ee2e05f0 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Mon, 17 Feb 2025 14:42:20 +0800 Subject: [PATCH 40/67] resolve compatibility issues --- source/common/src/msg/tmsg.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 5d4c5b5cc4..609e60e3e6 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -1473,6 +1473,12 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tEncodeI64(&encoder, pReq->analVer)); TAOS_CHECK_EXIT(tSerializeSMonitorParas(&encoder, &pReq->clusterCfg.monitorParas)); + for (int32_t i = 0; i < vlen; ++i) { + SVnodeLoad *pload = taosArrayGet(pReq->pVloads, i); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncAppliedIndex)); + TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncCommitIndex)); + } + tEndEncode(&encoder); _exit: @@ -1544,8 +1550,6 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tDecodeI32(&decoder, &vload.learnerProgress)); TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.roleTimeMs)); TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.startTimeMs)); - TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.syncAppliedIndex)); - TAOS_CHECK_EXIT(tDecodeI64(&decoder, &vload.syncCommitIndex)); if (taosArrayPush(pReq->pVloads, &vload) == NULL) { TAOS_CHECK_EXIT(terrno); } @@ -1604,6 +1608,14 @@ int32_t tDeserializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tDeserializeSMonitorParas(&decoder, &pReq->clusterCfg.monitorParas)); } + if (!tDecodeIsEnd(&decoder)) { + for (int32_t i = 0; i < vlen; ++i) { + SVnodeLoad *pLoad = taosArrayGet(pReq->pVloads, i); + TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pLoad->syncAppliedIndex)); + TAOS_CHECK_EXIT(tDecodeI64(&decoder, &pLoad->syncCommitIndex)); + } + } + tEndDecode(&decoder); _exit: From 420c222d5b2bb8c6a94104b72e4418bf520c651b Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 17 Feb 2025 15:32:18 +0800 Subject: [PATCH 41/67] fix:[TS-5776]add raw type from consumer --- source/common/src/msg/tmsg.c | 2 +- source/libs/nodes/src/nodesCloneFuncs.c | 8 -------- source/libs/nodes/src/nodesUtilFuncs.c | 1 + source/libs/parser/src/parInsertUtil.c | 5 ++++- source/libs/transport/src/trans.c | 3 +-- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 75791ed0ce..19ffa132a6 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11513,7 +11513,7 @@ static void tDeleteMqDataRspCommon(SMqDataRsp *pRsp) { taosArrayDestroy(pRsp->blockDataLen); pRsp->blockDataLen = NULL; if (pRsp->blockDataElementFree){ - taosArrayDestroyP(pRsp->blockData) + taosArrayDestroyP(pRsp->blockData, NULL); } else { taosArrayDestroy(pRsp->blockData); } diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 6d245ebd61..4fd5898354 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -849,11 +849,6 @@ static int32_t physiDispatchCopy(const SDataDispatcherNode* pSrc, SDataDispatche return TSDB_CODE_SUCCESS; } -static int32_t physiInserterCopy(const SDataInserterNode* pSrc, SDataInserterNode* pDst) { - COPY_BASE_OBJECT_FIELD(sink, dataSinkNodeCopy); - return TSDB_CODE_SUCCESS; -} - static int32_t physiQueryInserterCopy(const SQueryInserterNode* pSrc, SQueryInserterNode* pDst) { COPY_BASE_OBJECT_FIELD(sink, dataSinkNodeCopy); CLONE_NODE_LIST_FIELD(pCols); @@ -1135,9 +1130,6 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) { case QUERY_NODE_PHYSICAL_PLAN_DISPATCH: code = physiDispatchCopy((const SDataDispatcherNode*)pNode, (SDataDispatcherNode*)pDst); break; - //case QUERY_NODE_PHYSICAL_PLAN_INSERT: - // code = physiInserterCopy((const SDataInserterNode*)pNode, (SDataInserterNode*)pDst); - // break; case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT: code = physiQueryInserterCopy((const SQueryInserterNode*)pNode, (SQueryInserterNode*)pDst); break; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 4d31fe47fe..c6d2caed53 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1995,6 +1995,7 @@ void nodesDestroyNode(SNode* pNode) { case QUERY_NODE_PHYSICAL_PLAN_INSERT: { SDataInserterNode* pSink = (SDataInserterNode*)pNode; destroyDataSinkNode((SDataSinkNode*)pSink); + taosMemFreeClear(pSink->pData); break; } case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT: { diff --git a/source/libs/parser/src/parInsertUtil.c b/source/libs/parser/src/parInsertUtil.c index f3ca87e9bc..1931f0803d 100644 --- a/source/libs/parser/src/parInsertUtil.c +++ b/source/libs/parser/src/parInsertUtil.c @@ -830,6 +830,7 @@ static int32_t buildSubmitReq(int32_t vgId, SSubmitReq2* pReq, void** pData, uin } static void destroyVgDataBlocks(void* p) { + if (p == NULL) return; SVgDataBlocks* pVg = p; taosMemoryFree(pVg->pData); taosMemoryFree(pVg); @@ -855,7 +856,6 @@ int32_t insBuildVgDataBlocks(SHashObj* pVgroupsHashObj, SArray* pVgDataCxtList, if (TSDB_CODE_SUCCESS == code) { dst->numOfTables = taosArrayGetSize(src->pData->aSubmitTbData); code = taosHashGetDup(pVgroupsHashObj, (const char*)&src->vgId, sizeof(src->vgId), &dst->vg); - // uError("td23101 3vgId:%d, numEps:%d", src->vgId, dst->vg.epSet.numOfEps); } if (TSDB_CODE_SUCCESS == code) { code = buildSubmitReq(src->vgId, src->pData, &dst->pData, &dst->size); @@ -863,6 +863,9 @@ int32_t insBuildVgDataBlocks(SHashObj* pVgroupsHashObj, SArray* pVgDataCxtList, if (TSDB_CODE_SUCCESS == code) { code = (NULL == taosArrayPush(pDataBlocks, &dst) ? terrno : TSDB_CODE_SUCCESS); } + if (TSDB_CODE_SUCCESS != code) { + destroyVgDataBlocks(dst); + } } if (append) { diff --git a/source/libs/transport/src/trans.c b/source/libs/transport/src/trans.c index 986fe08504..b3b69d81c0 100644 --- a/source/libs/transport/src/trans.c +++ b/source/libs/transport/src/trans.c @@ -155,7 +155,7 @@ void rpcCloseImpl(void* arg) { void* rpcMallocCont(int64_t contLen) { int64_t size = contLen + TRANS_MSG_OVERHEAD; - char* start = taosMemoryMalloc(size); + char* start = taosMemoryCalloc(1, size); if (start == NULL) { tError("failed to malloc msg, size:%" PRId64, size); return NULL; @@ -163,7 +163,6 @@ void* rpcMallocCont(int64_t contLen) { tTrace("malloc mem:%p size:%" PRId64, start, size); } - memset(start, 0, TRANS_MSG_OVERHEAD); return start + TRANS_MSG_OVERHEAD; } From 12dd3a621e14634f70b2dc963bc5a28da789c85b Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Mon, 17 Feb 2025 16:18:13 +0800 Subject: [PATCH 42/67] enh: optimize group by tag queries --- include/libs/nodes/plannodes.h | 1 + source/libs/nodes/src/nodesCloneFuncs.c | 1 + source/libs/planner/src/planLogicCreater.c | 49 +++++++++++++++++++++- source/libs/planner/src/planOptimizer.c | 14 +++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 3e95f1e286..1afec35c3c 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -128,6 +128,7 @@ typedef struct SScanLogicNode { bool paraTablesSort; // for table merge scan bool smallDataTsSort; // disable row id sort for table merge scan bool needSplit; + bool noPseudoRefAfterGrp; // no pseudo columns referenced ater group/partition clause } SScanLogicNode; typedef struct SJoinLogicNode { diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 161c5f7ca7..8a39795c3e 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -510,6 +510,7 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) { COPY_SCALAR_FIELD(paraTablesSort); COPY_SCALAR_FIELD(smallDataTsSort); COPY_SCALAR_FIELD(needSplit); + COPY_SCALAR_FIELD(noPseudoRefAfterGrp); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index c3fd9cdcf2..0eef305bc0 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -406,6 +406,47 @@ static int32_t makeScanLogicNode(SLogicPlanContext* pCxt, SRealTableNode* pRealT static bool needScanDefaultCol(EScanType scanType) { return SCAN_TYPE_TABLE_COUNT != scanType; } +static int32_t updateScanNoPseudoRefAfterGrp(SSelectStmt* pSelect, SScanLogicNode* pScan, SRealTableNode* pRealTable) { + if (NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0) { + return TSDB_CODE_SUCCESS; + } + + SNodeList* pList = NULL; + int32_t code = 0; + if (NULL == pSelect->pPartitionByList || pSelect->pPartitionByList->length <= 0) { + if (NULL == pSelect->pGroupByList || pSelect->pGroupByList->length <= 0) { + return TSDB_CODE_SUCCESS; + } + + code = nodesCollectColumns(pSelect, SQL_CLAUSE_GROUP_BY, pRealTable->table.tableAlias, COLLECT_COL_TYPE_TAG, + &pList); + if (TSDB_CODE_SUCCESS == code) { + code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, pRealTable->table.tableAlias, fmIsScanPseudoColumnFunc, + &pList); + } + if (TSDB_CODE_SUCCESS == code && (NULL == pList || pList->length <= 0)) { + pScan->noPseudoRefAfterGrp = true; + } + goto _return; + } + + code = nodesCollectColumns(pSelect, SQL_CLAUSE_PARTITION_BY, pRealTable->table.tableAlias, COLLECT_COL_TYPE_TAG, + &pList); + if (TSDB_CODE_SUCCESS == code) { + code = nodesCollectFuncs(pSelect, SQL_CLAUSE_PARTITION_BY, pRealTable->table.tableAlias, fmIsScanPseudoColumnFunc, + &pList); + } + + if (TSDB_CODE_SUCCESS == code && (NULL == pList || pList->length <= 0)) { + pScan->noPseudoRefAfterGrp = true; + } + +_return: + + nodesDestroyList(pList); + return code; +} + static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable, SLogicNode** pLogicNode) { SScanLogicNode* pScan = NULL; @@ -437,7 +478,13 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect &pScan->pScanPseudoCols); } - pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType, pSelect->tagScan); + if (TSDB_CODE_SUCCESS == code) { + code = updateScanNoPseudoRefAfterGrp(pSelect, pScan, pRealTable); + } + + if (TSDB_CODE_SUCCESS == code) { + pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType, pSelect->tagScan); + } // rewrite the expression in subsequent clauses if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 38f2e5024f..e132ce5ee6 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -3302,6 +3302,17 @@ static int32_t partTagsRewriteGroupTagsToFuncs(SNodeList* pGroupTags, int32_t st return code; } +static int32_t partTagsOptRemovePseudoCols(SScanLogicNode* pScan) { + if (!pScan->noPseudoRefAfterGrp || NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0) { + return TSDB_CODE_SUCCESS; + } + + nodesDestroyList(pScan->pScanPseudoCols); + pScan->pScanPseudoCols = NULL; + + return TSDB_CODE_SUCCESS; +} + static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { SLogicNode* pNode = optFindPossibleNode(pLogicSubplan->pNode, partTagsOptMayBeOptimized, NULL); if (NULL == pNode) { @@ -3362,6 +3373,9 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub code = partTagsRewriteGroupTagsToFuncs(pScan->pGroupTags, start, pAgg); } } + if (TSDB_CODE_SUCCESS == code) { + code = partTagsOptRemovePseudoCols(pScan); + } if (TSDB_CODE_SUCCESS == code) { code = partTagsOptRebuildTbanme(pScan->pGroupTags); } From bf5dc63a30e04f670c9e18f0a7738c24a6f9569b Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 17 Feb 2025 17:40:54 +0800 Subject: [PATCH 43/67] fix:[TS-5776]add test case --- source/dnode/vnode/src/tq/tqScan.c | 23 ++- tests/parallel_test/cases.task | 1 + tests/system-test/7-tmq/tmq_ts-5776.py | 39 ++++ utils/test/c/CMakeLists.txt | 8 + utils/test/c/tmq_ts5776.c | 255 +++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 10 deletions(-) create mode 100644 tests/system-test/7-tmq/tmq_ts-5776.py create mode 100644 utils/test/c/tmq_ts5776.c diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index ead040b7a5..d43afc9ebd 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -400,29 +400,31 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, return; } + if (pSubmitTbData->pCreateTbReq == NULL){ + continue; + } + int64_t uid = pSubmitTbData->uid; if (taosHashGet(pRequest->uidHash, &uid, LONG_BYTES) != NULL) { tqDebug("poll rawdata split,uid:%" PRId64 " is already exists", uid); terrno = TSDB_CODE_TMQ_RAW_DATA_SPLIT; return; } else { - if (taosHashPut(pRequest->uidHash, &uid, LONG_BYTES, &uid, LONG_BYTES) != 0){ - tqError("failed to add table create time to hash, uid:%"PRId64, uid); + int32_t code = taosHashPut(pRequest->uidHash, &uid, LONG_BYTES, &uid, LONG_BYTES); + if (code != 0){ + tqError("failed to add table uid to hash, code:%d, uid:%"PRId64, code, uid); } } - if (pSubmitTbData->pCreateTbReq == NULL){ - continue; - } - int64_t createTime = 0; int64_t *cTime = (int64_t*)taosHashGet(pHandle->tableCreateTimeHash, &uid, LONG_BYTES); if (cTime != NULL){ createTime = *cTime; } else{ createTime = metaGetTableCreateTime(pReader->pVnodeMeta, uid, 1); - if (taosHashPut(pHandle->tableCreateTimeHash, &uid, LONG_BYTES, &createTime, LONG_BYTES) != 0){ - tqError("failed to add table create time to hash, uid:%"PRId64, uid); + int32_t code = taosHashPut(pHandle->tableCreateTimeHash, &uid, LONG_BYTES, &createTime, LONG_BYTES); + if (code != 0){ + tqError("failed to add table create time to hash,code:%d, uid:%"PRId64, code, uid); } } if (pHandle->fetchMeta == WITH_DATA || pSubmitTbData->ctimeMs > createTime){ @@ -447,8 +449,9 @@ int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, SMqData } code = tqReaderSetSubmitMsg(pReader, submit.msgStr, submit.msgLen, submit.ver, rawList); TSDB_CHECK_CODE(code, lino, END); - preProcessSubmitMsg(pHandle, pRequest, &rawList); - + if (pRequest->rawData) { + preProcessSubmitMsg(pHandle, pRequest, &rawList); + } // data could not contains same uid data in rawdata mode if (pRequest->rawData != 0 && terrno == TSDB_CODE_TMQ_RAW_DATA_SPLIT){ goto END; diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index 94bb254302..22ea60cd3d 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -449,6 +449,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_ts5466.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_td33504.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_ts-5473.py +,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_ts-5776.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/tmq_ts5906.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/td-32187.py ,,y,system-test,./pytest.sh python3 ./test.py -f 7-tmq/td-33225.py diff --git a/tests/system-test/7-tmq/tmq_ts-5776.py b/tests/system-test/7-tmq/tmq_ts-5776.py new file mode 100644 index 0000000000..738d69701f --- /dev/null +++ b/tests/system-test/7-tmq/tmq_ts-5776.py @@ -0,0 +1,39 @@ + +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +from util.common import * +from taos.tmq import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + updatecfgDict = {'debugFlag': 135, 'asynclog': 0} + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor()) + #tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def run(self): + buildPath = tdCom.getBuildPath() + cmdStr = '%s/build/bin/tmq_ts5776'%(buildPath) + tdLog.info(cmdStr) + os.system(cmdStr) + + return + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/utils/test/c/CMakeLists.txt b/utils/test/c/CMakeLists.txt index d1c049ef1e..d73f91aad3 100644 --- a/utils/test/c/CMakeLists.txt +++ b/utils/test/c/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(tmq_taosx_ci tmq_taosx_ci.c) add_executable(tmq_ts5466 tmq_ts5466.c) add_executable(tmq_td32526 tmq_td32526.c) add_executable(tmq_td32187 tmq_td32187.c) +add_executable(tmq_ts5776 tmq_ts5776.c) add_executable(tmq_td32471 tmq_td32471.c) add_executable(tmq_write_raw_test tmq_write_raw_test.c) add_executable(write_raw_block_test write_raw_block_test.c) @@ -87,6 +88,13 @@ target_link_libraries( PUBLIC common PUBLIC os ) +target_link_libraries( + tmq_ts5776 + PUBLIC ${TAOS_LIB} + PUBLIC util + PUBLIC common + PUBLIC os +) target_link_libraries( tmq_taosx_ci PUBLIC ${TAOS_LIB} diff --git a/utils/test/c/tmq_ts5776.c b/utils/test/c/tmq_ts5776.c new file mode 100644 index 0000000000..c50809bccd --- /dev/null +++ b/utils/test/c/tmq_ts5776.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include "cJSON.h" +#include "taos.h" +#include "tmsg.h" +#include "types.h" + +static TAOS* use_db() { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + if (pConn == NULL) { + return NULL; + } + + TAOS_RES* pRes = taos_query(pConn, "use db_dst"); + if (taos_errno(pRes) != 0) { + printf("error in use db_taosx, reason:%s\n", taos_errstr(pRes)); + return NULL; + } + taos_free_result(pRes); + return pConn; +} + +static void msg_process(TAOS_RES* msg) { + printf("-----------topic-------------: %s\n", tmq_get_topic_name(msg)); + printf("db: %s\n", tmq_get_db_name(msg)); + printf("vg: %d\n", tmq_get_vgroup_id(msg)); + TAOS* pConn = use_db(); + if (tmq_get_res_type(msg) == TMQ_RES_TABLE_META || tmq_get_res_type(msg) == TMQ_RES_METADATA) { + char* result = tmq_get_json_meta(msg); + printf("meta result: %s\n", result); + tmq_free_json_meta(result); + } + + tmq_raw_data raw = {0}; + tmq_get_raw(msg, &raw); + printf("write raw data type: %d\n", raw.raw_type); + int32_t ret = tmq_write_raw(pConn, raw); + printf("write raw data: %s\n", tmq_err2str(ret)); + ASSERT(ret == 0); + + tmq_free_raw(raw); + taos_close(pConn); +} + +int buildDatabase(TAOS* pConn, TAOS_RES* pRes) { + pRes = taos_query(pConn, + "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int, t3 " + "nchar(8), t4 bool)"); + if (taos_errno(pRes) != 0) { + printf("failed to create super table st1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query( + pConn, + "insert into ct3 using st1(t1) tags(3000) values(1626006833600, 5, 6, 'c') ct1 using st1(t1) tags(2000) values(1626006833601, 2, 3, 'sds') (1626006833602, 4, 5, " + "'ddd') ct0 using st1 tags(1000, \"ttt\", true) values(1626006833603, 4, 3, 'hwj') ct1 using st1(t1) tags(2000) values(now+5s, 23, 32, 's21ds')"); + if (taos_errno(pRes) != 0) { + printf("failed to insert into ct3, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query( + pConn, + "insert into ct3 values(1626006839602, 5, 6, 'c')"); + if (taos_errno(pRes) != 0) { + printf("failed to insert into ct3, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query( + pConn, + "insert into ct3 using st1(t1) tags(3000) values(1626006833602, 5, 6, 'c') ct1 values(1626006833611, 2, 3, 'sds') (1626006833612, 4, 5, " + "'ddd') ct10 using st1 tags(1000, \"ttt\", true) values(1626006833603, 4, 3, 'hwj')"); + if (taos_errno(pRes) != 0) { + printf("failed to insert into ct3, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + return 0; +} + +int32_t init_env() { + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + if (pConn == NULL) { + return -1; + } + + TAOS_RES* pRes = taos_query(pConn, "drop database if exists db_dst"); + if (taos_errno(pRes) != 0) { + printf("error in drop db_taosx, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "create database if not exists db_dst vgroups 1 wal_retention_period 3600"); + if (taos_errno(pRes) != 0) { + printf("error in create db_taosx, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "drop topic if exists topic_db"); + if (taos_errno(pRes) != 0) { + printf("error in drop topic, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "drop database if exists db_src"); + if (taos_errno(pRes) != 0) { + printf("error in drop db, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "create database if not exists db_src vgroups 1 wal_retention_period 3600"); + if (taos_errno(pRes) != 0) { + printf("error in create db, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "use db_src"); + if (taos_errno(pRes) != 0) { + printf("error in use db, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + buildDatabase(pConn, pRes); + + taos_close(pConn); + return 0; +} + +int32_t create_topic() { + printf("create topic\n"); + TAOS_RES* pRes; + TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); + if (pConn == NULL) { + return -1; + } + + pRes = taos_query(pConn, "create topic topic_db with meta as database db_src"); + if (taos_errno(pRes) != 0) { + printf("failed to create topic topic_db, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + taos_close(pConn); + return 0; +} + +void tmq_commit_cb_print(tmq_t* tmq, int32_t code, void* param) { + printf("commit %d tmq %p param %p\n", code, tmq, param); +} + +tmq_t* build_consumer() { + tmq_conf_t* conf = tmq_conf_new(); + tmq_conf_set(conf, "group.id", "tg2"); + tmq_conf_set(conf, "client.id", "my app 1"); + tmq_conf_set(conf, "td.connect.user", "root"); + tmq_conf_set(conf, "td.connect.pass", "taosdata"); + tmq_conf_set(conf, "msg.with.table.name", "true"); + tmq_conf_set(conf, "enable.auto.commit", "true"); + tmq_conf_set(conf, "auto.offset.reset", "earliest"); + tmq_conf_set(conf, "msg.consume.rawdata", "1"); + + tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL); + tmq_t* tmq = tmq_consumer_new(conf, NULL, 0); + assert(tmq); + tmq_conf_destroy(conf); + return tmq; +} + +tmq_list_t* build_topic_list() { + tmq_list_t* topic_list = tmq_list_new(); + tmq_list_append(topic_list, "topic_db"); + return topic_list; +} + +void basic_consume_loop(tmq_t* tmq, tmq_list_t* topics) { + int32_t code; + + if ((code = tmq_subscribe(tmq, topics))) { + fprintf(stderr, "%% Failed to start consuming topics: %s\n", tmq_err2str(code)); + printf("subscribe err\n"); + return; + } + int32_t cnt = 0; + while (1) { + TAOS_RES* tmqmessage = tmq_consumer_poll(tmq, 5000); + if (tmqmessage) { + cnt++; + msg_process(tmqmessage); + taos_free_result(tmqmessage); + } else { + break; + } + } + + code = tmq_consumer_close(tmq); + if (code) + fprintf(stderr, "%% Failed to close consumer: %s\n", tmq_err2str(code)); + else + fprintf(stderr, "%% Consumer closed\n"); +} + +void check_result(){ + TAOS* taos = use_db(); + TAOS_RES *res = taos_query(taos, "select * from st1"); + int code = taos_errno(res); + assert(code == 0); + int affectedRows = taos_affected_rows(res); + printf("affected rows %d\n", affectedRows); + assert(affectedRows == 10); + taos_free_result(res); + taos_close(taos); + +} +int main(int argc, char* argv[]) { + if (init_env() < 0) { + return -1; + } + create_topic(); + + tmq_t* tmq = build_consumer(); + tmq_list_t* topic_list = build_topic_list(); + basic_consume_loop(tmq, topic_list); + tmq_list_destroy(topic_list); +} From 551eb5bf41dcf27eec4a46f2c0ab6b0872b88766 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 17 Feb 2025 17:44:13 +0800 Subject: [PATCH 44/67] fix:[TS-5776]add test case --- source/common/src/msg/tmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 2e2a20f20d..3e24265876 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -11605,7 +11605,7 @@ void tDeleteMqRawDataRsp(SMqDataRsp *pRsp) { tOffsetDestroy(&pRsp->reqOffset); tOffsetDestroy(&pRsp->rspOffset); if (pRsp->rawData != NULL){ - taosMemoryFree(pRsp->rawData - sizeof(SMqRspHead)); + taosMemoryFree(POINTER_SHIFT(pRsp->rawData, - sizeof(SMqRspHead))); } } From d071f403288daaf51f28ed07ebcb32dea7572b46 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Tue, 18 Feb 2025 09:31:15 +0800 Subject: [PATCH 45/67] Fix review errors. --- include/util/tdef.h | 2 +- source/common/src/msg/tmsg.c | 2 -- source/dnode/mnode/impl/src/mndVgroup.c | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/include/util/tdef.h b/include/util/tdef.h index ee3284991f..36ef36260d 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -364,7 +364,7 @@ typedef enum ELogicConditionType { #define TSDB_MAX_REPLICA 5 #define TSDB_MAX_LEARNER_REPLICA 10 #define TSDB_SYNC_RESTORE_lEN 20 -#define TSDB_SYNC_APPLY_COMMIT_LEN 27 +#define TSDB_SYNC_APPLY_COMMIT_LEN 41 #define TSDB_SYNC_LOG_BUFFER_SIZE 4096 #define TSDB_SYNC_LOG_BUFFER_RETENTION 256 #define TSDB_SYNC_LOG_BUFFER_THRESHOLD (1024 * 1024 * 5) diff --git a/source/common/src/msg/tmsg.c b/source/common/src/msg/tmsg.c index 609e60e3e6..edaf7fa2c1 100644 --- a/source/common/src/msg/tmsg.c +++ b/source/common/src/msg/tmsg.c @@ -1432,8 +1432,6 @@ int32_t tSerializeSStatusReq(void *buf, int32_t bufLen, SStatusReq *pReq) { TAOS_CHECK_EXIT(tEncodeI32(&encoder, pload->learnerProgress)); TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->roleTimeMs)); TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->startTimeMs)); - TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncAppliedIndex)); - TAOS_CHECK_EXIT(tEncodeI64(&encoder, pload->syncCommitIndex)); } // mnode loads diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index ca48b23e6f..311beb0daa 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -1125,8 +1125,8 @@ static int32_t mndRetrieveVgroups(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *p return code; } - char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN] = {0}; - char buf[TSDB_SYNC_APPLY_COMMIT_LEN] = {0}; + char applyStr[TSDB_SYNC_APPLY_COMMIT_LEN + 1] = {0}; + char buf[TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE + 1] = {0}; snprintf(applyStr, sizeof(applyStr), "%" PRId64 "/%" PRId64, pVgroup->vnodeGid[i].syncAppliedIndex, pVgroup->vnodeGid[i].syncCommitIndex); STR_WITH_MAXSIZE_TO_VARSTR(buf, applyStr, pShow->pMeta->pSchemas[cols].bytes); @@ -1358,7 +1358,7 @@ static int32_t mndRetrieveVnodes(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB calculateRstoreFinishTime(pGid->appliedRate, unappliedCount, restoreStr, sizeof(restoreStr)); } STR_TO_VARSTR(buf, restoreStr); - colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false); + code = colDataSetVal(pColInfo, numOfRows, (const char *)&buf, false); if (code != 0) { mError("vgId:%d, failed to set syncRestore finish time, since %s", pVgroup->vgId, tstrerror(code)); return code; From e70be44c8c2e2219d1534aa25c023d8fdb9a09d9 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 18 Feb 2025 09:53:54 +0800 Subject: [PATCH 46/67] fix: reduce compa size from 1M to 36k with 2 table 2000 rows --- .../data0/test.3479004165561.0.avro | Bin 101667 -> 0 bytes .../data0/test.3479004165563.2.avro | Bin 101088 -> 0 bytes .../data0/test.3479004165566.4.avro | Bin 102709 -> 0 bytes .../data0/test.3479004165569.5.avro | Bin 101481 -> 0 bytes .../data0/test.3479004165572.6.avro | Bin 99447 -> 0 bytes .../data0/test.3479004165574.7.avro | Bin 100152 -> 0 bytes .../data0/test.3479004165576.8.avro | Bin 101096 -> 0 bytes .../data0/test.3479004165578.9.avro | Bin 103187 -> 0 bytes .../data0/test.3479004165610.3.avro | Bin 101581 -> 0 bytes .../data0/test.3479004165620.1.avro | Bin 102337 -> 0 bytes .../data0/test.3479684286962.0.avro | Bin 0 -> 11555 bytes .../data0/test.3479684286964.1.avro | Bin 0 -> 11521 bytes .../dbs.sql | 0 .../test.3479684286947.avro-tbtags} | Bin 541 -> 432 bytes .../tools/taosdump/native/taosdumpCompa.py | 6 +++--- 15 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165561.0.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165563.2.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165566.4.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165569.5.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165572.6.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165574.7.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165576.8.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165578.9.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165610.3.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165620.1.avro create mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286962.0.avro create mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286964.1.avro rename tests/army/tools/taosdump/native/compa/{taosdump.3479004165464 => taosdump.3479684286936}/dbs.sql (100%) rename tests/army/tools/taosdump/native/compa/{taosdump.3479004165464/test.3479004165475.avro-tbtags => taosdump.3479684286936/test.3479684286947.avro-tbtags} (59%) diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165561.0.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165561.0.avro deleted file mode 100644 index bd6659545a8b13b4a5ff1b24f25c0863a9e38289..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101667 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Ð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 Ry8r6SDic?Z9y~hw{{k9A)@A?z diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165563.2.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165563.2.avro deleted file mode 100644 index 1dc4853c134489e636f026ed08b931be9c40fea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101088 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

X7#R4aW$1+8 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 diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165566.4.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165566.4.avro deleted file mode 100644 index 6b9825f77ef564717abdadfea767a118ea523a3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102709 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 i)>)xJ(4w64@|sAvfcz6 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 KZr!<~um2x8<}`-@ diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165569.5.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165569.5.avro deleted file mode 100644 index 7465371600a8f714f985ca9c1ed97a0930d50e6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101481 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%0AU&q5ZVt7 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 a$`l2!pm5>&HGg}&?TNv+yyxfv(*G9^rvu~w diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165572.6.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165572.6.avro deleted file mode 100644 index f239d68fd8cd135ba069533f6e6a3896fbb9a744..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99447 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 V%r|gTF_>|1`R=xz4SnYd|37jdC!7EP diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165574.7.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165574.7.avro deleted file mode 100644 index 0d29e52cc5e2208eadb84389514e702313475b05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 100152 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 N`JbQoyHiJG|35^9lYjsK diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165610.3.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165610.3.avro deleted file mode 100644 index 4fd5995027e91e5f9e8fbf0f07bdc552011ca688..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101581 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

0z4ku=FrZIiDVe zqfF`H-U~fFOpDG)57YFo-uU0xmnJvB0Y{7BW2BX%>JdAlTfIIXZ9)Z2 zA-P$-BWVM23x1C53(Zgqbge5U%rfALt3oY3F~htKHlWXDJBC*8j0vT5#(bvkh5AH5 zsDg*c(|Q*sOLPxlMYl{DnXnR=3cWD{O&4Z#v1_LumPQ&FGC+t8;Zaa;VQ4Ol(4%_^ z=+OCb6cfYbs7^#^w{DtySP0H019tRYEA~mG=r4P~)(=w9P4f^1-86~M)=iVxtV!wN6)sDnl6;*2f-|u8&80Jn>h_rs1izE(o_1jnow{Zsx z;Wh|^)=!fdsOuB`RNQ3+yl4$tYz!8(Xnlp!T{<6_XdOmu3>E=Q>x3;EgGIF3KY*7N zb@$t*2#0ngB6%NtLXj$nK;8%cA*+B5)kB2}A<;K3IiwQ;gpb17WE(eI0T0@hDB`2A z6i7%hpFftI>THOk`XbYtHpe$fvP*%Dvd`&rEy0!N{HrnJ1;ayBe!izr^ z2q28g(wHr(53^#EsvWT_3{r7=FGD{9baXzrVQf}Y5>I)#Y0+0&mQ4zWEVOmSA9&VDe zn|fMx77W>e$A@dJ;CzFv8FuXL9DW*tE=-Sy3j+}XMOO3d2THmc95HN*F<1N-0}cbX z+@>3#7`rvh>(E!$vc*Pl!4)I8FpbxF16WhsXdAK^#idjAgovao0+)^A0xuiIMKrQe zTwAJ-jjb$%s0n5^iVMnY6xVjUZ#dH^t}A+TLCFSj!I?cjz)aVRfY~4}0JAw74%l|+ z(r%y?hH$Y6SgMIsY3-<09@A^4Kb`30AB@xC$sQiCWDgH$(lLfoRyqE)rsSezjYybl zTL4KrfYF9doo#`wN04j`*Fs*gmc3K1u%KkaxIjrq0+9{liVT_YA=@HIK9cJ${tPyf z3zqyT0!}&)82M8~7*$7dMTmSP*S(@`TssE?`Q85gXwDN>HYMrHT3r5mqAJShvVnXK? zj8UkHr1(?hRy!N0=%jF>0!nJbxj@CAB9RsC6EV?XE*McIfT(~Df0YP;gr@?4Xj5cE zYk;8wDtssxV5kBrRDgsJ<%&#bC>KEZP_EIK@PS+bi!f4aqn&Y+6~qjke+%cgfm~ay zqMr(Th1g~l+pXAP#ZET!h&UFE0C%xc4Ab-Mwyi)>8^{&IhELa!CnJpHf(+e49Tutt zh>SiAuVVlgL@<;qJyN*1cx6yBW|tDU2&1{6!e1Z&!$)($hCd@taTVDg4hfGi%ojX# ziO7c5z`}=f#TcUch=mX53S@+r2Do5;W$sW|FqUhvoi}3PW4T1eoae^;ki=4@Jr^$Y zk^mZdNq`G`NqER^D;F(zNdOBA@=#$f32v+Ykx*$<|Q;3nm-V|b>ur~#T3iC=?&62sCud&k$3C;}? zzXuD%j9-GE%7;jIwwF7u*&zDc0YvES03JN71BB1jaM(W25i5ul{%W95fe9ifj8yns z4Pc=Q0fh>M2b*gXDyT>+CkPL}tN)?T)IfyLH3$!-z7Y5oAE+3O2yFuge;tTKs2&{r zbzmh+)tMRqZIzu9DEy`1KDOH=%MlD_YDjknpPB%N`=o$}P7NC#>A}P2YJd=bC5TbO zCu&${M-e!DqK1uDLEP|(8e-rW&Hk{|69WHsJ938=JFVDd#cnJ1a8^qX@f`7q8UiFC zf)h1}?#VGl5Mjcn0TUH9^OA}*%yLB;faLD8hOKL~D@_Q}@6zzgJfS z57YM0VcLF+9UmVoI)0l~Mlx)62L8Tvc$l&W5FG~{ChLJi>yTlxK4P(dK=%>Ba7|C} za80lHVY6{YJY3TYkE*7RfVie7h`6SQ5iXuqPAdNz1p8bL{5_Z+Uc&Dt-37Xl@XN_n OS3L2~ca7`-{r>@~k$3n2 diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165620.1.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479004165464/data0/test.3479004165620.1.avro deleted file mode 100644 index 59dafef4e6ff6f598f663725b956838be553a57c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102337 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

NFjAwr~`*aEE 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�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∈FVvTx^sf&Lv+Uj07w}_ AYXATM diff --git a/tests/army/tools/taosdump/native/taosdumpCompa.py b/tests/army/tools/taosdump/native/taosdumpCompa.py index 30088a1f6e..f219f748c4 100644 --- a/tests/army/tools/taosdump/native/taosdumpCompa.py +++ b/tests/army/tools/taosdump/native/taosdumpCompa.py @@ -71,9 +71,9 @@ class TDTestCase(TBase): # compare sum(pk) stb = "meters" - self.checkSame(db, stb, "count(ts)", 100000) - self.checkSame(db, stb, "sum(current)", 1005767.2491703) - self.checkSame(db, stb, "avg(voltage)", 208.58818) + self.checkSame(db, stb, "count(ts)", 2000) + self.checkSame(db, stb, "sum(current)", 20241.627464294433594) + self.checkSame(db, stb, "avg(voltage)", 209.538000000000011) def run(self): # database From cbfc52427e3f36efc426dc0fd445ec5d30cc8cc2 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 18 Feb 2025 11:10:11 +0800 Subject: [PATCH 47/67] fix: stream and columns in targets issue --- source/libs/planner/src/planLogicCreater.c | 2 +- source/libs/planner/src/planOptimizer.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 0eef305bc0..96623d406d 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -407,7 +407,7 @@ static int32_t makeScanLogicNode(SLogicPlanContext* pCxt, SRealTableNode* pRealT static bool needScanDefaultCol(EScanType scanType) { return SCAN_TYPE_TABLE_COUNT != scanType; } static int32_t updateScanNoPseudoRefAfterGrp(SSelectStmt* pSelect, SScanLogicNode* pScan, SRealTableNode* pRealTable) { - if (NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0) { + if (NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0 || NULL != pSelect->pTags) { return TSDB_CODE_SUCCESS; } diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index e132ce5ee6..a3fa5a3d7c 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -3307,6 +3307,16 @@ static int32_t partTagsOptRemovePseudoCols(SScanLogicNode* pScan) { return TSDB_CODE_SUCCESS; } + SNode* pNode = NULL, *pTarget = NULL; + FOREACH(pNode, pScan->pScanPseudoCols) { + FOREACH(pTarget, pScan->node.pTargets) { + if (0 == strcmp(((SExprNode*)pNode)->aliasName, ((SColumnNode*)pTarget)->colName)) { + ERASE_NODE(pScan->node.pTargets); + break; + } + } + } + nodesDestroyList(pScan->pScanPseudoCols); pScan->pScanPseudoCols = NULL; From 9dcac195cb384934c7999641ccac16d910af14f4 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 18 Feb 2025 11:20:42 +0800 Subject: [PATCH 48/67] fix:[TS-5776]error in ci --- source/client/src/clientRawBlockWrite.c | 2 +- source/dnode/vnode/src/tq/tqScan.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/client/src/clientRawBlockWrite.c b/source/client/src/clientRawBlockWrite.c index 705ce14911..e99d5c2e83 100644 --- a/source/client/src/clientRawBlockWrite.c +++ b/source/client/src/clientRawBlockWrite.c @@ -2608,7 +2608,7 @@ void tmq_free_raw(tmq_raw_data raw) { raw.raw_type == RES_TYPE__TMQ_METADATA) { taosMemoryFree(raw.raw); } else if(raw.raw_type == RES_TYPE__TMQ_RAWDATA && raw.raw != NULL){ - taosMemoryFree(raw.raw - sizeof(SMqRspHead)); + taosMemoryFree(POINTER_SHIFT(raw.raw, - sizeof(SMqRspHead))); } (void)memset(terrMsg, 0, ERR_MSG_LEN); } diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index d43afc9ebd..e0c746c0e7 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -31,8 +31,9 @@ static int32_t tqAddRawDataToRsp(const void* rawData, SMqDataRsp* pRsp, int8_t p memcpy(pRetrieve->data, rawData, *(uint32_t *)rawData + INT_BYTES); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &dataStrLen), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); + pRsp->blockDataElementFree = true; - tqTrace("add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); + tqTrace("tqAddRawDataToRsp add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); END: if (code != TSDB_CODE_SUCCESS) { taosMemoryFree(buf); @@ -63,12 +64,13 @@ static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, TSDB_CHECK_NULL(taosArrayPush(pRsp->blockDataLen, &actualLen), code, lino, END, terrno); TSDB_CHECK_NULL(taosArrayPush(pRsp->blockData, &buf), code, lino, END, terrno); pRsp->blockDataElementFree = true; - buf = NULL; + tqTrace("tqAddBlockDataToRsp add block data to block array, blockDataLen:%d, blockData:%p", dataStrLen, buf); + END: - if (code != 0){ + if (code != TSDB_CODE_SUCCESS){ + taosMemoryFree(buf); tqError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code)); } - taosMemoryFree(buf); return code; } @@ -400,10 +402,6 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, return; } - if (pSubmitTbData->pCreateTbReq == NULL){ - continue; - } - int64_t uid = pSubmitTbData->uid; if (taosHashGet(pRequest->uidHash, &uid, LONG_BYTES) != NULL) { tqDebug("poll rawdata split,uid:%" PRId64 " is already exists", uid); @@ -416,6 +414,10 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, } } + if (pSubmitTbData->pCreateTbReq == NULL){ + continue; + } + int64_t createTime = 0; int64_t *cTime = (int64_t*)taosHashGet(pHandle->tableCreateTimeHash, &uid, LONG_BYTES); if (cTime != NULL){ From 25a1af2b883c3d8f72e6357d5d3f4d1cd4d423e8 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Tue, 18 Feb 2025 12:28:07 +0800 Subject: [PATCH 49/67] Fix ci problems. --- tests/script/tsim/dnode/redistribute_vgroup_replica3_v3.sim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v3.sim b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v3.sim index 30e644f170..b3746dfcf4 100644 --- a/tests/script/tsim/dnode/redistribute_vgroup_replica3_v3.sim +++ b/tests/script/tsim/dnode/redistribute_vgroup_replica3_v3.sim @@ -136,13 +136,13 @@ if $data(2)[4] == leader then $follower1 = 3 $follower2 = 4 endi -if $data(2)[6] == leader then +if $data(2)[7] == leader then $leaderExist = 1 $leaderVnode = 3 $follower1 = 2 $follower2 = 4 endi -if $data(2)[8] == leader then +if $data(2)[10] == leader then $leaderExist = 1 $leaderVnode = 4 $follower1 = 2 From 9af22f18f7008956bd5e0c069c8a2af6a21f3263 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 18 Feb 2025 14:38:59 +0800 Subject: [PATCH 50/67] fix: taosdumpCompa.py add full type data check --- .../data0/test.3479684286962.0.avro | Bin 11555 -> 0 bytes .../data0/test.3479684286964.1.avro | Bin 11521 -> 0 bytes .../compa/taosdump.3479684286936/dbs.sql | 10 ----- .../test.3479684286947.avro-tbtags | Bin 432 -> 0 bytes .../data0/test.3479698875538.0.avro | Bin 0 -> 322063 bytes .../compa/taosdump.3479698875513/dbs.sql | 10 +++++ .../test.3479698875523.avro-tbtags | Bin 0 -> 1213 bytes .../tools/taosdump/native/taosdumpCompa.py | 38 ++++++++++++++---- 8 files changed, 40 insertions(+), 18 deletions(-) delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286962.0.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286964.1.avro delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/dbs.sql delete mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479684286936/test.3479684286947.avro-tbtags create mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479698875513/data0/test.3479698875538.0.avro create mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479698875513/dbs.sql create mode 100644 tests/army/tools/taosdump/native/compa/taosdump.3479698875513/test.3479698875523.avro-tbtags diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286962.0.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479684286936/data0/test.3479684286962.0.avro deleted file mode 100644 index e810258dda722261122730623e5bf8a52728519f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11555 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�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 diff --git a/tests/army/tools/taosdump/native/compa/taosdump.3479698875513/data0/test.3479698875538.0.avro b/tests/army/tools/taosdump/native/compa/taosdump.3479698875513/data0/test.3479698875538.0.avro new file mode 100644 index 0000000000000000000000000000000000000000..3c2ecc1e03ff81dede7cac9a781ea693672c1ed1 GIT binary patch literal 322063 zcmb@u33O9s_ceZV`lL9+EPk;Wu}DNG@U3-I?rQT(m_ZAW)Ucp2#6G!L<9#s5E1zAl;8hb>-P<7z3W?_tR+x-Z|;4b^X#+F zKKnGI&?aH-=BB!8O;L4mNs()PmAR&-Ro(xU`XWn7rFn+(MWLa!rbL)1)Rh!f*A)x? zLY2AF{`VLD+ZXC<%tiLEHk8yi;Co7~B^AZ>!o+7^{Qtkbp|Jlt|Npuj{^7swTh&-m zA-wGWKmK0dP-m?w6JCDK{d%_kVd^(EsIi!T-T^|Jxl2 z`428M*VUO@@qN~Yl1fC;|A>wL7yoaOfo%%?e|^KS|JOGR_)ntn|MbpJ7x907>45(v zIRAG?$sX7LNq82v;wamr^SPI~i?N-n$ENugDc}3zV9UJI{MXK%A4>0SVtq-(ibZPg zTL1V#A#t>NNvxiJ8SnE${nW<>S}CF7)Tf|nZp3a#9!of4`yV?ze&T>X+_?SZiQD5R z_#ghVV>SLDao{8pl~fXo?~|2e#AJ~&pdi^8Sk)LKwXxn!3Y%ry7bXKaE2V*}FWoiJ zzbS)0bE0DkV$VL7SlGcQ3X5#bohP0ac4M=23io89h0}$Z>WWF3Us4tmm)p=FwXm+e zQcHz|P73GsWcm3>kkmLVlBUuO34QBAt;CkdPjbr#SlNZXp;oqNnbFGWLX*Rcq^!

~Jb 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 Date: Tue, 18 Feb 2025 14:47:49 +0800 Subject: [PATCH 51/67] Update index.md --- docs/zh/06-advanced/06-TDgpt/04-forecast/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/06-advanced/06-TDgpt/04-forecast/index.md b/docs/zh/06-advanced/06-TDgpt/04-forecast/index.md index bbfd108491..bf2697d46b 100644 --- a/docs/zh/06-advanced/06-TDgpt/04-forecast/index.md +++ b/docs/zh/06-advanced/06-TDgpt/04-forecast/index.md @@ -141,5 +141,5 @@ gen_figure = true 如果设置了 `gen_figure` 为 true,分析结果中还会有绘制的分析预测结果图(如下图所示)。 -预测对比结果 +预测对比结果 From c26d0903dfe78a4cd90ecbfa7fd9aec4ca21332c Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Tue, 18 Feb 2025 14:48:25 +0800 Subject: [PATCH 52/67] Update index.md --- docs/zh/06-advanced/06-TDgpt/05-anomaly-detection/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/06-advanced/06-TDgpt/05-anomaly-detection/index.md b/docs/zh/06-advanced/06-TDgpt/05-anomaly-detection/index.md index 7eff427518..4802fa2e4f 100644 --- a/docs/zh/06-advanced/06-TDgpt/05-anomaly-detection/index.md +++ b/docs/zh/06-advanced/06-TDgpt/05-anomaly-detection/index.md @@ -102,5 +102,5 @@ lof={"algo":"auto", "n_neighbor": 3} 如果设置了 `gen_figure` 为 `true`,比较程序会自动将每个参与比较的算法分析结果采用图片方式呈现出来(如下图所示为 ksigma 的异常检测结果标注)。 -异常检测标注图 +异常检测标注图 From b4927ca10a7a17643d4bb5d630110c7f1dcfaf15 Mon Sep 17 00:00:00 2001 From: xiao-77 Date: Tue, 18 Feb 2025 15:06:38 +0800 Subject: [PATCH 53/67] Fix some review errors. --- source/common/src/systable.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 44ae0b2faf..cb7672a3b8 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -292,16 +292,16 @@ static const SSysDbTableSchema vgroupsSchema[] = { {.name = "tables", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "v1_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, {.name = "v1_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, - {.name = "v1_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v1_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v2_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, {.name = "v2_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, - {.name = "v2_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v2_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v3_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, {.name = "v3_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, - {.name = "v3_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v3_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "v4_dnode", .bytes = 2, .type = TSDB_DATA_TYPE_SMALLINT, .sysInfo = true}, {.name = "v4_status", .bytes = 9 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, - {.name = "v4_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, + {.name = "v4_applied/committed", .bytes = TSDB_SYNC_APPLY_COMMIT_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = true}, {.name = "cacheload", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "cacheelements", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = true}, {.name = "tsma", .bytes = 1, .type = TSDB_DATA_TYPE_TINYINT, .sysInfo = true}, From 07e4265dde85c2b88c054f5bec432531372a8896 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 18 Feb 2025 15:21:51 +0800 Subject: [PATCH 54/67] fix:[TS-5776]error in create table time --- source/dnode/vnode/src/meta/metaQuery.c | 2 +- source/dnode/vnode/src/tq/tqRead.c | 1 - source/dnode/vnode/src/tq/tqScan.c | 10 ++++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/dnode/vnode/src/meta/metaQuery.c b/source/dnode/vnode/src/meta/metaQuery.c index 7b866d9230..169adf219f 100644 --- a/source/dnode/vnode/src/meta/metaQuery.c +++ b/source/dnode/vnode/src/meta/metaQuery.c @@ -457,7 +457,7 @@ int64_t metaGetTableCreateTime(SMeta *pMeta, tb_uid_t uid, int lock) { int nData = 0; int64_t version = 0; SDecoder dc = {0}; - int64_t createTime = 0; + int64_t createTime = INT64_MAX; if (lock) { metaRLock(pMeta); } diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index f01a35d58f..d650ae9751 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -1102,7 +1102,6 @@ int32_t tqRetrieveTaosxBlock(STqReader* pReader, SMqDataRsp* pRsp, SArray* block int64_t uid = pSubmitTbData->uid; pReader->lastBlkUid = uid; - int64_t createTime = 0; tDeleteSchemaWrapper(pReader->pSchemaWrapper); pReader->pSchemaWrapper = metaGetTableSchema(pReader->pVnodeMeta, uid, sversion, 1); if (pReader->pSchemaWrapper == NULL) { diff --git a/source/dnode/vnode/src/tq/tqScan.c b/source/dnode/vnode/src/tq/tqScan.c index e0c746c0e7..b109be5626 100644 --- a/source/dnode/vnode/src/tq/tqScan.c +++ b/source/dnode/vnode/src/tq/tqScan.c @@ -418,15 +418,17 @@ static void preProcessSubmitMsg(STqHandle* pHandle, const SMqPollReq* pRequest, continue; } - int64_t createTime = 0; + int64_t createTime = INT64_MAX; int64_t *cTime = (int64_t*)taosHashGet(pHandle->tableCreateTimeHash, &uid, LONG_BYTES); if (cTime != NULL){ createTime = *cTime; } else{ createTime = metaGetTableCreateTime(pReader->pVnodeMeta, uid, 1); - int32_t code = taosHashPut(pHandle->tableCreateTimeHash, &uid, LONG_BYTES, &createTime, LONG_BYTES); - if (code != 0){ - tqError("failed to add table create time to hash,code:%d, uid:%"PRId64, code, uid); + if (createTime != INT64_MAX){ + int32_t code = taosHashPut(pHandle->tableCreateTimeHash, &uid, LONG_BYTES, &createTime, LONG_BYTES); + if (code != 0){ + tqError("failed to add table create time to hash,code:%d, uid:%"PRId64, code, uid); + } } } if (pHandle->fetchMeta == WITH_DATA || pSubmitTbData->ctimeMs > createTime){ From 2a18be6e2353f4b931f7f69ec45272571add5246 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Tue, 18 Feb 2025 15:41:02 +0800 Subject: [PATCH 55/67] docs: format --- docs/zh/14-reference/03-taos-sql/14-stream.md | 198 +++++++++--------- 1 file changed, 100 insertions(+), 98 deletions(-) diff --git a/docs/zh/14-reference/03-taos-sql/14-stream.md b/docs/zh/14-reference/03-taos-sql/14-stream.md index e255102f76..d729a7e596 100644 --- a/docs/zh/14-reference/03-taos-sql/14-stream.md +++ b/docs/zh/14-reference/03-taos-sql/14-stream.md @@ -30,11 +30,11 @@ subquery: SELECT select_list window_clause ``` -支持会话窗口、状态窗口、滑动窗口、事件窗口和计数窗口,其中,状态窗口、事件窗口和计数窗口搭配超级表时必须与partition by tbname一起使用。对于数据源表是复合主键的流,不支持状态窗口、事件窗口、计数窗口的计算。 +支持会话窗口、状态窗口、滑动窗口、事件窗口和计数窗口。其中,状态窗口、事件窗口和计数窗口搭配超级表时必须与 partition by tbname 一起使用。对于数据源表是复合主键的流,不支持状态窗口、事件窗口、计数窗口的计算。 -stb_name 是保存计算结果的超级表的表名,如果该超级表不存在,会自动创建;如果已存在,则检查列的schema信息。详见 写入已存在的超级表。 +stb_name 是保存计算结果的超级表的表名,如果该超级表不存在,会自动创建;如果已存在,则检查列的schema信息。详见 [写入已存在的超级表](#写入已存在的超级表) 。 -TAGS 子句定义了流计算中创建TAG的规则,可以为每个partition对应的子表生成自定义的TAG值,详见 自定义TAG +TAGS 子句定义了流计算中创建TAG的规则,可以为每个 partition 对应的子表生成自定义的TAG值,详见 [自定义 TAG](#自定义 TAG) ```sql create_definition: col_name column_definition @@ -42,7 +42,7 @@ column_definition: type_name [COMMENT 'string_value'] ``` -subtable 子句定义了流式计算中创建的子表的命名规则,详见 流式计算的 partition 部分。 +subtable 子句定义了流式计算中创建的子表的命名规则,详见 [流式计算的 partition](#流式计算的 partitionG)。 ```sql window_clause: { @@ -54,23 +54,25 @@ window_clause: { } ``` -其中,SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口。该窗口的 _wend 等于最后一条数据的时间加上 tol_val。 +其中: -STATE_WINDOW 是状态窗口,col 用来标识状态量,相同的状态量数值则归属于同一个状态窗口,col 数值改变后则当前窗口结束,自动开启下一个窗口。 +- SESSION 是会话窗口,tol_val 是时间间隔的最大范围。在 tol_val 时间间隔范围内的数据都属于同一个窗口,如果连续的两条数据的时间超过 tol_val,则自动开启下一个窗口。该窗口的 _wend 等于最后一条数据的时间加上 tol_val。 -INTERVAL 是时间窗口,又可分为滑动时间窗口和翻转时间窗口。INTERVAL 子句用于指定窗口相等时间周期,SLIDING 字句用于指定窗口向前滑动的时间。当 interval_val 与 sliding_val 相等的时候,时间窗口即为翻转时间窗口,否则为滑动时间窗口,注意:sliding_val 必须小于等于 interval_val。 +- STATE_WINDOW 是状态窗口,col 用来标识状态量,相同的状态量数值则归属于同一个状态窗口,col 数值改变后则当前窗口结束,自动开启下一个窗口。 -EVENT_WINDOW 是事件窗口,根据开始条件和结束条件来划定窗口。当 start_trigger_condition 满足时则窗口开始,直到 end_trigger_condition 满足时窗口关闭。 start_trigger_condition 和 end_trigger_condition 可以是任意 TDengine 支持的条件表达式,且可以包含不同的列。 +- INTERVAL 是时间窗口,又可分为滑动时间窗口和翻转时间窗口。INTERVAL 子句用于指定窗口相等时间周期,SLIDING 字句用于指定窗口向前滑动的时间。当 interval_val 与 sliding_val 相等的时候,时间窗口即为翻转时间窗口,否则为滑动时间窗口,注意:sliding_val 必须小于等于 interval_val。 -COUNT_WINDOW 是计数窗口,按固定的数据行数来划分窗口。 count_val 是常量,是正整数,必须大于等于2,小于2147483648。 count_val 表示每个 COUNT_WINDOW 包含的最大数据行数,总数据行数不能整除 count_val 时,最后一个窗口的行数会小于 count_val 。 sliding_val 是常量,表示窗口滑动的数量,类似于 INTERVAL 的 SLIDING 。 +- EVENT_WINDOW 是事件窗口,根据开始条件和结束条件来划定窗口。当 start_trigger_condition 满足时则窗口开始,直到 end_trigger_condition 满足时窗口关闭。 start_trigger_condition 和 end_trigger_condition 可以是任意 TDengine 支持的条件表达式,且可以包含不同的列。 + +- COUNT_WINDOW 是计数窗口,按固定的数据行数来划分窗口。 count_val 是常量,是正整数,必须大于等于2,小于2147483648。 count_val 表示每个 COUNT_WINDOW 包含的最大数据行数,总数据行数不能整除 count_val 时,最后一个窗口的行数会小于 count_val 。 sliding_val 是常量,表示窗口滑动的数量,类似于 INTERVAL 的 SLIDING 。 窗口的定义与时序数据特色查询中的定义完全相同,详见 [TDengine 特色查询](../distinguished) 例如,如下语句创建流式计算。第一个流计算,自动创建名为 avg_vol 的超级表,以一分钟为时间窗口、30 秒为前向增量统计这些电表的平均电压,并将来自 meters 表的数据的计算结果写入 avg_vol 表,不同 partition 的数据会分别创建子表并写入不同子表。 -第二个流计算,自动创建名为 streamt0 的超级表,将数据按时间戳的顺序,以 voltage < 0 作为窗口的开始条件,voltage > 9作为窗口的结束条件,划分窗口做聚合运算,并将来自 meters 表的数据的计算结果写入 streamt0 表,不同 partition 的数据会分别创建子表并写入不同子表。 +第二个流计算,自动创建名为 streamt0 的超级表,将数据按时间戳的顺序,以 voltage < 0 作为窗口的开始条件,voltage > 9 作为窗口的结束条件,划分窗口做聚合运算,并将来自 meters 表的数据的计算结果写入 streamt0 表,不同 partition 的数据会分别创建子表并写入不同子表。 -第三个流计算,自动创建名为 streamt1 的超级表,将数据按时间戳的顺序,以10条数据为一组,划分窗口做聚合运算,并将来自 meters 表的数据的计算结果写入 streamt1 表,不同 partition 的数据会分别创建子表并写入不同子表。 +第三个流计算,自动创建名为 streamt1 的超级表,将数据按时间戳的顺序,以 10 条数据为一组,划分窗口做聚合运算,并将来自 meters 表的数据的计算结果写入 streamt1 表,不同 partition 的数据会分别创建子表并写入不同子表。 ```sql CREATE STREAM avg_vol_s INTO avg_vol AS @@ -83,7 +85,7 @@ CREATE STREAM streams1 IGNORE EXPIRED 1 WATERMARK 100s INTO streamt1 AS SELECT _wstart, count(*), avg(voltage) from meters PARTITION BY tbname COUNT_WINDOW(10); ``` -notification_definition 子句定义了窗口计算过程中,在窗口打开/关闭等指定事件发生时,需要向哪些地址发送通知。详见 [流式计算的事件通知](#流失计算的事件通知) +notification_definition 子句定义了窗口计算过程中,在窗口打开/关闭等指定事件发生时,需要向哪些地址发送通知。详见 [流式计算的事件通知](#流式计算的事件通知) ## 流式计算的 partition @@ -99,19 +101,19 @@ notification_definition 子句定义了窗口计算过程中,在窗口打开/ CREATE STREAM avg_vol_s INTO avg_vol SUBTABLE(CONCAT('new-', tname)) AS SELECT _wstart, count(*), avg(voltage) FROM meters PARTITION BY tbname tname INTERVAL(1m); ``` -PARTITION 子句中,为 tbname 定义了一个别名 tname, 在PARTITION 子句中的别名可以用于 SUBTABLE 子句中的表达式计算,在上述示例中,流新创建的子表将以前缀 'new-' 连接原表名作为表名(从3.2.3.0开始,为了避免 SUBTABLE 中的表达式无法区分各个子表,即误将多个相同时间线写入一个子表,在指定的子表名后面加上 _stableName_groupId)。 +PARTITION 子句中,为 tbname 定义了一个别名 tname, 在 PARTITION 子句中的别名可以用于 SUBTABLE 子句中的表达式计算,在上述示例中,流新创建的子表将以前缀 'new-' 连接原表名作为表名(从 3.2.3.0 版本开始,为了避免 SUBTABLE 中的表达式无法区分各个子表,即误将多个相同时间线写入一个子表,在指定的子表名后面加上 _stableName_groupId)。 注意,子表名的长度若超过 TDengine 的限制,将被截断。若要生成的子表名已经存在于另一超级表,由于 TDengine 的子表名是唯一的,因此对应新子表的创建以及数据的写入将会失败。 ## 流式计算读取历史数据 -正常情况下,流式计算不会处理创建前已经写入源表中的数据,若要处理已经写入的数据,可以在创建流时设置 fill_history 1 选项,这样创建的流式计算会自动处理创建前、创建中、创建后写入的数据。流计算处理历史数据的最大窗口数是2000万,超过限制会报错。例如: +正常情况下,流式计算不会处理创建前已经写入源表中的数据,若要处理已经写入的数据,可以在创建流时设置 fill_history 1 选项,这样创建的流式计算会自动处理创建前、创建中、创建后写入的数据。流计算处理历史数据的最大窗口数是 2000万,超过限制会报错。例如: ```sql create stream if not exists s1 fill_history 1 into st1 as select count(*) from t1 interval(10s) ``` -结合 fill_history 1 选项,可以实现只处理特定历史时间范围的数据,例如:只处理某历史时刻(2020年1月30日)之后的数据 +结合 fill_history 1 选项,可以实现只处理特定历史时间范围的数据,例如:只处理某历史时刻(2020 年 1 月 30 日)之后的数据 ```sql create stream if not exists s1 fill_history 1 into st1 as select count(*) from t1 where ts > '2020-01-30' interval(10s) @@ -156,7 +158,7 @@ SELECT * from information_schema.`ins_streams`; 2. WINDOW_CLOSE:窗口关闭时触发(窗口关闭由事件时间决定,可配合 watermark 使用) 3. MAX_DELAY time:若窗口关闭,则触发计算。若窗口未关闭,且未关闭时长超过 max delay 指定的时间,则触发计算。 -4. FORCE_WINDOW_CLOSE:以操作系统当前时间为准,只计算当前关闭窗口的结果,并推送出去。窗口只会在被关闭的时刻计算一次,后续不会再重复计算。该模式当前只支持 INTERVAL 窗口(不支持滑动);FILL_HISTORY 必须为 0,IGNORE EXPIRED 必须为 1,IGNORE UPDATE 必须为 1;FILL 只支持 PREV 、NULL、NONE、VALUE。 +4. FORCE_WINDOW_CLOSE:以操作系统当前时间为准,只计算当前关闭窗口的结果,并推送出去。窗口只会在被关闭的时刻计算一次,后续不会再重复计算。该模式当前只支持 INTERVAL 窗口(不支持滑动);FILL_HISTORY 必须为 0,IGNORE EXPIRED 必须为 1,IGNORE UPDATE 必须为 1;FILL 只支持 PREV、NULL、NONE、VALUE。 由于窗口关闭是由事件时间决定的,如事件流中断、或持续延迟,则事件时间无法更新,可能导致无法得到最新的计算结果。 @@ -217,33 +219,33 @@ TDengine 对于修改数据提供两种处理方式,由 IGNORE UPDATE 选项 ## 写入已存在的超级表 ```sql -[field1_name,...] +[field1_name, ...] ``` -在本页文档顶部的 [field1_name,...] 是用来指定 stb_name 的列与 subquery 输出结果的对应关系的。如果 stb_name 的列与 subquery 输出结果的位置、数量全部匹配,则不需要显示指定对应关系。如果 stb_name 的列与 subquery 输出结果的数据类型不匹配,会把 subquery 输出结果的类型转换成对应的 stb_name 的列的类型。创建流计算时不能指定 stb_name 的列和 TAG 的数据类型,否则会报错。 +在本页文档顶部的 [field1_name, ...] 是用来指定 stb_name 的列与 subquery 输出结果的对应关系的。如果 stb_name 的列与 subquery 输出结果的位置、数量全部匹配,则不需要显示指定对应关系。如果 stb_name 的列与 subquery 输出结果的数据类型不匹配,会把 subquery 输出结果的类型转换成对应的 stb_name 的列的类型。创建流计算时不能指定 stb_name 的列和 TAG 的数据类型,否则会报错。 对于已经存在的超级表,检查列的schema信息 1. 检查列的 schema 信息是否匹配,对于不匹配的,则自动进行类型转换,当前只有数据长度大于 4096byte 时才报错,其余场景都能进行类型转换。 2. 检查列的个数是否相同,如果不同,需要显示的指定超级表与 subquery 的列的对应关系,否则报错;如果相同,可以指定对应关系,也可以不指定,不指定则按位置顺序对应。 -## 自定义TAG +## 自定义 TAG -用户可以为每个 partition 对应的子表生成自定义的TAG值。 +用户可以为每个 partition 对应的子表生成自定义的 TAG 值。 ```sql -CREATE STREAM streams2 trigger at_once INTO st1 TAGS(cc varchar(100)) as select _wstart, count(*) c1 from st partition by concat("tag-", tbname) as cc interval(10s)); +CREATE STREAM streams2 trigger at_once INTO st1 TAGS(cc varchar(100)) as select _wstart, count(*) c1 from st partition by concat("tag-", tbname) as cc interval(10s)); ``` -PARTITION 子句中,为 concat("tag-", tbname)定义了一个别名cc, 对应超级表st1的自定义TAG的名字。在上述示例中,流新创建的子表的TAG将以前缀 'new-' 连接原表名作为TAG的值。 +PARTITION 子句中,为 concat("tag-", tbname) 定义了一个别名 cc,对应超级表 st1 的自定义 TAG 的名字。在上述示例中,流新创建的子表的 TAG 将以前缀 'new-' 连接原表名作为 TAG 的值。 会对TAG信息进行如下检查 -1. 检查tag的schema信息是否匹配,对于不匹配的,则自动进行数据类型转换,当前只有数据长度大于4096byte时才报错,其余场景都能进行类型转换。 -2. 检查tag的个数是否相同,如果不同,需要显示的指定超级表与subquery的tag的对应关系,否则报错;如果相同,可以指定对应关系,也可以不指定,不指定则按位置顺序对应。 +1. 检查 tag 的 schema 信息是否匹配,对于不匹配的,则自动进行数据类型转换,当前只有数据长度大于 4096byte 时才报错,其余场景都能进行类型转换。 +2. 检查 tag 的个数是否相同,如果不同,需要显示的指定超级表与 subquery 的 tag 的对应关系,否则报错;如果相同,可以指定对应关系,也可以不指定,不指定则按位置顺序对应。 ## 清理中间状态 ``` -DELETE_MARK time +DELETE_MARK time ``` -DELETE_MARK用于删除缓存的窗口状态,也就是删除流计算的中间结果。如果不设置,默认值是10年 +DELETE_MARK 用于删除缓存的窗口状态,也就是删除流计算的中间结果。如果不设置,默认值是 10 年 T = 最新事件时间 - DELETE_MARK ## 流式计算支持的函数 @@ -274,15 +276,15 @@ T = 最新事件时间 - DELETE_MARK ## 暂停、恢复流计算 1.流计算暂停计算任务 PAUSE STREAM [IF EXISTS] stream_name; -没有指定IF EXISTS,如果该stream不存在,则报错;如果存在,则暂停流计算。指定了IF EXISTS,如果该stream不存在,则返回成功;如果存在,则暂停流计算 +没有指定 IF EXISTS,如果该 stream 不存在,则报错;如果存在,则暂停流计算。指定了 IF EXISTS,如果该 stream 不存在,则返回成功;如果存在,则暂停流计算。 2.流计算恢复计算任务 RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name; -没有指定IF EXISTS,如果该stream不存在,则报错,如果存在,则恢复流计算;指定了IF EXISTS,如果stream不存在,则返回成功;如果存在,则恢复流计算。如果指定IGNORE UNTREATED,则恢复流计算时,忽略流计算暂停期间写入的数据。 +没有指定 IF EXISTS,如果该 stream 不存在,则报错,如果存在,则恢复流计算;指定了 IF EXISTS,如果 stream 不存在,则返回成功;如果存在,则恢复流计算。如果指定 IGNORE UNTREATED,则恢复流计算时,忽略流计算暂停期间写入的数据。 ## 状态数据备份与同步 -流计算的中间结果成为计算的状态数据,需要在流计算整个生命周期中进行持久化保存。为了确保流计算中间状态能够在集群环境下在不同的节点间可靠地同步和迁移,至3.3.2.1 版本开始,需要在运行环境中部署 rsync 软件,还需要增加以下的步骤: -1. 在配置文件中配置 snode 的地址(IP+端口)和状态数据备份目录(该目录系 snode 所在的物理节点的目录)。 +流计算的中间结果成为计算的状态数据,需要在流计算整个生命周期中进行持久化保存。为了确保流计算中间状态能够在集群环境下在不同的节点间可靠地同步和迁移,从 3.3.2.1 版本开始,需要在运行环境中部署 rsync 软件,还需要增加以下的步骤: +1. 在配置文件中配置 snode 的地址(IP + 端口)和状态数据备份目录(该目录系 snode 所在的物理节点的目录)。 2. 然后创建 snode。 完成上述两个步骤以后才能创建流。 如果没有创建 snode 并正确配置 snode 的地址,流计算过程中将无法生成检查点(checkpoint),并可能导致后续的计算结果产生错误。 @@ -293,7 +295,7 @@ RESUME STREAM [IF EXISTS] [IGNORE UNTREATED] stream_name; ## 创建 snode 的方式 -使用以下命令创建 snode(stream node), snode 是流计算中有状态的计算节点,可用于部署聚合任务,同时负责备份不同的流计算任务生成的检查点数据。 +使用以下命令创建 snode(stream node),snode 是流计算中有状态的计算节点,可用于部署聚合任务,同时负责备份不同的流计算任务生成的检查点数据。 ```sql CREATE SNODE ON DNODE [id] ``` @@ -304,7 +306,7 @@ CREATE SNODE ON DNODE [id] ### 使用说明 -流式计算支持在窗口打开/关闭时,向外部系统发送相关的事件通知。用户通过 notification_definition 来指定需要通知的事件,以及用于接收通知消息的目标地址。 +流式计算支持在窗口打开/关闭时,向外部系统发送相关的事件通知。用户通过 `notification_definition` 来指定需要通知的事件,以及用于接收通知消息的目标地址。 ```sql notification_definition: @@ -321,14 +323,14 @@ notification_options: { ``` 上述语法中的相关规则含义如下: -1. `url`: 指定通知的目标地址,必须包括协议、IP 或域名、端口号,并允许包含路径、参数。目前仅支持 websocket 协议。例如:'ws://localhost:8080','ws://localhost:8080/notify','wss://localhost:8080/notify?key=foo'。 -1. `event_type`: 定义需要通知的事件,支持的事件类型有: - 1. 'WINDOW_OPEN':窗口打开事件,所有类型的窗口打开时都会触发 - 1. 'WINDOW_CLOSE':窗口关闭事件,所有类型的窗口关闭时都会触发 -1. `NOTIFY_HISTORY`: 控制是否在计算历史数据时触发通知,默认值为0,即不触发 -1. `ON_FAILURE`: 向通知地址发送通知失败时(比如网络不佳场景)是否允许丢弃部分事件,默认值为 `PAUSE` +1. `url`:指定通知的目标地址,必须包括协议、IP 或域名、端口号,并允许包含路径、参数。目前仅支持 websocket 协议。例如:`ws://localhost:8080`、`ws://localhost:8080/notify`、`wss://localhost:8080/notify?key=foo`。 +1. `event_type`:定义需要通知的事件,支持的事件类型有: + 1. WINDOW_OPEN:窗口打开事件,所有类型的窗口打开时都会触发。 + 1. WINDOW_CLOSE:窗口关闭事件,所有类型的窗口关闭时都会触发。 +1. `NOTIFY_HISTORY`:控制是否在计算历史数据时触发通知,默认值为 0,即不触发。 +1. `ON_FAILURE`:向通知地址发送通知失败时(比如网络不佳场景)是否允许丢弃部分事件,默认值为 `PAUSE`。 1. PAUSE 表示发送通知失败时暂停流计算任务。taosd 会重试发送通知,直到发送成功后,任务自动恢复运行。 - 1. DROP 表示发送通知失败时直接丢弃事件信息,流计算任务继续运行,不受影响 + 1. DROP 表示发送通知失败时直接丢弃事件信息,流计算任务继续运行,不受影响。 比如,以下示例创建一个流,计算电表电流的每分钟平均值,并在窗口打开、关闭时向两个通知地址发送通知,计算历史数据时不发送通知,不允许在通知发送失败时丢弃通知: @@ -432,89 +434,89 @@ CREATE STREAM avg_current_stream FILL_HISTORY 1 ### 根级字段说明 -1. "messageId": 字符串类型,是通知消息的唯一标识符,确保整条消息可以被追踪和去重。 -1. "timestamp": 长整型时间戳,表示通知消息生成的时间,精确到毫秒,即: '00:00, Jan 1 1970 UTC' 以来的毫秒数。 -1. "streams": 对象数组,包含多个流任务的事件信息。(详细信息见下节) +1. messageId:字符串类型,是通知消息的唯一标识符,确保整条消息可以被追踪和去重。 +1. timestamp:长整型时间戳,表示通知消息生成的时间,精确到毫秒,即: '00:00, Jan 1 1970 UTC' 以来的毫秒数。 +1. streams:对象数组,包含多个流任务的事件信息。(详细信息见下节) ### stream 对象的字段说明 -1. "streamName": 字符串类型,流任务的名称,用于标识事件所属的流。 -1. "events": 对象数组,该流任务下的事件列表,包含一个或多个事件对象。(详细信息见下节) +1. streamName:字符串类型,流任务的名称,用于标识事件所属的流。 +1. events:对象数组,该流任务下的事件列表,包含一个或多个事件对象。(详细信息见下节) ### event 对象的字段说明 #### 通用字段 这部分是所有 event 对象所共有的字段。 -1. "tableName": 字符串类型,是对应目标子表的表名。 -1. "eventType": 字符串类型,表示事件类型 ("WINDOW_OPEN", "WINDOW_CLOSE" 或 "WINDOW_INVALIDATION")。 -1. "eventTime": 长整型时间戳,表示事件生成时间,精确到毫秒,即: '00:00, Jan 1 1970 UTC' 以来的毫秒数。 -1. "windowId": 字符串类型,窗口的唯一标识符,确保打开和关闭事件的 ID 一致,便于外部系统将两者关联。如果 taosd 发生故障重启,部分事件可能会重复发送,会保证同一窗口的 windowId 保持不变。 -1. "windowType": 字符串类型,表示窗口类型 ("Time", "State", "Session", "Event", "Count")。 +1. tableName:字符串类型,是对应目标子表的表名。 +1. eventType:字符串类型,表示事件类型,支持 WINDOW_OPEN、WINDOW_CLOSE、WINDOW_INVALIDATION 三种类型。 +1. eventTime:长整型时间戳,表示事件生成时间,精确到毫秒,即:'00:00, Jan 1 1970 UTC' 以来的毫秒数。 +1. windowId:字符串类型,窗口的唯一标识符,确保打开和关闭事件的 ID 一致,便于外部系统将两者关联。如果 taosd 发生故障重启,部分事件可能会重复发送,会保证同一窗口的 windowId 保持不变。 +1. windowType:字符串类型,表示窗口类型,支持 Time、State、Session、Event、Count 五种类型。 #### 时间窗口相关字段 -这部分是 "windowType" 为"Time" 时 event 对象才有的字段。 -1. 如果 "eventType" 为 "WINDOW_OPEN",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 -1. 如果 "eventType" 为 "WINDOW_CLOSE",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 - 1. "result": 计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 +这部分是 windowType 为 Time 时 event 对象才有的字段。 +1. 如果 eventType 为 WINDOW_OPEN,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 +1. 如果 eventType 为 WINDOW_CLOSE,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. windowEnd:长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 + 1. result:计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 #### 状态窗口相关字段 -这部分是 "windowType" 为"State" 时 event 对象才有的字段。 -1. 如果 "eventType" 为 "WINDOW_OPEN",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "prevState": 与状态列的类型相同,表示上一个窗口的状态值。如果没有上一个窗口(即: 现在是第一个窗口),则为 NULL。 - 1. "curState": 与状态列的类型相同,表示当前窗口的状态值。 -1. 如果 "eventType" 为 "WINDOW_CLOSE",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 - 1. "curState": 与状态列的类型相同,表示当前窗口的状态值。 - 1. "nextState": 与状态列的类型相同,表示下一个窗口的状态值。 - 1. "result": 计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 +这部分是 windowType 为 State 时 event 对象才有的字段。 +1. 如果 eventType 为 WINDOW_OPEN,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. prevState:与状态列的类型相同,表示上一个窗口的状态值。如果没有上一个窗口(即:现在是第一个窗口),则为 NULL。 + 1. curState:与状态列的类型相同,表示当前窗口的状态值。 +1. 如果 eventType 为 WINDOW_CLOSE,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. windowEnd:长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 + 1. curState:与状态列的类型相同,表示当前窗口的状态值。 + 1. nextState:与状态列的类型相同,表示下一个窗口的状态值。 + 1. result:计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 #### 会话窗口相关字段 -这部分是 "windowType" 为"Session" 时 event 对象才有的字段。 -1. 如果 "eventType" 为 "WINDOW_OPEN",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 -1. 如果 "eventType" 为 "WINDOW_CLOSE",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 - 1. "result": 计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 +这部分是 windowType 为 Session 时 event 对象才有的字段。 +1. 如果 eventType 为 WINDOW_OPEN,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 +1. 如果 eventType 为 WINDOW_CLOSE,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. windowEnd:长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 + 1. result:计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 #### 事件窗口相关字段 -这部分是 "windowType" 为"Event" 时 event 对象才有的字段。 -1. 如果 "eventType" 为 "WINDOW_OPEN",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "triggerCondition": 触发窗口开始的条件信息,包括以下字段: - 1. "conditionIndex": 整型,表示满足的触发窗口开始的条件的索引,从0开始编号。 - 1. "fieldValue": 键值对形式,包含条件列列名及其对应的值。 -1. 如果 "eventType" 为 "WINDOW_CLOSE",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 - 1. "triggerCondition": 触发窗口关闭的条件信息,包括以下字段: - 1. "conditionIndex": 整型,表示满足的触发窗口关闭的条件的索引,从0开始编号。 - 1. "fieldValue": 键值对形式,包含条件列列名及其对应的值。 - 1. "result": 计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 +这部分是 windowType 为 Event 时 event 对象才有的字段。 +1. 如果 eventType 为 WINDOW_OPEN,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. triggerCondition:触发窗口开始的条件信息,包括以下字段: + 1. conditionIndex:整型,表示满足的触发窗口开始的条件的索引,从0开始编号。 + 1. fieldValue:键值对形式,包含条件列列名及其对应的值。 +1. 如果 eventType 为 WINDOW_CLOSE,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. windowEnd:长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 + 1. triggerCondition:触发窗口关闭的条件信息,包括以下字段: + 1. conditionIndex:整型,表示满足的触发窗口关闭的条件的索引,从0开始编号。 + 1. fieldValue:键值对形式,包含条件列列名及其对应的值。 + 1. result:计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 #### 计数窗口相关字段 -这部分是 "windowType" 为"Count" 时 event 对象才有的字段。 -1. 如果 "eventType" 为 "WINDOW_OPEN",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 -1. 如果 "eventType" 为 "WINDOW_CLOSE",则包含如下字段: - 1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 - 1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 - 1. "result": 计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 +这部分是 windowType 为 Count 时 event 对象才有的字段。 +1. 如果 eventType 为 WINDOW_OPEN,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 +1. 如果 eventType 为 WINDOW_CLOSE,则包含如下字段: + 1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 + 1. windowEnd:长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 + 1. result:计算结果,为键值对形式,包含窗口计算的结果列列名及其对应的值。 #### 窗口失效相关字段 -因为流计算过程中会遇到数据乱序、更新、删除等情况,可能造成已生成的窗口被删除,或者结果需要重新计算。此时会向通知地址发送一条 "WINDOW_INVALIDATION" 的通知,说明哪些窗口已经被删除。 -这部分是 "eventType" 为 "WINDOW_INVALIDATION" 时,event 对象才有的字段。 -1. "windowStart": 长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 -1. "windowEnd": 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 +因为流计算过程中会遇到数据乱序、更新、删除等情况,可能造成已生成的窗口被删除,或者结果需要重新计算。此时会向通知地址发送一条 WINDOW_INVALIDATION 的通知,说明哪些窗口已经被删除。 +这部分是 eventType 为 WINDOW_INVALIDATION 时,event 对象才有的字段。 +1. windowStart:长整型时间戳,表示窗口的开始时间,精度与结果表的时间精度一致。 +1. windowEnd: 长整型时间戳,表示窗口的结束时间,精度与结果表的时间精度一致。 From 152c54a10b4f589b79cb035aa6aa97dbc6636766 Mon Sep 17 00:00:00 2001 From: danielclow <106956386+danielclow@users.noreply.github.com> Date: Tue, 18 Feb 2025 15:49:28 +0800 Subject: [PATCH 56/67] docs: correct url format in 3.0 --- docs/zh/08-operation/09-backup.md | 2 +- docs/zh/08-operation/10-disaster.md | 2 +- docs/zh/10-third-party/05-bi/03-powerbi.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/zh/08-operation/09-backup.md b/docs/zh/08-operation/09-backup.md index 5b02b4fa55..fbc2e612e1 100644 --- a/docs/zh/08-operation/09-backup.md +++ b/docs/zh/08-operation/09-backup.md @@ -61,7 +61,7 @@ TDengine Enterprise 的备份和恢复功能包括以下几个概念: ## 2.2. 数据备份 -通过浏览器访问 taosExplorer 服务,访问地址通常为 TDengine 集群所在 IP 地址的端口 6060,如 http://localhost:6060。 在 +通过浏览器访问 taosExplorer 服务,访问地址通常为 TDengine 集群所在 IP 地址的端口 6060,如 `http://localhost:6060`。 在 taosExplorer 服务页面中,进入“系统管理 - 备份”页面,在“备份计划”标签页下,点击“创建备份计划”,填写备份计划的相关信息。 需要填写的信息包括: diff --git a/docs/zh/08-operation/10-disaster.md b/docs/zh/08-operation/10-disaster.md index b274e1373b..96f9822725 100644 --- a/docs/zh/08-operation/10-disaster.md +++ b/docs/zh/08-operation/10-disaster.md @@ -23,7 +23,7 @@ TDengine 支持 WAL 机制,实现数据的容错能力,保证数据的高可 - 第 1 步,在集群 A 中创建一个数据库 db1,并向该数据库持续写入数据。 -- 第 2 步, 通过 Web 浏览器访问集群 A 的 taosExplorer 服务, 访问地址通常 为TDengine 集群所在 IP 地址的端口 6060,如 http://localhost:6060。 +- 第 2 步, 通过 Web 浏览器访问集群 A 的 taosExplorer 服务, 访问地址通常 为TDengine 集群所在 IP 地址的端口 6060,如 `http://localhost:6060`。 - 第 3 步,访问 TDengine 集群 B,创建一个与集群 A 中数据库 db1 参数配置相同的数据库 db2。 diff --git a/docs/zh/10-third-party/05-bi/03-powerbi.md b/docs/zh/10-third-party/05-bi/03-powerbi.md index bd51b5591d..b864fa2835 100644 --- a/docs/zh/10-third-party/05-bi/03-powerbi.md +++ b/docs/zh/10-third-party/05-bi/03-powerbi.md @@ -23,12 +23,12 @@ Power BI是由Microsoft提供的一种商业分析工具。通过配置使用ODB 第3步,在“选择您想为其安装数据源的驱动程序”列表中选择“TDengine”,点击“完成”按钮,进入TDengine ODBC数据源配置页面。填写如下必要信息。 - DSN:数据源名称,必填,比如“MyTDengine”。 - 连接类型:勾选“WebSocket”复选框。 - - URL:ODBC 数据源 URL,必填,比如“http://127.0.0.1:6041”。 + - URL:ODBC 数据源 URL,必填,比如`http://127.0.0.1:6041`。 - 数据库:表示需要连接的数据库,可选,比如“test”。 - 用户名:输入用户名,如果不填,默认为“root”。 - 密码:输入用户密码,如果不填,默认为“taosdata”。 -第4步,点击“测试连接”按钮,测试连接情况,如果成功连接,则会提示“成功连接到http://127.0.0.1:6041”。 +第4步,点击“测试连接”按钮,测试连接情况,如果成功连接,则会提示“成功连接到`http://127.0.0.1:6041`”。 第5步,点击“确定”按钮,即可保存配置并退出。 ## 导入TDengine数据到Power BI From 9ee7fa5d5c310865294e34dfc99ed5ceca42ff9c Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Tue, 18 Feb 2025 16:06:51 +0800 Subject: [PATCH 57/67] docs: update keywords --- docs/zh/14-reference/03-taos-sql/20-keywords.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/zh/14-reference/03-taos-sql/20-keywords.md b/docs/zh/14-reference/03-taos-sql/20-keywords.md index 0a1bdc4ce8..9c023e0f92 100644 --- a/docs/zh/14-reference/03-taos-sql/20-keywords.md +++ b/docs/zh/14-reference/03-taos-sql/20-keywords.md @@ -37,6 +37,7 @@ description: TDengine 保留关键字的详细列表 | ASOF | | | AT_ONCE | | | ATTACH | | +| AUTO | 3.3.5.0 及后续版本 | ### B |关键字|说明| @@ -82,6 +83,9 @@ description: TDengine 保留关键字的详细列表 | COMP | | | COMPACT | | | COMPACTS | | +| COMPACT_INTERVAL | 3.3.5.0 及后续版本 | +| COMPACT_TIME_OFFSET | 3.3.5.0 及后续版本 | +| COMPACT_TIME_RANGE | 3.3.5.0 及后续版本 | | CONCAT | | | CONFLICT | | | CONNECTION | | @@ -111,6 +115,7 @@ description: TDengine 保留关键字的详细列表 | DESC | | | DESCRIBE | | | DETACH | | +| DISK_INFO | 3.3.5.0 及后续版本 | | DISTINCT | | | DISTRIBUTED | | | DIVIDE | | @@ -201,6 +206,7 @@ description: TDengine 保留关键字的详细列表 | INTO | | | IPTOKEN | | | IROWTS | | +| IROWTS_ORIGIN | 3.3.5.0 及后续版本 | | IS | | | IS_IMPORT | | | ISFILLED | | @@ -269,6 +275,8 @@ description: TDengine 保留关键字的详细列表 | NONE | | | NORMAL | | | NOT | | +| NOTIFY | 3.3.6.0 及后续版本 | +| NOTIFY_HISTORY | 3.3.6.0 及后续版本 | | NOTNULL | | | NOW | | | NULL | | @@ -282,6 +290,7 @@ description: TDengine 保留关键字的详细列表 | OFFSET | | | ON | | | ONLY | | +| ON_FAILURE | 3.3.6.0 及后续版本 | | OR | | | ORDER | | | OUTER | | @@ -329,6 +338,7 @@ description: TDengine 保留关键字的详细列表 | RATIO | | | READ | | | RECURSIVE | | +| REGEXP | 3.3.6.0 及后续版本 | | REDISTRIBUTE | | | REM | | | REPLACE | | @@ -475,7 +485,7 @@ description: TDengine 保留关键字的详细列表 | WINDOW_OFFSET | | | WITH | | | WRITE | | -| WSTART | | +| WSTART | | ### \_ From 4cfaa8550f884661243df19b284a1cfbced7dd5f Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 18 Feb 2025 16:16:21 +0800 Subject: [PATCH 58/67] fix: sum write to avg --- tests/army/tools/taosdump/native/taosdumpCompa.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/army/tools/taosdump/native/taosdumpCompa.py b/tests/army/tools/taosdump/native/taosdumpCompa.py index af498392bc..c3158e4a80 100644 --- a/tests/army/tools/taosdump/native/taosdumpCompa.py +++ b/tests/army/tools/taosdump/native/taosdumpCompa.py @@ -71,8 +71,7 @@ class TDTestCase(TBase): self.checkSame(db, stb, "last(ts)", "2023-11-15 07:36:39") self.checkSame(db, stb, "last(bc)", False) self.checkSame(db, stb, "sum(fc)", 2468.910999777726829) - self.checkSame(db, stb, "avg(dc)", 24811.172123999996984) - + self.checkSame(db, stb, "sum(dc)", 24811.172123999996984) self.checkSame(db, stb, "sum(ti)", -411) self.checkSame(db, stb, "sum(si)", 117073) self.checkSame(db, stb, "sum(ic)", -39181) From 2c6ad3ac8aa7dd24746ca13a578adeaf557f3426 Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 18 Feb 2025 16:18:16 +0800 Subject: [PATCH 59/67] fix: show check result --- tests/army/tools/taosdump/native/taosdumpCompa.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/army/tools/taosdump/native/taosdumpCompa.py b/tests/army/tools/taosdump/native/taosdumpCompa.py index c3158e4a80..f525b20fd7 100644 --- a/tests/army/tools/taosdump/native/taosdumpCompa.py +++ b/tests/army/tools/taosdump/native/taosdumpCompa.py @@ -59,9 +59,7 @@ class TDTestCase(TBase): # sum pk db sql = f"select {aggfun} from {db}.{stb}" tdSql.query(sql) - tdSql.checkData(0, 0, expect) - - + tdSql.checkData(0, 0, expect, show=True) def verifyResult(self, db): From 69d7298e5913ef7db237c59441d12de3b5605930 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Tue, 18 Feb 2025 16:38:34 +0800 Subject: [PATCH 60/67] doc: minor changes --- docs/zh/14-reference/03-taos-sql/14-stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh/14-reference/03-taos-sql/14-stream.md b/docs/zh/14-reference/03-taos-sql/14-stream.md index d729a7e596..666cf97ea7 100644 --- a/docs/zh/14-reference/03-taos-sql/14-stream.md +++ b/docs/zh/14-reference/03-taos-sql/14-stream.md @@ -42,7 +42,7 @@ column_definition: type_name [COMMENT 'string_value'] ``` -subtable 子句定义了流式计算中创建的子表的命名规则,详见 [流式计算的 partition](#流式计算的 partitionG)。 +subtable 子句定义了流式计算中创建的子表的命名规则,详见 [流式计算的 partition](#流式计算的 partition)。 ```sql window_clause: { From 87040f1822a2da07ef5c378cf1344614b07109f1 Mon Sep 17 00:00:00 2001 From: Jinqing Kuang Date: Tue, 18 Feb 2025 17:13:35 +0800 Subject: [PATCH 61/67] enh(stream): replace magic numbers in u64toaFastLut with macros Replace magic numbers in the u64toaFastLut function with macros for better readability and maintainability. Add unit test to ensure the correctness of the refactor. --- source/util/src/tlog.c | 41 +++++++++++++++++++++++++++------------- source/util/test/log.cpp | 25 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index 0e3e236b36..2460c7c650 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -1502,31 +1502,46 @@ bool taosAssertRelease(bool condition) { } #endif +#define NUM_BASE 100 +#define DIGIT_LENGTH 2 +#define MAX_DIGITS 24 + char* u64toaFastLut(uint64_t val, char* buf) { + // Look-up table for 2-digit numbers static const char* lut = "0001020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455" "5657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"; - char temp[24]; - char* p = temp; + char temp[MAX_DIGITS]; + char* p = temp + tListLen(temp); - while (val >= 100) { - strncpy(p, lut + (val % 100) * 2, 2); - val /= 100; - p += 2; + // Process the digits greater than or equal to 100 + while (val >= NUM_BASE) { + // Get the last 2 digits from the look-up table and add to the buffer + p -= DIGIT_LENGTH; + strncpy(p, lut + (val % NUM_BASE) * DIGIT_LENGTH, DIGIT_LENGTH); + val /= NUM_BASE; } + // Process the remaining 1 or 2 digits if (val >= 10) { - strncpy(p, lut + val * 2, 2); - p += 2; + // If the number is 10 or more, get the 2 digits from the look-up table + p -= DIGIT_LENGTH; + strncpy(p, lut + val * DIGIT_LENGTH, DIGIT_LENGTH); } else if (val > 0 || p == temp) { - *(p++) = val + '0'; + // If the number is less than 10, add the single digit to the buffer + p -= 1; + *p = val + '0'; } - while (p != temp) { - *buf++ = *--p; + int64_t len = temp + tListLen(temp) - p; + if (len > 0) { + memcpy(buf, p, len); + } else { + buf[0] = '0'; + len = 1; } + buf[len] = '\0'; - *buf = '\0'; - return buf; + return buf + len; } diff --git a/source/util/test/log.cpp b/source/util/test/log.cpp index 1899aac2c4..ae1be94e40 100644 --- a/source/util/test/log.cpp +++ b/source/util/test/log.cpp @@ -139,3 +139,28 @@ TEST(log, misc) { taosCloseLog(); } + +TEST(log, test_u64toa) { + char buf[64] = {0}; + char *p = buf; + + p = u64toaFastLut(0, buf); + EXPECT_EQ(p, buf + 1); + EXPECT_EQ(strcmp(buf, "0"), 0); + + p = u64toaFastLut(1, buf); + EXPECT_EQ(p, buf + 1); + EXPECT_EQ(strcmp(buf, "1"), 0); + + p = u64toaFastLut(12, buf); + EXPECT_EQ(p, buf + 2); + EXPECT_EQ(strcmp(buf, "12"), 0); + + p = u64toaFastLut(12345, buf); + EXPECT_EQ(p, buf + 5); + EXPECT_EQ(strcmp(buf, "12345"), 0); + + p = u64toaFastLut(1234567890, buf); + EXPECT_EQ(p, buf + 10); + EXPECT_EQ(strcmp(buf, "1234567890"), 0); +} From a48095d467e36faf431856d33a5a3c489fee7e33 Mon Sep 17 00:00:00 2001 From: Jinqing Kuang Date: Tue, 18 Feb 2025 15:30:21 +0800 Subject: [PATCH 62/67] enh(streams): add options to control message and frame size Add options to allow users to specify message and frame size limits for event notifications. --- include/common/tglobal.h | 2 ++ source/common/src/tglobal.c | 14 +++++++++++++- source/dnode/vnode/src/tq/tqStreamNotify.c | 7 ++----- .../libs/executor/src/streamtimewindowoperator.c | 1 - 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/common/tglobal.h b/include/common/tglobal.h index bb3f0964de..1b59f1de8a 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -296,6 +296,8 @@ extern int32_t tsMaxStreamBackendCache; extern int32_t tsPQSortMemThreshold; extern bool tsStreamCoverage; extern int8_t tsS3EpNum; +extern int32_t tsStreamNotifyMessageSize; +extern int32_t tsStreamNotifyFrameSize; extern bool tsExperimental; // #define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 223418feed..05898ea26e 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -356,6 +356,9 @@ int32_t tsMaxTsmaCalcDelay = 600; int64_t tsmaDataDeleteMark = 1000 * 60 * 60 * 24; // in ms, default to 1d void *pTimezoneNameMap = NULL; +int32_t tsStreamNotifyMessageSize = 8 * 1024; // KB, default 8MB +int32_t tsStreamNotifyFrameSize = 256; // KB, default 256KB + int32_t taosCheckCfgStrValueLen(const char *name, const char *value, int32_t len); #define TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, pName) \ @@ -965,6 +968,9 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { TAOS_CHECK_RETURN(cfgAddInt64(pCfg, "minDiskFreeSize", tsMinDiskFreeSize, TFS_MIN_DISK_FREE_SIZE, 1024 * 1024 * 1024, CFG_SCOPE_SERVER, CFG_DYN_ENT_SERVER,CFG_CATEGORY_LOCAL)); TAOS_CHECK_RETURN(cfgAddBool(pCfg, "enableWhiteList", tsEnableWhiteList, CFG_SCOPE_SERVER, CFG_DYN_SERVER,CFG_CATEGORY_GLOBAL)); + TAOS_CHECK_RETURN(cfgAddInt32(pCfg, "streamNotifyMessageSize", tsStreamNotifyMessageSize, 8, 1024 * 1024, CFG_SCOPE_SERVER, CFG_DYN_NONE,CFG_CATEGORY_LOCAL)); + TAOS_CHECK_RETURN(cfgAddInt32(pCfg, "streamNotifyFrameSize", tsStreamNotifyFrameSize, 8, 1024 * 1024, CFG_SCOPE_SERVER, CFG_DYN_NONE,CFG_CATEGORY_LOCAL)); + // clang-format on // GRANT_CFG_ADD; @@ -1850,6 +1856,12 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "minReservedMemorySize"); tsMinReservedMemorySize = pItem->i32; + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "streamNotifyMessageSize"); + tsStreamNotifyMessageSize = pItem->i32; + + TAOS_CHECK_GET_CFG_ITEM(pCfg, pItem, "streamNotifyFrameSize"); + tsStreamNotifyFrameSize = pItem->i32; + // GRANT_CFG_GET; TAOS_RETURN(TSDB_CODE_SUCCESS); } @@ -3241,4 +3253,4 @@ int32_t taosCheckCfgStrValueLen(const char *name, const char *value, int32_t len TAOS_RETURN(TSDB_CODE_INVALID_CFG_VALUE); } TAOS_RETURN(TSDB_CODE_SUCCESS); -} \ No newline at end of file +} diff --git a/source/dnode/vnode/src/tq/tqStreamNotify.c b/source/dnode/vnode/src/tq/tqStreamNotify.c index 61200b189b..1c64c404e6 100644 --- a/source/dnode/vnode/src/tq/tqStreamNotify.c +++ b/source/dnode/vnode/src/tq/tqStreamNotify.c @@ -21,9 +21,6 @@ #endif #define STREAM_EVENT_NOTIFY_RETRY_MS 50 // 50 ms -#define STREAM_EVENT_NOTIFY_MESSAAGE_SIZE_KB 8 * 1024 // 8 MB -#define STREAM_EVENT_NOTIFY_FRAME_SIZE 256 * 1024 // 256 KB - typedef struct SStreamNotifyHandle { TdThreadMutex mutex; #ifndef WINDOWS @@ -296,7 +293,7 @@ static int32_t packupStreamNotifyEvent(const char* streamName, const SArray* pBl msgLen += varDataLen(val) + 1; } *nNotifyEvents += pDataBlock->info.rows; - if (msgLen >= STREAM_EVENT_NOTIFY_MESSAAGE_SIZE_KB * 1024) { + if (msgLen >= tsStreamNotifyMessageSize * 1024) { break; } } @@ -381,7 +378,7 @@ static int32_t sendSingleStreamNotify(SStreamNotifyHandle* pHandle, char* msg) { } sentLen = 0; while (sentLen < totalLen) { - size_t chunkSize = TMIN(totalLen - sentLen, STREAM_EVENT_NOTIFY_FRAME_SIZE); + size_t chunkSize = TMIN(totalLen - sentLen, tsStreamNotifyFrameSize * 1024); if (sentLen == 0) { res = curl_ws_send(pHandle->curl, msg, chunkSize, &nbytes, totalLen, CURLWS_TEXT | CURLWS_OFFSET); TSDB_CHECK_CONDITION(res == CURLE_OK, code, lino, _end, TSDB_CODE_FAILED); diff --git a/source/libs/executor/src/streamtimewindowoperator.c b/source/libs/executor/src/streamtimewindowoperator.c index 3b799eea23..fbb55301cd 100644 --- a/source/libs/executor/src/streamtimewindowoperator.c +++ b/source/libs/executor/src/streamtimewindowoperator.c @@ -2977,7 +2977,6 @@ static int32_t rebuildSessionWindow(SOperatorInfo* pOperator, SArray* pWinArray, if (winCode == TSDB_CODE_SUCCESS && inWinRange(&pWinKey->win, &childWin.sessionWin.win)) { if (num == 0) { - int32_t winCode = TSDB_CODE_SUCCESS; code = setSessionOutputBuf(pAggSup, pWinKey->win.skey, pWinKey->win.ekey, pWinKey->groupId, &parentWin, &winCode); QUERY_CHECK_CODE(code, lino, _end); From aef5611d1b48f9e5ed17222d5c872d904a36f8e9 Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Tue, 18 Feb 2025 17:59:57 +0800 Subject: [PATCH 63/67] switch create thread to taosc task queue --- include/client/taos.h | 13 +++++---- include/libs/qcom/query.h | 1 + source/client/inc/clientStmt2.h | 8 ++++++ source/client/src/clientMain.c | 17 +++++++++-- source/client/src/clientStmt2.c | 48 ++------------------------------ source/libs/qcom/src/queryUtil.c | 12 ++++++++ 6 files changed, 44 insertions(+), 55 deletions(-) diff --git a/include/client/taos.h b/include/client/taos.h index 59ada33d91..188b479cc6 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -247,12 +247,13 @@ typedef struct TAOS_STMT2_BINDV { DLL_EXPORT TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option); DLL_EXPORT int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length); DLL_EXPORT int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx); -DLL_EXPORT int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, void *param); -DLL_EXPORT int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows); -DLL_EXPORT int taos_stmt2_close(TAOS_STMT2 *stmt); -DLL_EXPORT int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert); -DLL_EXPORT int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields); -DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields); +DLL_EXPORT int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, + void *param); +DLL_EXPORT int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows); +DLL_EXPORT int taos_stmt2_close(TAOS_STMT2 *stmt); +DLL_EXPORT int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert); +DLL_EXPORT int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields); +DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields); DLL_EXPORT TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt); DLL_EXPORT char *taos_stmt2_error(TAOS_STMT2 *stmt); diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 5b28eadc4f..a17e67279c 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -300,6 +300,7 @@ int32_t cleanupTaskQueue(); int32_t taosAsyncExec(__async_exec_fn_t execFn, void* execParam, int32_t* code); int32_t taosAsyncWait(); int32_t taosAsyncRecover(); +int32_t taosStmt2AsyncBind(__async_exec_fn_t execFn, void* execParam); void destroySendMsgInfo(SMsgSendInfo* pMsgBody); diff --git a/source/client/inc/clientStmt2.h b/source/client/inc/clientStmt2.h index feec9ec337..283573803e 100644 --- a/source/client/inc/clientStmt2.h +++ b/source/client/inc/clientStmt2.h @@ -133,6 +133,13 @@ SStmtQNode* tail; uint64_t qRemainNum; } SStmtQueue; */ +typedef struct { + TAOS_STMT2 *stmt; + TAOS_STMT2_BINDV *bindv; + int32_t col_idx; + __taos_async_fn_t fp; + void *param; +} ThreadArgs; typedef struct AsyncBindParam { TdThreadMutex mutex; @@ -234,6 +241,7 @@ int stmtIsInsert2(TAOS_STMT2 *stmt, int *insert); TAOS_RES *stmtUseResult2(TAOS_STMT2 *stmt); const char *stmtErrstr2(TAOS_STMT2 *stmt); int stmt2AsyncBind(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp, void *param); +int stmtAsyncBindThreadFunc(void *args); #ifdef __cplusplus } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index ba67ff7f76..25184b041b 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -2256,14 +2256,25 @@ int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t c } STscStmt2 *pStmt = (STscStmt2 *)stmt; + if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) { + tscError("async bind param is still working, please try again later"); + return TSDB_CODE_TSC_STMT_API_ERROR; + } + + ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs)); + args->stmt = stmt; + args->bindv = bindv; + args->col_idx = col_idx; + args->fp = fp; + args->param = param; (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1); - int code = stmt2AsyncBind(stmt, bindv, col_idx, fp, param); - if (code != TSDB_CODE_SUCCESS) { + int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args); + if (code_s != TSDB_CODE_SUCCESS) { (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1); // terrno = TAOS_SYSTEM_ERROR(errno); } - return code; + return code_s; } int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) { diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 597ec95f23..67066e1fdd 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -1957,17 +1957,8 @@ TAOS_RES* stmtUseResult2(TAOS_STMT2* stmt) { return pStmt->exec.pRequest; } -typedef struct { - TAOS_STMT2* stmt; - TAOS_STMT2_BINDV* bindv; - int32_t col_idx; - __taos_async_fn_t fp; - void* param; -} ThreadArgs; - -static void* stmtAsyncBindThreadFunc(void* args) { - setThreadName("stmtAsyncBind"); +int32_t stmtAsyncBindThreadFunc(void* args) { qInfo("async stmt bind thread started"); ThreadArgs* targs = (ThreadArgs*)args; @@ -1983,40 +1974,5 @@ static void* stmtAsyncBindThreadFunc(void* args) { qInfo("async stmt bind thread stopped"); - return NULL; -} - -int stmt2AsyncBind(TAOS_STMT2* stmt, TAOS_STMT2_BINDV* bindv, int32_t col_idx, __taos_async_fn_t fp, void* param) { - STscStmt2* pStmt = (STscStmt2*)stmt; - if (atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum) > 1) { - tscError("async bind param is still working, please try again later"); - return TSDB_CODE_TSC_STMT_API_ERROR; - } - - TdThreadAttr thAttr; - if (taosThreadAttrInit(&thAttr) != 0) { - return TSDB_CODE_TSC_INTERNAL_ERROR; - } - if (taosThreadAttrSetDetachState(&thAttr, PTHREAD_CREATE_DETACHED) != 0) { - return TSDB_CODE_TSC_INTERNAL_ERROR; - } - - ThreadArgs* args = (ThreadArgs*)taosMemoryMalloc(sizeof(ThreadArgs)); - args->stmt = stmt; - args->bindv = bindv; - args->col_idx = col_idx; - args->fp = fp; - args->param = param; - - if (taosThreadCreate(&pStmt->bindThread, &thAttr, stmtAsyncBindThreadFunc, args) != 0) { - (void)taosThreadAttrDestroy(&thAttr); - terrno = TAOS_SYSTEM_ERROR(errno); - STMT_ERR_RET(terrno); - } - - // pStmt->bindThreadInUse = true; - - (void)taosThreadAttrDestroy(&thAttr); - - return TSDB_CODE_SUCCESS; + return code; } \ No newline at end of file diff --git a/source/libs/qcom/src/queryUtil.c b/source/libs/qcom/src/queryUtil.c index 85b1c543c0..35f258c554 100644 --- a/source/libs/qcom/src/queryUtil.c +++ b/source/libs/qcom/src/queryUtil.c @@ -202,6 +202,18 @@ int32_t taosAsyncRecover() { return taskQueue.wrokrerPool.pCb->afterRecoverFromBlocking(&taskQueue.wrokrerPool); } +int32_t taosStmt2AsyncBind(__async_exec_fn_t bindFn, void* bindParam) { + SSchedMsg* pSchedMsg; + int32_t rc = taosAllocateQitem(sizeof(SSchedMsg), DEF_QITEM, 0, (void **)&pSchedMsg); + if (rc) return rc; + pSchedMsg->fp = NULL; + pSchedMsg->ahandle = bindFn; + pSchedMsg->thandle = bindParam; + // pSchedMsg->msg = code; + + return taosWriteQitem(taskQueue.pTaskQueue, pSchedMsg); +} + void destroySendMsgInfo(SMsgSendInfo* pMsgBody) { if (NULL == pMsgBody) { return; From df674440bf8b40170939cde659c64af9c4bcd3ef Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 18 Feb 2025 19:27:47 +0800 Subject: [PATCH 64/67] fix: last row scan and tag in conds issues --- source/libs/executor/src/cachescanoperator.c | 16 +++---- source/libs/planner/src/planOptimizer.c | 49 ++++++++++++++++++++ source/libs/scheduler/src/schStatus.c | 8 ++-- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 649a7a4524..7349feb70f 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -398,16 +398,16 @@ static int32_t doScanCacheNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) { // check for tag values if (pInfo->pRes->info.rows > 0) { - if (pInfo->pseudoExprSup.numOfExprs > 0) { - SExprSupp* pSup = &pInfo->pseudoExprSup; + SExprSupp* pSup = &pInfo->pseudoExprSup; - STableKeyInfo* pKeyInfo = &((STableKeyInfo*)pList)[0]; - pInfo->pRes->info.id.groupId = pKeyInfo->groupId; + STableKeyInfo* pKeyInfo = &((STableKeyInfo*)pList)[0]; + pInfo->pRes->info.id.groupId = pKeyInfo->groupId; - if (taosArrayGetSize(pInfo->pUidList) > 0) { - void* pUid = taosArrayGet(pInfo->pUidList, 0); - QUERY_CHECK_NULL(pUid, code, lino, _end, terrno); - pInfo->pRes->info.id.uid = *(tb_uid_t*)pUid; + if (taosArrayGetSize(pInfo->pUidList) > 0) { + void* pUid = taosArrayGet(pInfo->pUidList, 0); + QUERY_CHECK_NULL(pUid, code, lino, _end, terrno); + pInfo->pRes->info.id.uid = *(tb_uid_t*)pUid; + if (pInfo->pseudoExprSup.numOfExprs > 0) { code = addTagPseudoColumnData(&pInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pInfo->pRes, pInfo->pRes->info.rows, pTaskInfo, NULL); QUERY_CHECK_CODE(code, lino, _end); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index a3fa5a3d7c..e8a8e6889a 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -93,6 +93,12 @@ typedef struct SCpdCollectTableColCxt { int32_t errCode; } SCpdCollectTableColCxt; +typedef struct SCollectColsCxt { + SHashObj* pColHash; + int32_t errCode; +} SCollectColsCxt; + + typedef enum ECondAction { COND_ACTION_STAY = 1, COND_ACTION_PUSH_JOIN, @@ -3302,11 +3308,54 @@ static int32_t partTagsRewriteGroupTagsToFuncs(SNodeList* pGroupTags, int32_t st return code; } +static EDealRes partTagsCollectColsNodes(SNode* pNode, void* pContext) { + SCollectColsCxt* pCxt = pContext; + if (QUERY_NODE_COLUMN == nodeType(pNode)) { + SColumnNode* pCol = (SColumnNode*)pNode; + if (NULL == taosHashGet(pCxt->pColHash, pCol->colName, strlen(pCol->colName))) { + pCxt->errCode = taosHashPut(pCxt->pColHash, pCol->colName, strlen(pCol->colName), NULL, 0); + } + } + + return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR); +} + + +static bool partTagsIsScanPseudoColsInConds(SScanLogicNode* pScan) { + SCollectColsCxt cxt = { + .errCode = TSDB_CODE_SUCCESS, + .pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)}; + if (NULL == cxt.pColHash) { + return true; + } + + nodesWalkExpr(pScan->node.pConditions, partTagsCollectColsNodes, &cxt); + if (cxt.errCode) { + taosHashCleanup(cxt.pColHash); + return true; + } + + SNode* pNode = NULL; + FOREACH(pNode, pScan->pScanPseudoCols) { + if (taosHashGet(cxt.pColHash, ((SExprNode*)pNode)->aliasName, strlen(((SExprNode*)pNode)->aliasName))) { + taosHashCleanup(cxt.pColHash); + return true; + } + } + + taosHashCleanup(cxt.pColHash); + return false; +} + static int32_t partTagsOptRemovePseudoCols(SScanLogicNode* pScan) { if (!pScan->noPseudoRefAfterGrp || NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0) { return TSDB_CODE_SUCCESS; } + if (pScan->node.pConditions && partTagsIsScanPseudoColsInConds(pScan)) { + return TSDB_CODE_SUCCESS; + } + SNode* pNode = NULL, *pTarget = NULL; FOREACH(pNode, pScan->pScanPseudoCols) { FOREACH(pTarget, pScan->node.pTargets) { diff --git a/source/libs/scheduler/src/schStatus.c b/source/libs/scheduler/src/schStatus.c index f24ee74101..9792af22f6 100644 --- a/source/libs/scheduler/src/schStatus.c +++ b/source/libs/scheduler/src/schStatus.c @@ -22,9 +22,11 @@ #include "trpc.h" int32_t schSwitchJobStatus(SSchJob* pJob, int32_t status, void* param) { - int32_t code = 0; - SCH_ERR_JRET(schUpdateJobStatus(pJob, status)); - + int32_t code = schUpdateJobStatus(pJob, status); + if (TSDB_CODE_SUCCESS != code) { + SCH_ERR_JRET((param && *(int32_t*)param) ? *(int32_t*)param : code); + } + switch (status) { case JOB_TASK_STATUS_INIT: break; From 64db62db4424dd2a59c0405248a42fe6140bbbac Mon Sep 17 00:00:00 2001 From: Alex Duan <417921451@qq.com> Date: Tue, 18 Feb 2025 20:59:30 +0800 Subject: [PATCH 65/67] fix: trigger pr runing --- tests/army/tools/taosdump/native/taosdumpCompa.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/army/tools/taosdump/native/taosdumpCompa.py b/tests/army/tools/taosdump/native/taosdumpCompa.py index f525b20fd7..780cb303e7 100644 --- a/tests/army/tools/taosdump/native/taosdumpCompa.py +++ b/tests/army/tools/taosdump/native/taosdumpCompa.py @@ -108,7 +108,6 @@ class TDTestCase(TBase): # verify db self.verifyResult(db) - def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) From fa2dc26555fb09dbc3a626d65b3bc16c7c4b6aaf Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Wed, 19 Feb 2025 08:56:21 +0800 Subject: [PATCH 66/67] fix: stream subtable name issue --- source/libs/planner/src/planLogicCreater.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index 96623d406d..3f064f2b66 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -407,7 +407,7 @@ static int32_t makeScanLogicNode(SLogicPlanContext* pCxt, SRealTableNode* pRealT static bool needScanDefaultCol(EScanType scanType) { return SCAN_TYPE_TABLE_COUNT != scanType; } static int32_t updateScanNoPseudoRefAfterGrp(SSelectStmt* pSelect, SScanLogicNode* pScan, SRealTableNode* pRealTable) { - if (NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0 || NULL != pSelect->pTags) { + if (NULL == pScan->pScanPseudoCols || pScan->pScanPseudoCols->length <= 0 || NULL != pSelect->pTags || NULL != pSelect->pSubtable) { return TSDB_CODE_SUCCESS; } From fcb4ffec495dc8367304dfb9a6dd5b42bee5cf22 Mon Sep 17 00:00:00 2001 From: happyguoxy Date: Wed, 19 Feb 2025 14:50:56 +0800 Subject: [PATCH 67/67] delete UPDATE_COMMAND --- tools/CMakeLists.txt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 86b13ca723..1ee2bc4ce6 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -16,10 +16,6 @@ IF(TD_WEBSOCKET) DEPENDS ${TAOS_LIB} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND cmake -E echo "taosws-rs no need cmake to config" - UPDATE_COMMAND - COMMAND echo "Starting to switch branch" - COMMAND git fetch origin main && git checkout -f origin/main - COMMAND echo "Switched to the main branch successfully" PATCH_COMMAND COMMAND git clean -f -d BUILD_COMMAND @@ -39,10 +35,6 @@ IF(TD_WEBSOCKET) DEPENDS ${TAOS_LIB} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND cmake -E echo "taosws-rs no need cmake to config" - UPDATE_COMMAND - COMMAND echo "Starting to switch branch" - COMMAND git fetch origin main && git checkout -f origin/main - COMMAND echo "Switched to the main branch successfully" PATCH_COMMAND COMMAND git clean -f -d BUILD_COMMAND @@ -63,10 +55,6 @@ IF(TD_WEBSOCKET) DEPENDS ${TAOS_LIB} BUILD_IN_SOURCE 1 CONFIGURE_COMMAND cmake -E echo "taosws-rs no need cmake to config" - UPDATE_COMMAND - COMMAND echo "Starting to switch branch" - COMMAND git fetch origin main && git checkout -f origin/main - COMMAND echo "Switched to the main branch successfully" PATCH_COMMAND COMMAND git clean -f -d BUILD_COMMAND