From 3451ba0c827100ba30ce09ba212db30cc393703a Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 9 Jun 2022 18:54:22 +0800 Subject: [PATCH 1/4] fix:error in schemaless --- source/client/src/clientSml.c | 64 +++++------------------------------ 1 file changed, 8 insertions(+), 56 deletions(-) diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index d1d7325909..75c308c029 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -67,6 +67,8 @@ for (int i = 1; i < keyLen; ++i) { \ #define BINARY_ADD_LEN 2 // "binary" 2 means " " #define NCHAR_ADD_LEN 3 // L"nchar" 3 means L" " + +#define MAX_RETRY_TIMES 5 //================================================================================================= typedef TSDB_SML_PROTOCOL_TYPE SMLProtocolType; @@ -303,7 +305,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uError("SML:0x%" PRIx64 " apply schema action. reset query cache. error: %s", info->id, taos_errstr(res2)); } taos_free_result(res2); - taosMsleep(10); + taosMsleep(500); } break; } @@ -327,7 +329,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uError("SML:0x%" PRIx64 " apply schema action. reset query cache. error: %s", info->id, taos_errstr(res2)); } taos_free_result(res2); - taosMsleep(10); + taosMsleep(500); } break; } @@ -350,7 +352,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uError("SML:0x%" PRIx64 " apply schema action. reset query cache. error: %s", info->id, taos_errstr(res2)); } taos_free_result(res2); - taosMsleep(10); + taosMsleep(500); } break; } @@ -373,7 +375,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uError("SML:0x%" PRIx64 " apply schema action. reset query cache. error: %s", info->id, taos_errstr(res2)); } taos_free_result(res2); - taosMsleep(10); + taosMsleep(500); } break; } @@ -424,7 +426,7 @@ static int32_t smlApplySchemaAction(SSmlHandle* info, SSchemaAction* action) { uError("SML:0x%" PRIx64 " apply schema action. reset query cache. error: %s", info->id, taos_errstr(res2)); } taos_free_result(res2); - taosMsleep(10); + taosMsleep(500); } break; } @@ -541,56 +543,6 @@ end: return code; } -//========================================================================= - -/* Field Escape charaters - 1: measurement Comma,Space - 2: tag_key, tag_value, field_key Comma,Equal Sign,Space - 3: field_value Double quote,Backslash -*/ -//static void escapeSpecialCharacter(uint8_t field, const char **pos) { -// const char *cur = *pos; -// if (*cur != '\\') { -// return; -// } -// switch (field) { -// case 1: -// switch (*(cur + 1)) { -// case ',': -// case ' ': -// cur++; -// break; -// default: -// break; -// } -// break; -// case 2: -// switch (*(cur + 1)) { -// case ',': -// case ' ': -// case '=': -// cur++; -// break; -// default: -// break; -// } -// break; -// case 3: -// switch (*(cur + 1)) { -// case '"': -// case '\\': -// cur++; -// break; -// default: -// break; -// } -// break; -// default: -// break; -// } -// *pos = cur; -//} - static bool smlParseNumber(SSmlKv *kvVal, SSmlMsgBuf *msg){ const char *pVal = kvVal->value; int32_t len = kvVal->length; @@ -2311,7 +2263,7 @@ static int smlProcess(SSmlHandle *info, char* lines[], int numLines) { do{ code = smlModifyDBSchemas(info); if (code == 0) break; - } while (retryNum++ < taosHashGetSize(info->superTables)); + } while (retryNum++ < taosHashGetSize(info->superTables) * MAX_RETRY_TIMES); if (code != 0) { uError("SML:0x%"PRIx64" smlModifyDBSchemas error : %s", info->id, tstrerror(code)); From 1d14725880d9b06d90de880f0fb4bfe13554822d Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 9 Jun 2022 21:38:57 +0800 Subject: [PATCH 2/4] feat:add async logic for schemaless --- source/client/src/clientSml.c | 141 ++++++++++++++++++++++++++-------- 1 file changed, 107 insertions(+), 34 deletions(-) diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 75c308c029..3039f93a30 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -155,8 +155,17 @@ typedef struct { int64_t endTime; } SSmlCostInfo; +typedef struct{ + SRequestObj* request; + SCatalog* catalog; + tsem_t sem; + TdThreadSpinlock lock; +} Params; + typedef struct { int64_t id; + Params params; + bool isLast; SMLProtocolType protocol; int8_t precision; @@ -1378,6 +1387,7 @@ static void smlDestroyInfo(SSmlHandle* info){ if(!info->dataFormat){ taosArrayDestroy(info->colsContainer); } + destroyRequest(info->pRequest); taosMemoryFreeClear(info); } @@ -1405,11 +1415,6 @@ static SSmlHandle* smlBuildSmlInfo(TAOS* taos, SRequestObj* request, SMLProtocol ((SVnodeModifOpStmt*)(info->pQuery->pRoot))->payloadType = PAYLOAD_TYPE_KV; info->taos = (STscObj *)taos; - code = catalogGetHandle(info->taos->pAppInfo->clusterId, &info->pCatalog); - if(code != TSDB_CODE_SUCCESS){ - uError("SML:0x%"PRIx64" get catalog error %d", info->id, code); - goto cleanup; - } info->precision = precision; info->protocol = protocol; @@ -2158,7 +2163,6 @@ end: return ret; } - static int32_t smlInsertData(SSmlHandle* info) { int32_t code = TSDB_CODE_SUCCESS; @@ -2200,10 +2204,12 @@ static int32_t smlInsertData(SSmlHandle* info) { } info->cost.insertRpcTime = taosGetTimestampUs(); - launchQueryImpl(info->pRequest, info->pQuery, true, NULL); + //launchQueryImpl(info->pRequest, info->pQuery, false, NULL); +// info->affectedRows = taos_affected_rows(info->pRequest); +// return info->pRequest->code; - info->affectedRows = taos_affected_rows(info->pRequest); - return info->pRequest->code; + launchAsyncQuery(info->pRequest, info->pQuery); + return TSDB_CODE_SUCCESS; } static void smlPrintStatisticInfo(SSmlHandle *info){ @@ -2284,30 +2290,53 @@ cleanup: return code; } -static int32_t isSchemalessDb(SSmlHandle* info){ +static int32_t isSchemalessDb(STscObj *taos, SCatalog *catalog){ SName name; - tNameSetDbName(&name, info->taos->acctId, info->taos->db, strlen(info->taos->db)); + tNameSetDbName(&name, taos->acctId, taos->db, strlen(taos->db)); char dbFname[TSDB_DB_FNAME_LEN] = {0}; tNameGetFullDbName(&name, dbFname); SDbCfgInfo pInfo = {0}; - SEpSet ep = getEpSet_s(&info->taos->pAppInfo->mgmtEp); + SEpSet ep = getEpSet_s(&taos->pAppInfo->mgmtEp); - int32_t code = catalogGetDBCfg(info->pCatalog, info->taos->pAppInfo->pTransporter, &ep, dbFname, &pInfo); + int32_t code = catalogGetDBCfg(catalog, taos->pAppInfo->pTransporter, &ep, dbFname, &pInfo); if (code != TSDB_CODE_SUCCESS) { - info->pRequest->code = code; - smlBuildInvalidDataMsg(&info->msgBuf, "catalogGetDBCfg error, code:", tstrerror(code)); return code; } taosArrayDestroy(pInfo.pRetensions); if (!pInfo.schemaless){ - info->pRequest->code = TSDB_CODE_SML_INVALID_DB_CONF; - smlBuildInvalidDataMsg(&info->msgBuf, "can not insert into schemaless db:", dbFname); return TSDB_CODE_SML_INVALID_DB_CONF; } return TSDB_CODE_SUCCESS; } +static void smlInsertCallback(void* param, void* res, int32_t code) { + if (code != TSDB_CODE_SUCCESS) { + uError("failed to execute, reason:%s\n", taos_errstr(res)); + } + SRequestObj *pRequest = (SRequestObj *)res; + int32_t rows = taos_affected_rows(pRequest); + SSmlHandle* info = (SSmlHandle *)param; + + // lock + taosThreadSpinLock(&info->params.lock); + info->params.request->body.resInfo.numOfRows += rows; + if(code != TSDB_CODE_SUCCESS){ + info->params.request->code = code; + } + taosThreadSpinUnlock(&info->params.lock); + // unlock + + printf("SML:0x%"PRIx64" insert finished, code: %d, total: %d, insert: %d\n", info->id, code, info->affectedRows, rows); + Params pParam = info->params; + bool isLast = info->isLast; + smlDestroyInfo(info); + + if(isLast){ + tsem_post(&pParam.sem); + } +} + /** * taos_schemaless_insert() parse and insert data points into database according to * different protocol. @@ -2336,48 +2365,92 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr return NULL; } - SSmlHandle* info = smlBuildSmlInfo(taos, request, (SMLProtocolType)protocol, precision); - if(!info){ - return (TAOS_RES*)request; - } + ((STscObj *)taos)->schemalessType = 1; + SSmlMsgBuf msg = {.buf = request->msgBuf, .len = ERROR_MSG_BUF_DEFAULT_SIZE}; - info->taos->schemalessType = 1; - if(request->pDb == NULL){ - request->code = TSDB_CODE_PAR_DB_NOT_SPECIFIED; - smlBuildInvalidDataMsg(&info->msgBuf, "Database not specified", NULL); + Params params = {.request = request}; + tsem_init(¶ms.sem, 0, 0); + taosThreadSpinInit(&(params.lock), 0); + + int32_t code = catalogGetHandle(((STscObj *)taos)->pAppInfo->clusterId, ¶ms.catalog); + if(code != TSDB_CODE_SUCCESS){ + uError("SML get catalog error %d", code); + request->code = code; goto end; } - if(isSchemalessDb(info) != TSDB_CODE_SUCCESS){ + if(request->pDb == NULL){ + request->code = TSDB_CODE_PAR_DB_NOT_SPECIFIED; + smlBuildInvalidDataMsg(&msg, "Database not specified", NULL); + goto end; + } + + if(isSchemalessDb(taos, params.catalog) != TSDB_CODE_SUCCESS){ request->code = TSDB_CODE_SML_INVALID_DB_CONF; - smlBuildInvalidDataMsg(&info->msgBuf, "Cannot write data to a non schemaless database", NULL); + smlBuildInvalidDataMsg(&msg, "Cannot write data to a non schemaless database", NULL); goto end; } if (!lines) { request->code = TSDB_CODE_SML_INVALID_DATA; - smlBuildInvalidDataMsg(&info->msgBuf, "lines is null", NULL); + smlBuildInvalidDataMsg(&msg, "lines is null", NULL); goto end; } if(protocol < TSDB_SML_LINE_PROTOCOL || protocol > TSDB_SML_JSON_PROTOCOL){ request->code = TSDB_CODE_SML_INVALID_PROTOCOL_TYPE; - smlBuildInvalidDataMsg(&info->msgBuf, "protocol invalidate", NULL); + smlBuildInvalidDataMsg(&msg, "protocol invalidate", NULL); goto end; } if(protocol == TSDB_SML_LINE_PROTOCOL && (precision < TSDB_SML_TIMESTAMP_NOT_CONFIGURED || precision > TSDB_SML_TIMESTAMP_NANO_SECONDS)){ request->code = TSDB_CODE_SML_INVALID_PRECISION_TYPE; - smlBuildInvalidDataMsg(&info->msgBuf, "precision invalidate for line protocol", NULL); + smlBuildInvalidDataMsg(&msg, "precision invalidate for line protocol", NULL); goto end; } - info->pRequest->code = smlProcess(info, lines, numLines); + int32_t perBatch = 20000; + for (int i = 0; i < ceil(((double)numLines)/perBatch); ++i) { + SRequestObj* req = (SRequestObj*)createRequest((STscObj *)taos, TSDB_SQL_INSERT); + if(!req){ + request->code = TSDB_CODE_OUT_OF_MEMORY; + uError("SML:taos_schemaless_insert error request is null"); + goto end; + } + SSmlHandle* info = smlBuildSmlInfo(taos, req, (SMLProtocolType)protocol, precision); + if(!info){ + request->code = TSDB_CODE_OUT_OF_MEMORY; + uError("SML:taos_schemaless_insert error SSmlHandle is null"); + goto end; + } + + if(numLines >= perBatch){ + numLines -= perBatch; + info->isLast = false; + }else{ + perBatch = numLines; + numLines = 0; + info->isLast = true; + } + + info->params = params; + info->pCatalog = params.catalog; + info->affectedRows = perBatch; + info->pRequest->body.queryFp = smlInsertCallback; + info->pRequest->body.param = info; + code = smlProcess(info, lines, perBatch); + lines += perBatch; + if (code != TSDB_CODE_SUCCESS){ + info->pRequest->body.queryFp(info, req, code); + } + } + tsem_wait(¶ms.sem); end: - info->taos->schemalessType = 0; - uDebug("result:%s", info->msgBuf.buf); - smlDestroyInfo(info); + taosThreadSpinDestroy(¶ms.lock); + tsem_destroy(¶ms.sem); + ((STscObj *)taos)->schemalessType = 0; + uDebug("result:%s", request->msgBuf); return (TAOS_RES*)request; } From a4fba1c70b243571b91c3522d17677e1f3e7fd72 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 10 Jun 2022 13:54:44 +0800 Subject: [PATCH 3/4] feat:add async logic for schemaless --- source/client/src/clientSml.c | 34 ++++++++++++++++------------------ source/client/test/smlTest.cpp | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 3039f93a30..25d15ab11e 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -69,6 +69,7 @@ for (int i = 1; i < keyLen; ++i) { \ #define NCHAR_ADD_LEN 3 // L"nchar" 3 means L" " #define MAX_RETRY_TIMES 5 +#define LINE_BATCH 20 //================================================================================================= typedef TSDB_SML_PROTOCOL_TYPE SMLProtocolType; @@ -164,7 +165,7 @@ typedef struct{ typedef struct { int64_t id; - Params params; + Params *params; bool isLast; SMLProtocolType protocol; @@ -2311,29 +2312,24 @@ static int32_t isSchemalessDb(STscObj *taos, SCatalog *catalog){ } static void smlInsertCallback(void* param, void* res, int32_t code) { - if (code != TSDB_CODE_SUCCESS) { - uError("failed to execute, reason:%s\n", taos_errstr(res)); - } SRequestObj *pRequest = (SRequestObj *)res; - int32_t rows = taos_affected_rows(pRequest); SSmlHandle* info = (SSmlHandle *)param; // lock - taosThreadSpinLock(&info->params.lock); - info->params.request->body.resInfo.numOfRows += rows; if(code != TSDB_CODE_SUCCESS){ - info->params.request->code = code; + taosThreadSpinLock(&info->params->lock); + info->params->request->code = code; + taosThreadSpinUnlock(&info->params->lock); } - taosThreadSpinUnlock(&info->params.lock); // unlock - printf("SML:0x%"PRIx64" insert finished, code: %d, total: %d, insert: %d\n", info->id, code, info->affectedRows, rows); - Params pParam = info->params; + printf("SML:0x%"PRIx64" insert finished, code: %d, total: %d\n", info->id, code, info->affectedRows); + Params *pParam = info->params; bool isLast = info->isLast; smlDestroyInfo(info); if(isLast){ - tsem_post(&pParam.sem); + tsem_post(&pParam->sem); } } @@ -2366,8 +2362,9 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr } ((STscObj *)taos)->schemalessType = 1; - SSmlMsgBuf msg = {.buf = request->msgBuf, .len = ERROR_MSG_BUF_DEFAULT_SIZE}; + SSmlMsgBuf msg = {.len = ERROR_MSG_BUF_DEFAULT_SIZE, .buf = request->msgBuf}; + int cnt = ceil(((double)numLines)/LINE_BATCH); Params params = {.request = request}; tsem_init(¶ms.sem, 0, 0); taosThreadSpinInit(&(params.lock), 0); @@ -2385,7 +2382,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr goto end; } - if(isSchemalessDb(taos, params.catalog) != TSDB_CODE_SUCCESS){ + if(isSchemalessDb(((STscObj *)taos), params.catalog) != TSDB_CODE_SUCCESS){ request->code = TSDB_CODE_SML_INVALID_DB_CONF; smlBuildInvalidDataMsg(&msg, "Cannot write data to a non schemaless database", NULL); goto end; @@ -2409,8 +2406,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr goto end; } - int32_t perBatch = 20000; - for (int i = 0; i < ceil(((double)numLines)/perBatch); ++i) { + for (int i = 0; i < cnt; ++i) { SRequestObj* req = (SRequestObj*)createRequest((STscObj *)taos, TSDB_SQL_INSERT); if(!req){ request->code = TSDB_CODE_OUT_OF_MEMORY; @@ -2424,7 +2420,9 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr goto end; } - if(numLines >= perBatch){ + int32_t perBatch = LINE_BATCH; + + if(numLines > perBatch){ numLines -= perBatch; info->isLast = false; }else{ @@ -2433,7 +2431,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr info->isLast = true; } - info->params = params; + info->params = ¶ms; info->pCatalog = params.catalog; info->affectedRows = perBatch; info->pRequest->body.queryFp = smlInsertCallback; diff --git a/source/client/test/smlTest.cpp b/source/client/test/smlTest.cpp index 8137583978..25bf13a113 100644 --- a/source/client/test/smlTest.cpp +++ b/source/client/test/smlTest.cpp @@ -1325,7 +1325,7 @@ TEST(testCase, sml_oom_Test) { pRes = taos_query(taos, "use oom"); taos_free_result(pRes); - TAOS_RES* res = taos_schemaless_insert(taos, (char**)sql, 100, TSDB_SML_LINE_PROTOCOL, 0); + TAOS_RES* res = taos_schemaless_insert(taos, (char**)sql, sizeof(sql)/sizeof(sql[0]), TSDB_SML_LINE_PROTOCOL, 0); ASSERT_EQ(taos_errno(res), 0); taos_free_result(pRes); } From f364ad7bed0ab8ab9594a3c1e9452e8d24c7f0c4 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Fri, 10 Jun 2022 16:13:41 +0800 Subject: [PATCH 4/4] fix:error in windows --- source/client/src/clientSml.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 25d15ab11e..bf60d25976 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -17,6 +17,9 @@ #include "tname.h" #include "cJSON.h" #include "tglobal.h" +#include "osSemaphore.h" +#include "osThread.h" + //================================================================================================= #define SPACE ' ' @@ -2323,7 +2326,7 @@ static void smlInsertCallback(void* param, void* res, int32_t code) { } // unlock - printf("SML:0x%"PRIx64" insert finished, code: %d, total: %d\n", info->id, code, info->affectedRows); + printf("SML:0x%" PRIx64 " insert finished, code: %d, total: %d\n", info->id, code, info->affectedRows); Params *pParam = info->params; bool isLast = info->isLast; smlDestroyInfo(info); @@ -2362,10 +2365,11 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr } ((STscObj *)taos)->schemalessType = 1; - SSmlMsgBuf msg = {.len = ERROR_MSG_BUF_DEFAULT_SIZE, .buf = request->msgBuf}; + SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf}; int cnt = ceil(((double)numLines)/LINE_BATCH); - Params params = {.request = request}; + Params params; + params.request = request; tsem_init(¶ms.sem, 0, 0); taosThreadSpinInit(&(params.lock), 0);