Merge remote-tracking branch 'origin/develop' into feature/crash_gen
This commit is contained in:
commit
8eb30f62b1
|
@ -24,3 +24,11 @@ ENDIF ()
|
|||
IF (TD_MEM_CHECK)
|
||||
ADD_DEFINITIONS(-DTAOS_MEM_CHECK)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_RANDOM_FILE_FAIL)
|
||||
ADD_DEFINITIONS(-DTAOS_RANDOM_FILE_FAIL)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_RANDOM_NETWORK_FAIL)
|
||||
ADD_DEFINITIONS(-DTAOS_RANDOM_NETWORK_FAIL)
|
||||
ENDIF ()
|
||||
|
|
|
@ -30,4 +30,14 @@ ENDIF ()
|
|||
IF (${MEM_CHECK} MATCHES "true")
|
||||
SET(TD_MEM_CHECK TRUE)
|
||||
MESSAGE(STATUS "build with memory check")
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
IF (${RANDOM_FILE_FAIL} MATCHES "true")
|
||||
SET(TD_RANDOM_FILE_FAIL TRUE)
|
||||
MESSAGE(STATUS "build with random-file-fail enabled")
|
||||
ENDIF ()
|
||||
|
||||
IF (${RANDOM_NETWORK_FAIL} MATCHES "true")
|
||||
SET(TD_RANDOM_NETWORK_FAIL TRUE)
|
||||
MESSAGE(STATUS "build with random-network-fail enabled")
|
||||
ENDIF ()
|
||||
|
|
|
@ -176,8 +176,6 @@ SColumn* tscColumnListInsert(SArray* pColList, SColumnIndex* colIndex);
|
|||
SArray* tscColumnListClone(const SArray* src, int16_t tableIndex);
|
||||
void tscColumnListDestroy(SArray* pColList);
|
||||
|
||||
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters);
|
||||
|
||||
int32_t tscValidateName(SSQLToken* pToken);
|
||||
|
||||
void tscIncStreamExecutionCount(void* pStream);
|
||||
|
|
|
@ -32,8 +32,8 @@ extern "C" {
|
|||
|
||||
#include "qExecutor.h"
|
||||
#include "qsqlparser.h"
|
||||
#include "qsqltype.h"
|
||||
#include "qtsbuf.h"
|
||||
#include "tcmdtype.h"
|
||||
|
||||
// forward declaration
|
||||
struct SSqlInfo;
|
||||
|
@ -395,7 +395,6 @@ TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port,
|
|||
void *param, void **taos);
|
||||
void waitForQueryRsp(void *param, TAOS_RES *tres, int code) ;
|
||||
|
||||
int doAsyncParseSql(SSqlObj* pSql);
|
||||
void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, void (*fp)(), void *param, const char *sqlstr, size_t sqlLen);
|
||||
|
||||
void tscProcessMultiVnodesImportFromFile(SSqlObj *pSql);
|
||||
|
@ -403,13 +402,14 @@ void tscKillSTableQuery(SSqlObj *pSql);
|
|||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
||||
bool tscIsUpdateQuery(SSqlObj* pSql);
|
||||
bool tscHasReachLimitation(SQueryInfo *pQueryInfo, SSqlRes *pRes);
|
||||
|
||||
// todo remove this function.
|
||||
bool tscResultsetFetchCompleted(TAOS_RES *result);
|
||||
|
||||
char *tscGetErrorMsgPayload(SSqlCmd *pCmd);
|
||||
|
||||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
|
||||
void tscQueueAsyncFreeResult(SSqlObj *pSql);
|
||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
void tscGetResultColumnChr(SSqlRes *pRes, SFieldInfo* pFieldInfo, int32_t column);
|
||||
|
||||
|
|
|
@ -213,27 +213,34 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
|
|||
// handle the sub queries of join query
|
||||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockFromSubquery(pSql);
|
||||
} else if (pRes->completed && pCmd->command == TSDB_SQL_FETCH) {
|
||||
if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes.
|
||||
tscTryQueryNextVnode(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
} else if (pRes->completed) {
|
||||
if(pCmd->command == TSDB_SQL_FETCH) {
|
||||
if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes.
|
||||
tscTryQueryNextVnode(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* all available virtual node has been checked already, now we need to check
|
||||
* for the next subclause queries
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
if (pCmd->clauseIndex < pCmd->numOfClause - 1) {
|
||||
tscTryQueryNextClause(pSql, tscAsyncQueryRowsForNextVnode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. has reach the limitation
|
||||
* 2. no remain virtual nodes to be retrieved anymore
|
||||
*/
|
||||
*/
|
||||
(*pSql->fetchFp)(param, pSql, 0);
|
||||
}
|
||||
return;
|
||||
} else if (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE) {
|
||||
// in case of show command, return no data
|
||||
(*pSql->fetchFp)(param, pSql, 0);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
return;
|
||||
} else { // current query is not completed, continue retrieve from node
|
||||
if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE && pCmd->command < TSDB_SQL_LOCAL) {
|
||||
pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH;
|
||||
|
@ -405,17 +412,6 @@ void tscProcessAsyncFree(SSchedMsg *pMsg) {
|
|||
taos_free_result(pSql);
|
||||
}
|
||||
|
||||
void tscQueueAsyncFreeResult(SSqlObj *pSql) {
|
||||
tscDebug("%p sqlObj put in queue to async free", pSql);
|
||||
|
||||
SSchedMsg schedMsg = { 0 };
|
||||
schedMsg.fp = tscProcessAsyncFree;
|
||||
schedMsg.ahandle = pSql;
|
||||
schedMsg.thandle = (void *)1;
|
||||
schedMsg.msg = NULL;
|
||||
taosScheduleTask(tscQhandle, &schedMsg);
|
||||
}
|
||||
|
||||
int tscSendMsgToServer(SSqlObj *pSql);
|
||||
|
||||
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||
|
|
|
@ -406,7 +406,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
pSql->res.qhandle = 0x1;
|
||||
pSql->res.numOfRows = 0;
|
||||
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
||||
taosCacheEmpty(tscCacheHandle);
|
||||
taosCacheEmpty(tscCacheHandle,false);
|
||||
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
||||
tscProcessServerVer(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_CLI_VERSION) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,8 +14,8 @@
|
|||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "qsqltype.h"
|
||||
#include "tcache.h"
|
||||
#include "tcmdtype.h"
|
||||
#include "trpc.h"
|
||||
#include "tscLocalMerge.h"
|
||||
#include "tscLog.h"
|
||||
|
@ -46,10 +46,13 @@ static int32_t minMsgSize() { return tsRpcHeadSize + 100; }
|
|||
|
||||
static void tscSetDnodeIpList(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) {
|
||||
SRpcIpSet* pIpList = &pSql->ipList;
|
||||
pIpList->inUse = 0;
|
||||
if (pVgroupInfo == NULL) {
|
||||
pIpList->numOfIps = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
pIpList->numOfIps = pVgroupInfo->numOfIps;
|
||||
pIpList->inUse = 0;
|
||||
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfIps; ++i) {
|
||||
strcpy(pIpList->fqdn[i], pVgroupInfo->ipAddr[i].fqdn);
|
||||
pIpList->port[i] = pVgroupInfo->ipAddr[i].port;
|
||||
|
@ -539,14 +542,18 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
|
|||
int32_t index = pTableMetaInfo->vgroupIndex;
|
||||
assert(index >= 0);
|
||||
|
||||
pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index];
|
||||
if (pTableMetaInfo->vgroupList->numOfVgroups > 0) {
|
||||
pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index];
|
||||
}
|
||||
tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups);
|
||||
} else {
|
||||
pVgroupInfo = &pTableMeta->vgroupInfo;
|
||||
}
|
||||
|
||||
tscSetDnodeIpList(pSql, pVgroupInfo);
|
||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||
if (pVgroupInfo != NULL) {
|
||||
pQueryMsg->head.vgId = htonl(pVgroupInfo->vgId);
|
||||
}
|
||||
|
||||
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||
pTableIdInfo->tid = htonl(pTableMeta->sid);
|
||||
|
@ -1675,8 +1682,8 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||
|
||||
pTableMetaInfo->pTableMeta =
|
||||
(STableMeta *) taosCachePut(tscCacheHandle, pTableMetaInfo->name, pTableMeta, size, tsTableMetaKeepTimer);
|
||||
pTableMetaInfo->pTableMeta = (STableMeta *) taosCachePut(tscCacheHandle, pTableMetaInfo->name,
|
||||
strlen(pTableMetaInfo->name), pTableMeta, size, tsTableMetaKeepTimer);
|
||||
|
||||
// todo handle out of memory case
|
||||
if (pTableMetaInfo->pTableMeta == NULL) {
|
||||
|
@ -1879,7 +1886,8 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
size_t size = 0;
|
||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg, &size);
|
||||
|
||||
pTableMetaInfo->pTableMeta = taosCachePut(tscCacheHandle, key, (char *)pTableMeta, size, tsTableMetaKeepTimer);
|
||||
pTableMetaInfo->pTableMeta = taosCachePut(tscCacheHandle, key, strlen(key), (char *)pTableMeta, size,
|
||||
tsTableMetaKeepTimer);
|
||||
SSchema *pTableSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
if (pQueryInfo->colList == NULL) {
|
||||
|
@ -1942,16 +1950,15 @@ int tscProcessUseDbRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
int tscProcessDropDbRsp(SSqlObj *UNUSED_PARAM(pSql)) {
|
||||
taosCacheEmpty(tscCacheHandle);
|
||||
taosCacheEmpty(tscCacheHandle, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessDropTableRsp(SSqlObj *pSql) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
|
||||
STableMeta *pTableMeta = taosCacheAcquireByName(tscCacheHandle, pTableMetaInfo->name);
|
||||
if (pTableMeta == NULL) {
|
||||
/* not in cache, abort */
|
||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscCacheHandle, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1975,7 +1982,7 @@ int tscProcessDropTableRsp(SSqlObj *pSql) {
|
|||
int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
|
||||
|
||||
STableMeta *pTableMeta = taosCacheAcquireByName(tscCacheHandle, pTableMetaInfo->name);
|
||||
STableMeta *pTableMeta = taosCacheAcquireByKey(tscCacheHandle, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMeta == NULL) { /* not in cache, abort */
|
||||
return 0;
|
||||
}
|
||||
|
@ -1989,7 +1996,7 @@ int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
|||
|
||||
if (isSuperTable) { // if it is a super table, reset whole query cache
|
||||
tscDebug("%p reset query cache since table:%s is stable", pSql, pTableMetaInfo->name);
|
||||
taosCacheEmpty(tscCacheHandle);
|
||||
taosCacheEmpty(tscCacheHandle, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2125,7 +2132,7 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
|||
taosCacheRelease(tscCacheHandle, (void **)&(pTableMetaInfo->pTableMeta), false);
|
||||
}
|
||||
|
||||
pTableMetaInfo->pTableMeta = (STableMeta *)taosCacheAcquireByName(tscCacheHandle, pTableMetaInfo->name);
|
||||
pTableMetaInfo->pTableMeta = (STableMeta *)taosCacheAcquireByKey(tscCacheHandle, pTableMetaInfo->name, strlen(pTableMetaInfo->name));
|
||||
if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||
tscDebug("%p retrieve table Meta from cache, the number of columns:%d, numOfTags:%d, %p", pSql, tinfo.numOfColumns,
|
||||
|
|
|
@ -148,7 +148,7 @@ void taos_init_imp() {
|
|||
refreshTime = refreshTime < 10 ? 10 : refreshTime;
|
||||
|
||||
if (tscCacheHandle == NULL) {
|
||||
tscCacheHandle = taosCacheInit(refreshTime);
|
||||
tscCacheHandle = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, NULL, "client");
|
||||
}
|
||||
|
||||
tscDebug("client is initialized successfully");
|
||||
|
|
|
@ -1115,31 +1115,6 @@ SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) {
|
|||
return taosArrayGetP(pColumnList, i);
|
||||
}
|
||||
|
||||
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters) {
|
||||
if (numOfFilters == 0) {
|
||||
assert(src == NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SColumnFilterInfo* pFilter = calloc(1, numOfFilters * sizeof(SColumnFilterInfo));
|
||||
|
||||
memcpy(pFilter, src, sizeof(SColumnFilterInfo) * numOfFilters);
|
||||
for (int32_t j = 0; j < numOfFilters; ++j) {
|
||||
|
||||
if (pFilter[j].filterstr) {
|
||||
size_t len = (size_t) pFilter[j].len + 1 * TSDB_NCHAR_SIZE;
|
||||
pFilter[j].pz = (int64_t) calloc(1, len);
|
||||
|
||||
memcpy((char*)pFilter[j].pz, (char*)src[j].pz, (size_t)len);
|
||||
}
|
||||
}
|
||||
|
||||
assert(src->filterstr == 0 || src->filterstr == 1);
|
||||
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
|
||||
|
||||
return pFilter;
|
||||
}
|
||||
|
||||
static void destroyFilterInfo(SColumnFilterInfo* pFilterInfo, int32_t numOfFilters) {
|
||||
for(int32_t i = 0; i < numOfFilters; ++i) {
|
||||
if (pFilterInfo[i].filterstr) {
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_QSQLCMD_H
|
||||
#define TDENGINE_QSQLCMD_H
|
||||
#ifndef TDENGINE_TSQLMSGTYPE_H
|
||||
#define TDENGINE_TSQLMSGTYPE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -109,4 +109,4 @@ extern char *sqlCmd[];
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_QSQLCMD_H
|
||||
#endif // TDENGINE_TSQLMSGTYPE_H
|
|
@ -50,8 +50,8 @@ extern "C" {
|
|||
typedef struct {
|
||||
int8_t type; // Column type
|
||||
int16_t colId; // column ID
|
||||
int32_t bytes; // column bytes
|
||||
int32_t offset; // point offset in SDataRow after the header part
|
||||
int16_t bytes; // column bytes
|
||||
int16_t offset; // point offset in SDataRow after the header part
|
||||
} STColumn;
|
||||
|
||||
#define colType(col) ((col)->type)
|
||||
|
@ -116,7 +116,7 @@ typedef struct {
|
|||
int tdInitTSchemaBuilder(STSchemaBuilder *pBuilder, int32_t version);
|
||||
void tdDestroyTSchemaBuilder(STSchemaBuilder *pBuilder);
|
||||
void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, int32_t version);
|
||||
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int32_t bytes);
|
||||
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int16_t bytes);
|
||||
STSchema *tdGetSchemaFromBuilder(STSchemaBuilder *pBuilder);
|
||||
|
||||
// ----------------- Data row structure
|
||||
|
|
|
@ -33,6 +33,7 @@ extern int32_t tsStatusInterval;
|
|||
extern int16_t tsNumOfVnodesPerCore;
|
||||
extern int16_t tsNumOfTotalVnodes;
|
||||
extern int32_t tsNumOfMnodes;
|
||||
extern int32_t tsEnableVnodeBak;
|
||||
|
||||
// common
|
||||
extern int tsRpcTimer;
|
||||
|
|
|
@ -27,4 +27,6 @@ SSchema tGetTableNameColumnSchema();
|
|||
|
||||
bool tscValidateTableNameLength(size_t len);
|
||||
|
||||
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters);
|
||||
|
||||
#endif // TDENGINE_NAME_H
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
|
||||
#define TSDB_SQL_C
|
||||
|
||||
#include "qsqltype.h"
|
||||
#include "tcmdtype.h"
|
||||
|
|
|
@ -43,7 +43,7 @@ int tdEncodeSchema(void **buf, STSchema *pSchema) {
|
|||
STColumn *pCol = schemaColAt(pSchema, i);
|
||||
tlen += taosEncodeFixedI8(buf, colType(pCol));
|
||||
tlen += taosEncodeFixedI16(buf, colColId(pCol));
|
||||
tlen += taosEncodeFixedI32(buf, colBytes(pCol));
|
||||
tlen += taosEncodeFixedI16(buf, colBytes(pCol));
|
||||
}
|
||||
|
||||
return tlen;
|
||||
|
@ -65,10 +65,10 @@ void *tdDecodeSchema(void *buf, STSchema **pRSchema) {
|
|||
for (int i = 0; i < numOfCols; i++) {
|
||||
int8_t type = 0;
|
||||
int16_t colId = 0;
|
||||
int32_t bytes = 0;
|
||||
int16_t bytes = 0;
|
||||
buf = taosDecodeFixedI8(buf, &type);
|
||||
buf = taosDecodeFixedI16(buf, &colId);
|
||||
buf = taosDecodeFixedI32(buf, &bytes);
|
||||
buf = taosDecodeFixedI16(buf, &bytes);
|
||||
if (tdAddColToSchema(&schemaBuilder, type, colId, bytes) < 0) {
|
||||
tdDestroyTSchemaBuilder(&schemaBuilder);
|
||||
return NULL;
|
||||
|
@ -105,7 +105,7 @@ void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, int32_t version) {
|
|||
pBuilder->version = version;
|
||||
}
|
||||
|
||||
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int32_t bytes) {
|
||||
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int16_t bytes) {
|
||||
if (!isValidDataType(type)) return -1;
|
||||
|
||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||
|
|
|
@ -41,6 +41,8 @@ int32_t tsStatusInterval = 1; // second
|
|||
int16_t tsNumOfVnodesPerCore = 8;
|
||||
int16_t tsNumOfTotalVnodes = TSDB_INVALID_VNODE_NUM;
|
||||
int32_t tsNumOfMnodes = 3;
|
||||
int32_t tsEnableVnodeBak = 1;
|
||||
|
||||
|
||||
// common
|
||||
int32_t tsRpcTimer = 1000;
|
||||
|
@ -422,6 +424,16 @@ static void doInitGlobalConfig() {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "vnodeBak";
|
||||
cfg.ptr = &tsEnableVnodeBak;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 1;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "balance";
|
||||
cfg.ptr = &tsEnableBalance;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
|
|
|
@ -49,4 +49,29 @@ SSchema tGetTableNameColumnSchema() {
|
|||
|
||||
bool tscValidateTableNameLength(size_t len) {
|
||||
return len < TSDB_TABLE_NAME_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
SColumnFilterInfo* tscFilterInfoClone(const SColumnFilterInfo* src, int32_t numOfFilters) {
|
||||
if (numOfFilters == 0) {
|
||||
assert(src == NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SColumnFilterInfo* pFilter = calloc(1, numOfFilters * sizeof(SColumnFilterInfo));
|
||||
|
||||
memcpy(pFilter, src, sizeof(SColumnFilterInfo) * numOfFilters);
|
||||
for (int32_t j = 0; j < numOfFilters; ++j) {
|
||||
|
||||
if (pFilter[j].filterstr) {
|
||||
size_t len = (size_t) pFilter[j].len + 1 * TSDB_NCHAR_SIZE;
|
||||
pFilter[j].pz = (int64_t) calloc(1, len);
|
||||
|
||||
memcpy((char*)pFilter[j].pz, (char*)src[j].pz, (size_t)len);
|
||||
}
|
||||
}
|
||||
|
||||
assert(src->filterstr == 0 || src->filterstr == 1);
|
||||
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
|
||||
|
||||
return pFilter;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,8 @@ void cqDrop(void *handle) {
|
|||
pObj->pStream = NULL;
|
||||
|
||||
cTrace("vgId:%d, id:%d CQ:%s is dropped", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||
tdFreeSchema(pObj->pSchema);
|
||||
free(pObj->sqlStr);
|
||||
free(pObj);
|
||||
|
||||
pthread_mutex_unlock(&pContext->mutex);
|
||||
|
|
|
@ -176,6 +176,7 @@ void dnodeCleanupMgmt() {
|
|||
tsMgmtQset = NULL;
|
||||
tsMgmtQueue = NULL;
|
||||
|
||||
vnodeCleanupResources();
|
||||
}
|
||||
|
||||
void dnodeDispatchToMgmtQueue(SRpcMsg *pMsg) {
|
||||
|
@ -242,8 +243,14 @@ static int32_t dnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
|
|||
int32_t vnode = atoi(de->d_name + 5);
|
||||
if (vnode == 0) continue;
|
||||
|
||||
vnodeList[*numOfVnodes] = vnode;
|
||||
(*numOfVnodes)++;
|
||||
|
||||
if (*numOfVnodes >= TSDB_MAX_VNODES) {
|
||||
dError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
|
||||
continue;
|
||||
} else {
|
||||
vnodeList[*numOfVnodes - 1] = vnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
|
@ -276,7 +283,7 @@ static void *dnodeOpenVnode(void *param) {
|
|||
|
||||
static int32_t dnodeOpenVnodes() {
|
||||
int32_t *vnodeList = calloc(TSDB_MAX_VNODES, sizeof(int32_t));
|
||||
int32_t numOfVnodes;
|
||||
int32_t numOfVnodes = 0;
|
||||
int32_t status = dnodeGetVnodeList(vnodeList, &numOfVnodes);
|
||||
|
||||
if (status != TSDB_CODE_SUCCESS) {
|
||||
|
@ -337,7 +344,7 @@ static int32_t dnodeOpenVnodes() {
|
|||
void dnodeStartStream() {
|
||||
int32_t vnodeList[TSDB_MAX_VNODES];
|
||||
int32_t numOfVnodes = 0;
|
||||
int32_t status = dnodeGetVnodeList(vnodeList, &numOfVnodes);
|
||||
int32_t status = vnodeGetVnodeList(vnodeList, &numOfVnodes);
|
||||
|
||||
if (status != TSDB_CODE_SUCCESS) {
|
||||
dInfo("get dnode list failed");
|
||||
|
@ -352,15 +359,14 @@ void dnodeStartStream() {
|
|||
}
|
||||
|
||||
static void dnodeCloseVnodes() {
|
||||
int32_t *vnodeList = (int32_t *)malloc(sizeof(int32_t) * TSDB_MAX_VNODES);
|
||||
int32_t numOfVnodes;
|
||||
int32_t vnodeList[TSDB_MAX_VNODES];
|
||||
int32_t numOfVnodes = 0;
|
||||
int32_t status;
|
||||
|
||||
status = dnodeGetVnodeList(vnodeList, &numOfVnodes);
|
||||
status = vnodeGetVnodeList(vnodeList, &numOfVnodes);
|
||||
|
||||
if (status != TSDB_CODE_SUCCESS) {
|
||||
dInfo("get dnode list failed");
|
||||
free(vnodeList);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -368,7 +374,6 @@ static void dnodeCloseVnodes() {
|
|||
vnodeClose(vnodeList[i]);
|
||||
}
|
||||
|
||||
free(vnodeList);
|
||||
dInfo("total vnodes:%d are all closed", numOfVnodes);
|
||||
}
|
||||
|
||||
|
@ -391,7 +396,7 @@ static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
|
|||
pCreate->nodes[j].nodeId = htonl(pCreate->nodes[j].nodeId);
|
||||
}
|
||||
|
||||
void *pVnode = vnodeAccquireVnode(pCreate->cfg.vgId);
|
||||
void *pVnode = vnodeAcquireVnode(pCreate->cfg.vgId);
|
||||
if (pVnode != NULL) {
|
||||
int32_t code = vnodeAlter(pVnode, pCreate);
|
||||
vnodeRelease(pVnode);
|
||||
|
|
|
@ -98,11 +98,7 @@ void dnodeDispatchToVnodeReadQueue(SRpcMsg *pMsg) {
|
|||
pHead->vgId = htonl(pHead->vgId);
|
||||
pHead->contLen = htonl(pHead->contLen);
|
||||
|
||||
if (pMsg->msgType == TSDB_MSG_TYPE_FETCH) {
|
||||
pVnode = vnodeGetVnode(pHead->vgId);
|
||||
} else {
|
||||
pVnode = vnodeAccquireVnode(pHead->vgId);
|
||||
}
|
||||
pVnode = vnodeAcquireVnode(pHead->vgId);
|
||||
|
||||
if (pVnode == NULL) {
|
||||
leftLen -= pHead->contLen;
|
||||
|
@ -179,24 +175,19 @@ void dnodeFreeVnodeRqueue(void *rqueue) {
|
|||
// dynamically adjust the number of threads
|
||||
}
|
||||
|
||||
static void dnodeContinueExecuteQuery(void* pVnode, void* qhandle, SReadMsg *pMsg) {
|
||||
void dnodePutItemIntoReadQueue(void *pVnode, void *qhandle) {
|
||||
SReadMsg *pRead = (SReadMsg *)taosAllocateQitem(sizeof(SReadMsg));
|
||||
pRead->rpcMsg = pMsg->rpcMsg;
|
||||
pRead->pCont = qhandle;
|
||||
pRead->contLen = 0;
|
||||
pRead->rpcMsg.msgType = TSDB_MSG_TYPE_QUERY;
|
||||
pRead->pCont = qhandle;
|
||||
pRead->contLen = 0;
|
||||
|
||||
taos_queue queue = vnodeGetRqueue(pVnode);
|
||||
taosWriteQitem(queue, TAOS_QTYPE_RPC, pRead);
|
||||
assert(pVnode != NULL);
|
||||
taos_queue queue = vnodeAcquireRqueue(pVnode);
|
||||
|
||||
taosWriteQitem(queue, TAOS_QTYPE_QUERY, pRead);
|
||||
}
|
||||
|
||||
void dnodeSendRpcReadRsp(void *pVnode, SReadMsg *pRead, int32_t code) {
|
||||
if (code == TSDB_CODE_VND_ACTION_IN_PROGRESS) return;
|
||||
if (code == TSDB_CODE_VND_ACTION_NEED_REPROCESSED) {
|
||||
dnodeContinueExecuteQuery(pVnode, pRead->rspRet.qhandle, pRead);
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pRead->rpcMsg.handle,
|
||||
.pCont = pRead->rspRet.rsp,
|
||||
|
@ -206,6 +197,12 @@ void dnodeSendRpcReadRsp(void *pVnode, SReadMsg *pRead, int32_t code) {
|
|||
|
||||
rpcSendResponse(&rpcRsp);
|
||||
rpcFreeCont(pRead->rpcMsg.pCont);
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
||||
void dnodeDispatchNonRspMsg(void *pVnode, SReadMsg *pRead, int32_t code) {
|
||||
vnodeRelease(pVnode);
|
||||
return;
|
||||
}
|
||||
|
||||
static void *dnodeProcessReadQueue(void *param) {
|
||||
|
@ -219,9 +216,16 @@ static void *dnodeProcessReadQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("%p, msg:%s will be processed in vread queue", pReadMsg->rpcMsg.ahandle, taosMsg[pReadMsg->rpcMsg.msgType]);
|
||||
dDebug("%p, msg:%s will be processed in vread queue, qtype:%d", pReadMsg->rpcMsg.ahandle,
|
||||
taosMsg[pReadMsg->rpcMsg.msgType], type);
|
||||
int32_t code = vnodeProcessRead(pVnode, pReadMsg);
|
||||
dnodeSendRpcReadRsp(pVnode, pReadMsg, code);
|
||||
|
||||
if (type == TAOS_QTYPE_RPC) {
|
||||
dnodeSendRpcReadRsp(pVnode, pReadMsg, code);
|
||||
} else {
|
||||
dnodeDispatchNonRspMsg(pVnode, pReadMsg, code);
|
||||
}
|
||||
|
||||
taosFreeQitem(pReadMsg);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ void *dnodeAllocateVnodeWqueue(void *pVnode);
|
|||
void dnodeFreeVnodeWqueue(void *queue);
|
||||
void *dnodeAllocateVnodeRqueue(void *pVnode);
|
||||
void dnodeFreeVnodeRqueue(void *rqueue);
|
||||
void dnodePutItemIntoReadQueue(void *pVnode, void *qhandle);
|
||||
void dnodeSendRpcVnodeWriteRsp(void *pVnode, void *param, int32_t code);
|
||||
|
||||
int32_t dnodeAllocateMnodePqueue();
|
||||
|
|
|
@ -20,6 +20,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef void* qinfo_t;
|
||||
typedef void (*_qinfo_free_fn_t)(void*);
|
||||
|
||||
/**
|
||||
* create the qinfo object according to QueryTableMsg
|
||||
|
@ -28,15 +29,13 @@ typedef void* qinfo_t;
|
|||
* @param qinfo
|
||||
* @return
|
||||
*/
|
||||
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryTableMsg, qinfo_t* qinfo);
|
||||
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryTableMsg, void* param, _qinfo_free_fn_t fn, qinfo_t* qinfo);
|
||||
|
||||
/**
|
||||
* Destroy QInfo object
|
||||
* @param qinfo qhandle
|
||||
* @param fp destroy callback function, while the qhandle is destoried, invoke the fp
|
||||
* @param param free callback params
|
||||
*/
|
||||
void qDestroyQueryInfo(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||
void qDestroyQueryInfo(qinfo_t qinfo);
|
||||
|
||||
/**
|
||||
* the main query execution function, including query on both table and multitables,
|
||||
|
@ -45,7 +44,7 @@ void qDestroyQueryInfo(qinfo_t qinfo, void (*fp)(void*), void* param);
|
|||
* @param qinfo
|
||||
* @return
|
||||
*/
|
||||
void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||
void qTableQuery(qinfo_t qinfo);
|
||||
|
||||
/**
|
||||
* Retrieve the produced results information, if current query is not paused or completed,
|
||||
|
@ -81,11 +80,16 @@ bool qHasMoreResultsToRetrieve(qinfo_t qinfo);
|
|||
/**
|
||||
* kill current ongoing query and free query handle automatically
|
||||
* @param qinfo qhandle
|
||||
* @param fp destroy callback function, while the qhandle is destoried, invoke the fp
|
||||
* @param param free callback params
|
||||
* @return
|
||||
*/
|
||||
int32_t qKillQuery(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||
int32_t qKillQuery(qinfo_t qinfo);
|
||||
|
||||
void* qOpenQueryMgmt(int32_t vgId);
|
||||
void qSetQueryMgmtClosed(void* pExecutor);
|
||||
void qCleanupQueryMgmt(void* pExecutor);
|
||||
void** qRegisterQInfo(void* pMgmt, void* qInfo);
|
||||
void** qAcquireQInfo(void* pMgmt, void** key);
|
||||
void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool needFree);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -365,6 +365,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TAOS_QTYPE_FWD 1
|
||||
#define TAOS_QTYPE_WAL 2
|
||||
#define TAOS_QTYPE_CQ 3
|
||||
#define TAOS_QTYPE_QUERY 4
|
||||
|
||||
typedef enum {
|
||||
TSDB_SUPER_TABLE = 0, // super table
|
||||
|
|
|
@ -285,9 +285,9 @@ typedef struct {
|
|||
int32_t tid;
|
||||
int16_t tversion;
|
||||
int16_t colId;
|
||||
int16_t type;
|
||||
int16_t bytes;
|
||||
int32_t tagValLen;
|
||||
int16_t numOfTags;
|
||||
int32_t schemaLen;
|
||||
char data[];
|
||||
} SUpdateTableTagValMsg;
|
||||
|
||||
|
|
|
@ -49,16 +49,19 @@ int32_t vnodeAlter(void *pVnode, SMDCreateVnodeMsg *pVnodeCfg);
|
|||
int32_t vnodeClose(int32_t vgId);
|
||||
|
||||
void vnodeRelease(void *pVnode);
|
||||
void* vnodeAccquireVnode(int32_t vgId); // add refcount
|
||||
void* vnodeAcquireVnode(int32_t vgId); // add refcount
|
||||
void* vnodeGetVnode(int32_t vgId); // keep refcount unchanged
|
||||
|
||||
void* vnodeAcquireRqueue(void *);
|
||||
void* vnodeGetRqueue(void *);
|
||||
void* vnodeGetWqueue(int32_t vgId);
|
||||
void* vnodeGetWal(void *pVnode);
|
||||
|
||||
int32_t vnodeProcessWrite(void *pVnode, int qtype, void *pHead, void *item);
|
||||
void vnodeBuildStatusMsg(void * param);
|
||||
int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes);
|
||||
void vnodeBuildStatusMsg(void *param);
|
||||
void vnodeSetAccess(SDMVgroupAccess *pAccess, int32_t numOfVnodes);
|
||||
void vnodeCleanupResources();
|
||||
|
||||
int32_t vnodeProcessRead(void *pVnode, SReadMsg *pReadMsg);
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@ PROJECT(TDengine)
|
|||
ADD_SUBDIRECTORY(shell)
|
||||
ADD_SUBDIRECTORY(taosdemo)
|
||||
ADD_SUBDIRECTORY(taosdump)
|
||||
ADD_SUBDIRECTORY(taosmigrate)
|
|
@ -32,6 +32,7 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wordexp.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include "taos.h"
|
||||
#include "tutil.h"
|
||||
|
@ -54,6 +55,7 @@ static struct argp_option options[] = {
|
|||
{0, 'P', "password", 0, "The password to use when connecting to the server. Default is 'taosdata'.", 3},
|
||||
{0, 'd', "database", 0, "Destination database. Default is 'test'.", 3},
|
||||
{0, 'm', "table_prefix", 0, "Table prefix name. Default is 't'.", 3},
|
||||
{0, 's', "sql file", 0, "The select sql file.", 3},
|
||||
{0, 'M', 0, 0, "Use metric flag.", 13},
|
||||
{0, 'o', "outputfile", 0, "Direct output to the named file. Default is './output.txt'.", 14},
|
||||
{0, 'q', "query_mode", 0, "Query mode--0: SYNC, 1: ASYNC. Default is SYNC.", 6},
|
||||
|
@ -79,6 +81,7 @@ typedef struct DemoArguments {
|
|||
char *password;
|
||||
char *database;
|
||||
char *tb_prefix;
|
||||
char *sqlFile;
|
||||
bool use_metric;
|
||||
bool insert_only;
|
||||
char *output_file;
|
||||
|
@ -120,6 +123,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
case 'o':
|
||||
arguments->output_file = arg;
|
||||
break;
|
||||
case 's':
|
||||
arguments->sqlFile = arg;
|
||||
break;
|
||||
case 'q':
|
||||
arguments->mode = atoi(arg);
|
||||
break;
|
||||
|
@ -179,10 +185,10 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
arguments->tb_prefix = arg;
|
||||
break;
|
||||
case 'M':
|
||||
arguments->use_metric = true;
|
||||
arguments->use_metric = false;
|
||||
break;
|
||||
case 'x':
|
||||
arguments->insert_only = true;
|
||||
arguments->insert_only = false;
|
||||
break;
|
||||
case 'c':
|
||||
if (wordexp(arg, &full_path, 0) != 0) {
|
||||
|
@ -253,6 +259,9 @@ typedef struct {
|
|||
int data_of_rate;
|
||||
int64_t start_time;
|
||||
bool do_aggreFunc;
|
||||
|
||||
char* cols;
|
||||
bool use_metric;
|
||||
|
||||
sem_t mutex_sem;
|
||||
int notFinished;
|
||||
|
@ -305,6 +314,8 @@ void rand_string(char *str, int size);
|
|||
double getCurrentTime();
|
||||
|
||||
void callBack(void *param, TAOS_RES *res, int code);
|
||||
void multiThreadCreateTable(char* cols, bool use_metric, int threads, int ntables, char* db_name, char* tb_prefix, char *ip_addr, uint16_t port, char *user, char *pass);
|
||||
void querySqlFile(TAOS* taos, char* sqlFile);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
SDemoArguments arguments = { NULL, // host
|
||||
|
@ -313,6 +324,7 @@ int main(int argc, char *argv[]) {
|
|||
"taosdata", // password
|
||||
"test", // database
|
||||
"t", // tb_prefix
|
||||
NULL,
|
||||
false, // use_metric
|
||||
false, // insert_only
|
||||
"./output.txt", // output_file
|
||||
|
@ -361,7 +373,7 @@ int main(int argc, char *argv[]) {
|
|||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
enum MODE query_mode = arguments.mode;
|
||||
char *ip_addr = arguments.host;
|
||||
uint16_t port = arguments.port;
|
||||
|
@ -385,6 +397,13 @@ int main(int argc, char *argv[]) {
|
|||
char dataString[STRING_LEN];
|
||||
bool do_aggreFunc = true;
|
||||
|
||||
if (NULL != arguments.sqlFile) {
|
||||
TAOS* qtaos = taos_connect(ip_addr, user, pass, db_name, port);
|
||||
querySqlFile(qtaos, arguments.sqlFile);
|
||||
taos_close(qtaos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(dataString, 0, STRING_LEN);
|
||||
int len = 0;
|
||||
|
||||
|
@ -495,47 +514,19 @@ int main(int argc, char *argv[]) {
|
|||
len += snprintf(cols + len, STRING_LEN - len, ",f%d %s(%d))", colIndex + 1, data_type[colIndex % count_data_type], len_of_binary);
|
||||
}
|
||||
|
||||
if (!use_metric) {
|
||||
/* Create all the tables; */
|
||||
printf("Creating %d table(s)......\n", ntables);
|
||||
for (int i = 0; i < ntables; i++) {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d (ts timestamp%s;", db_name, tb_prefix, i, cols);
|
||||
queryDB(taos, command);
|
||||
}
|
||||
|
||||
printf("Table(s) created!\n");
|
||||
taos_close(taos);
|
||||
|
||||
} else {
|
||||
if (use_metric) {
|
||||
/* Create metric table */
|
||||
printf("Creating meters super table...\n");
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.meters (ts timestamp%s tags (areaid int, loc binary(10))", db_name, cols);
|
||||
queryDB(taos, command);
|
||||
printf("meters created!\n");
|
||||
|
||||
/* Create all the tables; */
|
||||
printf("Creating %d table(s)......\n", ntables);
|
||||
for (int i = 0; i < ntables; i++) {
|
||||
int j;
|
||||
if (i % 10 == 0) {
|
||||
j = 10;
|
||||
} else {
|
||||
j = i % 10;
|
||||
}
|
||||
if (j % 2 == 0) {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d using %s.meters tags (%d,\"%s\");", db_name, tb_prefix, i, db_name, j, "shanghai");
|
||||
} else {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d using %s.meters tags (%d,\"%s\");", db_name, tb_prefix, i, db_name, j, "beijing");
|
||||
}
|
||||
queryDB(taos, command);
|
||||
}
|
||||
|
||||
printf("Table(s) created!\n");
|
||||
taos_close(taos);
|
||||
}
|
||||
/* Wait for table to create */
|
||||
|
||||
|
||||
/* Wait for table to create */
|
||||
multiThreadCreateTable(cols, use_metric, threads, ntables, db_name, tb_prefix, ip_addr, port, user, pass);
|
||||
|
||||
/* Insert data */
|
||||
double ts = getCurrentTime();
|
||||
printf("Inserting data......\n");
|
||||
|
@ -685,6 +676,198 @@ int main(int argc, char *argv[]) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_SQL_SIZE 65536
|
||||
void selectSql(TAOS* taos, char* sqlcmd)
|
||||
{
|
||||
TAOS_RES *pSql = taos_query(taos, sqlcmd);
|
||||
int32_t code = taos_errno(pSql);
|
||||
|
||||
if (code != 0) {
|
||||
printf("Failed to sqlcmd:%s, reason:%s\n", sqlcmd, taos_errstr(pSql));
|
||||
taos_free_result(pSql);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (taos_fetch_row(pSql) != NULL) {
|
||||
count++;
|
||||
}
|
||||
|
||||
taos_free_result(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Function to do regular expression check */
|
||||
static int regexMatch(const char *s, const char *reg, int cflags) {
|
||||
regex_t regex;
|
||||
char msgbuf[100] = {0};
|
||||
|
||||
/* Compile regular expression */
|
||||
if (regcomp(®ex, reg, cflags) != 0) {
|
||||
printf("Fail to compile regex\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Execute regular expression */
|
||||
int reti = regexec(®ex, s, 0, NULL, 0);
|
||||
if (!reti) {
|
||||
regfree(®ex);
|
||||
return 1;
|
||||
} else if (reti == REG_NOMATCH) {
|
||||
regfree(®ex);
|
||||
return 0;
|
||||
} else {
|
||||
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
|
||||
printf("Regex match failed: %s\n", msgbuf);
|
||||
regfree(®ex);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int isCommentLine(char *line) {
|
||||
if (line == NULL) return 1;
|
||||
|
||||
return regexMatch(line, "^\\s*#.*", REG_EXTENDED);
|
||||
}
|
||||
|
||||
void querySqlFile(TAOS* taos, char* sqlFile)
|
||||
{
|
||||
FILE *fp = fopen(sqlFile, "r");
|
||||
if (fp == NULL) {
|
||||
printf("failed to open file %s, reason:%s\n", sqlFile, strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int read_len = 0;
|
||||
char * cmd = calloc(1, MAX_SQL_SIZE);
|
||||
size_t cmd_len = 0;
|
||||
char * line = NULL;
|
||||
size_t line_len = 0;
|
||||
|
||||
double t = getCurrentTime();
|
||||
|
||||
while ((read_len = getline(&line, &line_len, fp)) != -1) {
|
||||
if (read_len >= MAX_SQL_SIZE) continue;
|
||||
line[--read_len] = '\0';
|
||||
|
||||
if (read_len == 0 || isCommentLine(line)) { // line starts with #
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[read_len - 1] == '\\') {
|
||||
line[read_len - 1] = ' ';
|
||||
memcpy(cmd + cmd_len, line, read_len);
|
||||
cmd_len += read_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(cmd + cmd_len, line, read_len);
|
||||
selectSql(taos, cmd);
|
||||
memset(cmd, 0, MAX_SQL_SIZE);
|
||||
cmd_len = 0;
|
||||
}
|
||||
|
||||
t = getCurrentTime() - t;
|
||||
printf("run %s took %.6f second(s)\n\n", sqlFile, t);
|
||||
|
||||
free(cmd);
|
||||
if (line) free(line);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
void * createTable(void *sarg)
|
||||
{
|
||||
char command[BUFFER_SIZE] = "\0";
|
||||
|
||||
info *winfo = (info *)sarg;
|
||||
|
||||
if (!winfo->use_metric) {
|
||||
/* Create all the tables; */
|
||||
printf("Creating table from %d to %d\n", winfo->start_table_id, winfo->end_table_id);
|
||||
for (int i = winfo->start_table_id; i <= winfo->end_table_id; i++) {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d (ts timestamp%s;", winfo->db_name, winfo->tb_prefix, i, winfo->cols);
|
||||
queryDB(winfo->taos, command);
|
||||
}
|
||||
|
||||
taos_close(winfo->taos);
|
||||
|
||||
} else {
|
||||
/* Create all the tables; */
|
||||
printf("Creating table from %d to %d\n", winfo->start_table_id, winfo->end_table_id);
|
||||
for (int i = winfo->start_table_id; i <= winfo->end_table_id; i++) {
|
||||
int j;
|
||||
if (i % 10 == 0) {
|
||||
j = 10;
|
||||
} else {
|
||||
j = i % 10;
|
||||
}
|
||||
if (j % 2 == 0) {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d using %s.meters tags (%d,\"%s\");", winfo->db_name, winfo->tb_prefix, i, winfo->db_name, j, "shanghai");
|
||||
} else {
|
||||
snprintf(command, BUFFER_SIZE, "create table if not exists %s.%s%d using %s.meters tags (%d,\"%s\");", winfo->db_name, winfo->tb_prefix, i, winfo->db_name, j, "beijing");
|
||||
}
|
||||
queryDB(winfo->taos, command);
|
||||
}
|
||||
taos_close(winfo->taos);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void multiThreadCreateTable(char* cols, bool use_metric, int threads, int ntables, char* db_name, char* tb_prefix, char *ip_addr, uint16_t port, char *user, char *pass) {
|
||||
double ts = getCurrentTime();
|
||||
printf("create table......\n");
|
||||
pthread_t *pids = malloc(threads * sizeof(pthread_t));
|
||||
info *infos = malloc(threads * sizeof(info));
|
||||
|
||||
int a = ntables / threads;
|
||||
if (a < 1) {
|
||||
threads = ntables;
|
||||
a = 1;
|
||||
}
|
||||
|
||||
int b = 0;
|
||||
if (threads != 0)
|
||||
b = ntables % threads;
|
||||
int last = 0;
|
||||
for (int i = 0; i < threads; i++) {
|
||||
info *t_info = infos + i;
|
||||
t_info->threadID = i;
|
||||
tstrncpy(t_info->db_name, db_name, MAX_DB_NAME_SIZE);
|
||||
tstrncpy(t_info->tb_prefix, tb_prefix, MAX_TB_NAME_SIZE);
|
||||
t_info->taos = taos_connect(ip_addr, user, pass, db_name, port);
|
||||
t_info->start_table_id = last;
|
||||
t_info->end_table_id = i < b ? last + a : last + a - 1;
|
||||
last = t_info->end_table_id + 1;
|
||||
t_info->use_metric = use_metric;
|
||||
t_info->cols = cols;
|
||||
pthread_create(pids + i, NULL, createTable, t_info);
|
||||
}
|
||||
|
||||
for (int i = 0; i < threads; i++) {
|
||||
pthread_join(pids[i], NULL);
|
||||
}
|
||||
|
||||
double t = getCurrentTime() - ts;
|
||||
printf("Spent %.4f seconds to create %d tables with %d connections\n", t, ntables, threads);
|
||||
|
||||
for (int i = 0; i < threads; i++) {
|
||||
info *t_info = infos + i;
|
||||
taos_close(t_info->taos);
|
||||
sem_destroy(&(t_info->mutex_sem));
|
||||
sem_destroy(&(t_info->lock_sem));
|
||||
}
|
||||
|
||||
free(pids);
|
||||
free(infos);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
void *readTable(void *sarg) {
|
||||
info *rinfo = (info *)sarg;
|
||||
TAOS *taos = rinfo->taos;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/vnode/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/common/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
|
||||
AUX_SOURCE_DIRECTORY(. SRC)
|
||||
|
||||
ADD_EXECUTABLE(taosmigrate ${SRC})
|
||||
TARGET_LINK_LIBRARIES(taosmigrate common tutil cJson)
|
||||
ENDIF ()
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(./taosmigrate.c PROPERTIES COMPILE_FLAGS -w)
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "taosmigrate.h"
|
||||
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{0, 'r', "data dir", 0, "data dir", 0},
|
||||
{0, 'd', "dnodeId", 0, "dnode id", 1},
|
||||
{0, 'p', "port", 0, "dnode port", 1},
|
||||
{0, 'f', "fqdn", 0, "dnode fqdn", 1},
|
||||
{0, 'g', "multi dnodes", 0, "multi dnode info, e.g. \"2 7030 fqdn1, 3 8030 fqdn2\"", 2},
|
||||
{0}};
|
||||
|
||||
/* Used by main to communicate with parse_opt. */
|
||||
struct arguments {
|
||||
char* dataDir;
|
||||
int32_t dnodeId;
|
||||
uint16_t port;
|
||||
char* fqdn;
|
||||
char* dnodeGroups;
|
||||
char** arg_list;
|
||||
int arg_list_len;
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||
struct arguments *arguments = state->input;
|
||||
switch (key) {
|
||||
case 'w':
|
||||
arguments->dataDir = arg;
|
||||
break;
|
||||
case 'd':
|
||||
arguments->dnodeId = atoi(arg);
|
||||
break;
|
||||
case 'p':
|
||||
arguments->port = atoi(arg);
|
||||
break;
|
||||
case 'f':
|
||||
arguments->fqdn = arg;
|
||||
case 'g':
|
||||
arguments->dnodeGroups = arg;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
arguments->arg_list = &state->argv[state->next - 1];
|
||||
arguments->arg_list_len = state->argc - state->next + 1;
|
||||
state->next = state->argc;
|
||||
|
||||
argp_usage(state);
|
||||
break;
|
||||
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct argp argp = {options, parse_opt, 0, 0};
|
||||
struct arguments arguments = {NULL, 0, 0, NULL, NULL, NULL, 0};
|
||||
SdnodeGroup tsDnodeGroup = {0};
|
||||
|
||||
int tSystemShell(const char * cmd)
|
||||
{
|
||||
FILE * fp;
|
||||
int res;
|
||||
char buf[1024];
|
||||
if (cmd == NULL) {
|
||||
printf("tSystem cmd is NULL!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fp = popen(cmd, "r") ) == NULL) {
|
||||
printf("popen cmd:%s error: %s/n", cmd, strerror(errno));
|
||||
return -1;
|
||||
} else {
|
||||
while(fgets(buf, sizeof(buf), fp)) {
|
||||
printf("popen result:%s", buf);
|
||||
}
|
||||
|
||||
if ((res = pclose(fp)) == -1) {
|
||||
printf("close popen file pointer fp error!\n");
|
||||
} else {
|
||||
printf("popen res is :%d\n", res);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
void taosMvFile(char* destFile, char *srcFile) {
|
||||
char shellCmd[1024+1] = {0};
|
||||
|
||||
//(void)snprintf(shellCmd, 1024, "cp -rf %s %s", srcDir, destDir);
|
||||
(void)snprintf(shellCmd, 1024, "mv -f %s %s", srcFile, destFile);
|
||||
tSystemShell(shellCmd);
|
||||
}
|
||||
|
||||
SdnodeIfo* getDnodeInfo(int32_t dnodeId)
|
||||
{
|
||||
for (int32_t i = 0; i < tsDnodeGroup.dnodeNum; i++) {
|
||||
if (dnodeId == tsDnodeGroup.dnodeArray[i].dnodeId) {
|
||||
return &(tsDnodeGroup.dnodeArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void parseOneDnodeInfo(char* buf, SdnodeIfo* pDnodeInfo)
|
||||
{
|
||||
char *ptr;
|
||||
char *p;
|
||||
int32_t i = 0;
|
||||
ptr = strtok_r(buf, " ", &p);
|
||||
while(ptr != NULL) {
|
||||
if (0 == i) {
|
||||
pDnodeInfo->dnodeId = atoi(ptr);
|
||||
} else if (1 == i) {
|
||||
pDnodeInfo->port = atoi(ptr);
|
||||
} else if (2 == i) {
|
||||
tstrncpy(pDnodeInfo->fqdn, ptr, TSDB_FQDN_LEN);
|
||||
} else {
|
||||
printf("input parameter error near:%s\n", buf);
|
||||
exit(-1);
|
||||
}
|
||||
i++;
|
||||
ptr = strtok_r(NULL, " ", &p);
|
||||
}
|
||||
|
||||
snprintf(pDnodeInfo->ep, TSDB_EP_LEN, "%s:%d", pDnodeInfo->fqdn, pDnodeInfo->port);
|
||||
}
|
||||
|
||||
void saveDnodeGroups()
|
||||
{
|
||||
if ((NULL != arguments.fqdn) && (arguments.dnodeId > 0) && (0 != arguments.port)) {
|
||||
//printf("dnodeId:%d port:%d fqdn:%s ep:%s\n", arguments.dnodeId, arguments.port, arguments.fqdn, arguments.ep);
|
||||
|
||||
tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].dnodeId = arguments.dnodeId;
|
||||
tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].port = arguments.port;
|
||||
tstrncpy(tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].fqdn, arguments.fqdn, TSDB_FQDN_LEN);
|
||||
snprintf(tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].ep, TSDB_EP_LEN, "%s:%d", tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].fqdn, tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum].port);
|
||||
|
||||
tsDnodeGroup.dnodeNum++;
|
||||
}
|
||||
|
||||
if (NULL == arguments.dnodeGroups) {
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("dnodeGroups:%s\n", arguments.dnodeGroups);
|
||||
|
||||
char buf[1024];
|
||||
char* str = NULL;
|
||||
char* start = arguments.dnodeGroups;
|
||||
while (NULL != (str = strstr(start, ","))) {
|
||||
memcpy(buf, start, str - start);
|
||||
// parse one dnode info: dnodeId port fqdn ep
|
||||
parseOneDnodeInfo(buf, &(tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum]));
|
||||
tsDnodeGroup.dnodeNum++;
|
||||
// next
|
||||
start = str + 1;
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
if (strlen(start)) {
|
||||
parseOneDnodeInfo(start, &(tsDnodeGroup.dnodeArray[tsDnodeGroup.dnodeNum]));
|
||||
tsDnodeGroup.dnodeNum++;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t main(int32_t argc, char *argv[]) {
|
||||
memset(&tsDnodeGroup, 0, sizeof(SdnodeGroup));
|
||||
|
||||
argp_parse(&argp, argc, argv, 0, 0, &arguments);
|
||||
|
||||
if ((NULL == arguments.dataDir) || ((NULL == arguments.dnodeGroups)
|
||||
&& (NULL == arguments.fqdn || arguments.dnodeId < 1 || 0 == arguments.port))) {
|
||||
printf("input parameter error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
saveDnodeGroups();
|
||||
|
||||
printf("===================arguments:==================\n");
|
||||
printf("oldWal:%s\n", arguments.dataDir);
|
||||
for (int32_t i = 0; i < tsDnodeGroup.dnodeNum; i++) {
|
||||
printf("dnodeId:%d port:%d fqdn:%s ep:%s\n", tsDnodeGroup.dnodeArray[i].dnodeId,
|
||||
tsDnodeGroup.dnodeArray[i].port,
|
||||
tsDnodeGroup.dnodeArray[i].fqdn,
|
||||
tsDnodeGroup.dnodeArray[i].ep);
|
||||
}
|
||||
printf("===========================\n");
|
||||
|
||||
// 1. modify wal for mnode
|
||||
char mnodeWal[TSDB_FILENAME_LEN*2] = {0};
|
||||
(void)snprintf(mnodeWal, TSDB_FILENAME_LEN*2, "%s/mnode/wal/wal0", arguments.dataDir);
|
||||
walModWalFile(mnodeWal);
|
||||
|
||||
// 2. modfiy dnode config: mnodeIpList.json
|
||||
char dnodeIpList[TSDB_FILENAME_LEN*2] = {0};
|
||||
(void)snprintf(dnodeIpList, TSDB_FILENAME_LEN*2, "%s/dnode/mnodeIpList.json", arguments.dataDir);
|
||||
modDnodeIpList(dnodeIpList);
|
||||
|
||||
// 3. modify vnode config: config.json
|
||||
char vnodeDir[TSDB_FILENAME_LEN*2] = {0};
|
||||
(void)snprintf(vnodeDir, TSDB_FILENAME_LEN*2, "%s/vnode", arguments.dataDir);
|
||||
modAllVnode(vnodeDir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TAOS_MIGRATE_H
|
||||
#define TAOS_MIGRATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#ifndef _ALPINE
|
||||
#include <error.h>
|
||||
#endif
|
||||
|
||||
#include <argp.h>
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "taosdef.h"
|
||||
#include "tutil.h"
|
||||
#include "twal.h"
|
||||
#include "tchecksum.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeSdb.h"
|
||||
#include "cJSON.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tglobal.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
//#include "vnode.h"
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#define MAX_DNODE_NUM 128
|
||||
|
||||
|
||||
typedef struct _SdnodeIfo {
|
||||
int32_t dnodeId;
|
||||
uint16_t port;
|
||||
char fqdn[TSDB_FQDN_LEN+1];
|
||||
char ep[TSDB_EP_LEN+1];
|
||||
} SdnodeIfo;
|
||||
|
||||
typedef struct _SdnodeGroup {
|
||||
int32_t dnodeNum;
|
||||
SdnodeIfo dnodeArray[MAX_DNODE_NUM];
|
||||
} SdnodeGroup;
|
||||
|
||||
int tSystemShell(const char * cmd);
|
||||
void taosMvFile(char* destFile, char *srcFile) ;
|
||||
void walModWalFile(char* walfile);
|
||||
SdnodeIfo* getDnodeInfo(int32_t dnodeId);
|
||||
void modDnodeIpList(char* dnodeIpList);
|
||||
void modAllVnode(char *vnodeDir);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "taosmigrate.h"
|
||||
|
||||
//#include "dnodeInt.h"
|
||||
//#include "dnodeMgmt.h"
|
||||
//#include "dnodeVRead.h"
|
||||
//#include "dnodeVWrite.h"
|
||||
//#include "dnodeModule.h"
|
||||
|
||||
static SDMMnodeInfos tsDnodeIpInfos = {0};
|
||||
|
||||
static bool dnodeReadMnodeInfos(char* dnodeIpList) {
|
||||
FILE *fp = fopen(dnodeIpList, "r");
|
||||
if (!fp) {
|
||||
printf("failed to read mnodeIpList.json, file not exist\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
int maxLen = 2000;
|
||||
char *content = calloc(1, maxLen + 1);
|
||||
int len = fread(content, 1, maxLen, fp);
|
||||
if (len <= 0) {
|
||||
free(content);
|
||||
fclose(fp);
|
||||
printf("failed to read mnodeIpList.json, content is null\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
content[len] = 0;
|
||||
cJSON* root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
printf("failed to read mnodeIpList.json, invalid json format\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
cJSON* inUse = cJSON_GetObjectItem(root, "inUse");
|
||||
if (!inUse || inUse->type != cJSON_Number) {
|
||||
printf("failed to read mnodeIpList.json, inUse not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsDnodeIpInfos.inUse = inUse->valueint;
|
||||
|
||||
cJSON* nodeNum = cJSON_GetObjectItem(root, "nodeNum");
|
||||
if (!nodeNum || nodeNum->type != cJSON_Number) {
|
||||
printf("failed to read mnodeIpList.json, nodeNum not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsDnodeIpInfos.nodeNum = nodeNum->valueint;
|
||||
|
||||
cJSON* nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
|
||||
if (!nodeInfos || nodeInfos->type != cJSON_Array) {
|
||||
printf("failed to read mnodeIpList.json, nodeInfos not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
int size = cJSON_GetArraySize(nodeInfos);
|
||||
if (size != tsDnodeIpInfos.nodeNum) {
|
||||
printf("failed to read mnodeIpList.json, nodeInfos size not matched\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cJSON* nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
|
||||
if (nodeInfo == NULL) continue;
|
||||
|
||||
cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
|
||||
if (!nodeId || nodeId->type != cJSON_Number) {
|
||||
printf("failed to read mnodeIpList.json, nodeId not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsDnodeIpInfos.nodeInfos[i].nodeId = nodeId->valueint;
|
||||
|
||||
cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
|
||||
if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
|
||||
printf("failed to read mnodeIpList.json, nodeName not found\n");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
strncpy(tsDnodeIpInfos.nodeInfos[i].nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
|
||||
|
||||
SdnodeIfo* pDnodeInfo = getDnodeInfo(tsDnodeIpInfos.nodeInfos[i].nodeId);
|
||||
if (NULL == pDnodeInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tstrncpy(tsDnodeIpInfos.nodeInfos[i].nodeEp, pDnodeInfo->ep, TSDB_EP_LEN);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
//printf("read mnode iplist successed, numOfIps:%d inUse:%d\n", tsDnodeIpInfos.nodeNum, tsDnodeIpInfos.inUse);
|
||||
//for (int32_t i = 0; i < tsDnodeIpInfos.nodeNum; i++) {
|
||||
// printf("mnode:%d, %s\n", tsDnodeIpInfos.nodeInfos[i].nodeId, tsDnodeIpInfos.nodeInfos[i].nodeEp);
|
||||
//}
|
||||
|
||||
PARSE_OVER:
|
||||
free(content);
|
||||
cJSON_Delete(root);
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void dnodeSaveMnodeInfos(char* dnodeIpList) {
|
||||
FILE *fp = fopen(dnodeIpList, "w");
|
||||
if (!fp) return;
|
||||
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = 2000;
|
||||
char * content = calloc(1, maxLen + 1);
|
||||
|
||||
len += snprintf(content + len, maxLen - len, "{\n");
|
||||
len += snprintf(content + len, maxLen - len, " \"inUse\": %d,\n", tsDnodeIpInfos.inUse);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeNum\": %d,\n", tsDnodeIpInfos.nodeNum);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
|
||||
for (int32_t i = 0; i < tsDnodeIpInfos.nodeNum; i++) {
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", tsDnodeIpInfos.nodeInfos[i].nodeId);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", tsDnodeIpInfos.nodeInfos[i].nodeEp);
|
||||
if (i < tsDnodeIpInfos.nodeNum -1) {
|
||||
len += snprintf(content + len, maxLen - len, " },{\n");
|
||||
} else {
|
||||
len += snprintf(content + len, maxLen - len, " }]\n");
|
||||
}
|
||||
}
|
||||
len += snprintf(content + len, maxLen - len, "}\n");
|
||||
|
||||
fwrite(content, 1, len, fp);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
free(content);
|
||||
|
||||
printf("mod mnode iplist successed\n");
|
||||
}
|
||||
|
||||
void modDnodeIpList(char* dnodeIpList)
|
||||
{
|
||||
(void)dnodeReadMnodeInfos(dnodeIpList);
|
||||
dnodeSaveMnodeInfos(dnodeIpList);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "taosmigrate.h"
|
||||
|
||||
static void recordWrite(int fd, SWalHead *pHead) {
|
||||
|
||||
taosCalcChecksumAppend(0, (uint8_t *)pHead, sizeof(SWalHead));
|
||||
|
||||
int contLen = pHead->len + sizeof(SWalHead);
|
||||
|
||||
if(write(fd, pHead, contLen) != contLen) {
|
||||
printf("failed to write(%s)", strerror(errno));
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void recordMod(SWalHead* pHead)
|
||||
{
|
||||
SDnodeObj *pDnode;
|
||||
|
||||
ESdbTable tableId = (ESdbTable)(pHead->msgType / 10);
|
||||
|
||||
switch (tableId) {
|
||||
case SDB_TABLE_DNODE:
|
||||
case SDB_TABLE_MNODE:
|
||||
pDnode = (SDnodeObj *)pHead->cont;
|
||||
|
||||
printf("dnodeId:%d port:%d fqdn:%s ep:%s\n", pDnode->dnodeId, pDnode->dnodePort, pDnode->dnodeFqdn, pDnode->dnodeEp);
|
||||
|
||||
SdnodeIfo* pDnodeInfo = getDnodeInfo(pDnode->dnodeId);
|
||||
if (NULL == pDnodeInfo) {
|
||||
break;
|
||||
}
|
||||
|
||||
pDnode->dnodePort = pDnodeInfo->port;
|
||||
tstrncpy(pDnode->dnodeFqdn, pDnodeInfo->fqdn, sizeof(pDnode->dnodeFqdn));
|
||||
tstrncpy(pDnode->dnodeEp, pDnodeInfo->ep, sizeof(pDnode->dnodeEp));
|
||||
break;
|
||||
#if 0
|
||||
case SDB_TABLE_ACCOUNT:
|
||||
SAcctObj *pAcct = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
case SDB_TABLE_USER:
|
||||
SUserObj *pUser = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
case SDB_TABLE_DB:
|
||||
SDbObj *pDb = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
case SDB_TABLE_VGROUP:
|
||||
SVgObj *pVgroup = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
case SDB_TABLE_STABLE:
|
||||
SSuperTableObj *pStable = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
case SDB_TABLE_CTABLE:
|
||||
SChildTableObj *pCTable = (SDnodeObj *)pHead->cont;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void walModWalFile(char* walfile) {
|
||||
char *buffer = malloc(1024000); // size for one record
|
||||
if (buffer == NULL) {
|
||||
printf("failed to malloc:%s\n", strerror(errno));
|
||||
return ;
|
||||
}
|
||||
|
||||
SWalHead *pHead = (SWalHead *)buffer;
|
||||
|
||||
int rfd = open(walfile, O_RDONLY);
|
||||
if (rfd < 0) {
|
||||
printf("failed to open %s failed:%s\n", walfile, strerror(errno));
|
||||
free(buffer);
|
||||
return ;
|
||||
}
|
||||
|
||||
char newWalFile[32] = "wal0";
|
||||
int wfd = open(newWalFile, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
|
||||
if (wfd < 0) {
|
||||
printf("wal:%s, failed to open(%s)\n", newWalFile, strerror(errno));
|
||||
free(buffer);
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("start to mod %s into %s\n", walfile, newWalFile);
|
||||
|
||||
while (1) {
|
||||
memset(buffer, 0, 1024000);
|
||||
int ret = read(rfd, pHead, sizeof(SWalHead));
|
||||
if ( ret == 0) break;
|
||||
|
||||
if (ret != sizeof(SWalHead)) {
|
||||
printf("wal:%s, failed to read head, skip, ret:%d(%s)\n", walfile, ret, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
|
||||
printf("wal:%s, cksum is messed up, skip the rest of file\n", walfile);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = read(rfd, pHead->cont, pHead->len);
|
||||
if ( ret != pHead->len) {
|
||||
printf("wal:%s, failed to read body, skip, len:%d ret:%d\n", walfile, pHead->len, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
recordMod(pHead);
|
||||
recordWrite(wfd, pHead);
|
||||
}
|
||||
|
||||
close(rfd);
|
||||
close(wfd);
|
||||
free(buffer);
|
||||
|
||||
taosMvFile(walfile, newWalFile);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "taosmigrate.h"
|
||||
|
||||
|
||||
static int32_t saveVnodeCfg(SVnodeObj *pVnode, char* cfgFile)
|
||||
{
|
||||
FILE *fp = fopen(cfgFile, "w");
|
||||
if (!fp) {
|
||||
printf("failed to open vnode cfg file for write, file:%s error:%s\n", cfgFile, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = 1000;
|
||||
char * content = calloc(1, maxLen + 1);
|
||||
if (content == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len += snprintf(content + len, maxLen - len, "{\n");
|
||||
len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pVnode->db);
|
||||
len += snprintf(content + len, maxLen - len, " \"cfgVersion\": %d,\n", pVnode->cfgVersion);
|
||||
len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pVnode->tsdbCfg.cacheBlockSize);
|
||||
len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pVnode->tsdbCfg.totalBlocks);
|
||||
len += snprintf(content + len, maxLen - len, " \"maxTables\": %d,\n", pVnode->tsdbCfg.maxTables);
|
||||
len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pVnode->tsdbCfg.daysPerFile);
|
||||
len += snprintf(content + len, maxLen - len, " \"daysToKeep\": %d,\n", pVnode->tsdbCfg.keep);
|
||||
len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pVnode->tsdbCfg.keep1);
|
||||
len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pVnode->tsdbCfg.keep2);
|
||||
len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pVnode->tsdbCfg.minRowsPerFileBlock);
|
||||
len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pVnode->tsdbCfg.maxRowsPerFileBlock);
|
||||
len += snprintf(content + len, maxLen - len, " \"commitTime\": %d,\n", pVnode->tsdbCfg.commitTime);
|
||||
len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pVnode->tsdbCfg.precision);
|
||||
len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pVnode->tsdbCfg.compression);
|
||||
len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pVnode->walCfg.walLevel);
|
||||
len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pVnode->syncCfg.replica);
|
||||
len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pVnode->walCfg.wals);
|
||||
len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pVnode->syncCfg.quorum);
|
||||
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
|
||||
for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", pVnode->syncCfg.nodeInfo[i].nodeId);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s:%d\"\n", pVnode->syncCfg.nodeInfo[i].nodeFqdn, pVnode->syncCfg.nodeInfo[i].nodePort);
|
||||
|
||||
if (i < pVnode->syncCfg.replica - 1) {
|
||||
len += snprintf(content + len, maxLen - len, " },{\n");
|
||||
} else {
|
||||
len += snprintf(content + len, maxLen - len, " }]\n");
|
||||
}
|
||||
}
|
||||
len += snprintf(content + len, maxLen - len, "}\n");
|
||||
|
||||
fwrite(content, 1, len, fp);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
free(content);
|
||||
|
||||
printf("mod vnode cfg %s successed\n", cfgFile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t readVnodeCfg(SVnodeObj *pVnode, char* cfgFile)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
char *content = NULL;
|
||||
int maxLen = 1000;
|
||||
int32_t ret = -1;
|
||||
|
||||
FILE *fp = fopen(cfgFile, "r");
|
||||
if (!fp) {
|
||||
printf("failed to open vnode cfg file:%s to read, error:%s\n", cfgFile, strerror(errno));
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
content = calloc(1, maxLen + 1);
|
||||
if (content == NULL) {
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
int len = fread(content, 1, maxLen, fp);
|
||||
if (len <= 0) {
|
||||
printf("failed to read vnode cfg, content is null, error:%s\n", strerror(errno));
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
printf("failed to json parse %s, invalid json format\n", cfgFile);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
cJSON *db = cJSON_GetObjectItem(root, "db");
|
||||
if (!db || db->type != cJSON_String || db->valuestring == NULL) {
|
||||
printf("vgId:%d, failed to read vnode cfg, db not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
strcpy(pVnode->db, db->valuestring);
|
||||
|
||||
cJSON *cfgVersion = cJSON_GetObjectItem(root, "cfgVersion");
|
||||
if (!cfgVersion || cfgVersion->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, cfgVersion not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->cfgVersion = cfgVersion->valueint;
|
||||
|
||||
cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
|
||||
if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, cacheBlockSize not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.cacheBlockSize = cacheBlockSize->valueint;
|
||||
|
||||
cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
|
||||
if (!totalBlocks || totalBlocks->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, totalBlocks not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.totalBlocks = totalBlocks->valueint;
|
||||
|
||||
cJSON *maxTables = cJSON_GetObjectItem(root, "maxTables");
|
||||
if (!maxTables || maxTables->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, maxTables not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.maxTables = maxTables->valueint;
|
||||
|
||||
cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
|
||||
if (!daysPerFile || daysPerFile->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, daysPerFile not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.daysPerFile = daysPerFile->valueint;
|
||||
|
||||
cJSON *daysToKeep = cJSON_GetObjectItem(root, "daysToKeep");
|
||||
if (!daysToKeep || daysToKeep->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, daysToKeep not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.keep = daysToKeep->valueint;
|
||||
|
||||
cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
|
||||
if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, daysToKeep1 not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.keep1 = daysToKeep1->valueint;
|
||||
|
||||
cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
|
||||
if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, daysToKeep2 not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.keep2 = daysToKeep2->valueint;
|
||||
|
||||
cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
|
||||
if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, minRowsPerFileBlock not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.minRowsPerFileBlock = minRowsPerFileBlock->valueint;
|
||||
|
||||
cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
|
||||
if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, maxRowsPerFileBlock not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.maxRowsPerFileBlock = maxRowsPerFileBlock->valueint;
|
||||
|
||||
cJSON *commitTime = cJSON_GetObjectItem(root, "commitTime");
|
||||
if (!commitTime || commitTime->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, commitTime not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.commitTime = (int8_t)commitTime->valueint;
|
||||
|
||||
cJSON *precision = cJSON_GetObjectItem(root, "precision");
|
||||
if (!precision || precision->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, precision not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.precision = (int8_t)precision->valueint;
|
||||
|
||||
cJSON *compression = cJSON_GetObjectItem(root, "compression");
|
||||
if (!compression || compression->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, compression not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->tsdbCfg.compression = (int8_t)compression->valueint;
|
||||
|
||||
cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
|
||||
if (!walLevel || walLevel->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, walLevel not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->walCfg.walLevel = (int8_t) walLevel->valueint;
|
||||
|
||||
cJSON *wals = cJSON_GetObjectItem(root, "wals");
|
||||
if (!wals || wals->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, wals not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->walCfg.wals = (int8_t)wals->valueint;
|
||||
pVnode->walCfg.keep = 0;
|
||||
|
||||
cJSON *replica = cJSON_GetObjectItem(root, "replica");
|
||||
if (!replica || replica->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, replica not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->syncCfg.replica = (int8_t)replica->valueint;
|
||||
|
||||
cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
|
||||
if (!quorum || quorum->type != cJSON_Number) {
|
||||
printf("vgId: %d, failed to read vnode cfg, quorum not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->syncCfg.quorum = (int8_t)quorum->valueint;
|
||||
|
||||
cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
|
||||
if (!nodeInfos || nodeInfos->type != cJSON_Array) {
|
||||
printf("vgId:%d, failed to read vnode cfg, nodeInfos not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
int size = cJSON_GetArraySize(nodeInfos);
|
||||
if (size != pVnode->syncCfg.replica) {
|
||||
printf("vgId:%d, failed to read vnode cfg, nodeInfos size not matched\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
|
||||
if (nodeInfo == NULL) continue;
|
||||
|
||||
cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
|
||||
if (!nodeId || nodeId->type != cJSON_Number) {
|
||||
printf("vgId:%d, failed to read vnode cfg, nodeId not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->syncCfg.nodeInfo[i].nodeId = nodeId->valueint;
|
||||
|
||||
cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
|
||||
if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
|
||||
printf("vgId:%d, failed to read vnode cfg, nodeFqdn not found\n", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
taosGetFqdnPortFromEp(nodeEp->valuestring, pVnode->syncCfg.nodeInfo[i].nodeFqdn, &pVnode->syncCfg.nodeInfo[i].nodePort);
|
||||
//pVnode->syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
|
||||
|
||||
|
||||
SdnodeIfo* pDnodeInfo = getDnodeInfo(pVnode->syncCfg.nodeInfo[i].nodeId);
|
||||
if (NULL == pDnodeInfo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pVnode->syncCfg.nodeInfo[i].nodePort = pDnodeInfo->port;
|
||||
tstrncpy(pVnode->syncCfg.nodeInfo[i].nodeFqdn, pDnodeInfo->fqdn, TSDB_FQDN_LEN);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
//printf("read vnode cfg successfully, replcia:%d\n", pVnode->syncCfg.replica);
|
||||
//for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
|
||||
// printf("dnode:%d, %s:%d\n", pVnode->syncCfg.nodeInfo[i].nodeId, pVnode->syncCfg.nodeInfo[i].nodeFqdn, pVnode->syncCfg.nodeInfo[i].nodePort);
|
||||
//}
|
||||
|
||||
PARSE_OVER:
|
||||
tfree(content);
|
||||
cJSON_Delete(root);
|
||||
if (fp) fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void modVnodeCfg(char* vnodeCfg)
|
||||
{
|
||||
int32_t ret;
|
||||
SVnodeObj vnodeObj = {0};
|
||||
ret = readVnodeCfg(&vnodeObj, vnodeCfg);
|
||||
if (0 != ret) {
|
||||
printf("read vnode cfg %s fail!\n", vnodeCfg);
|
||||
return ;
|
||||
}
|
||||
|
||||
(void)saveVnodeCfg(&vnodeObj, vnodeCfg);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
void modAllVnode(char *vnodeDir)
|
||||
{
|
||||
DIR *dir = opendir(vnodeDir);
|
||||
if (dir == NULL) return;
|
||||
|
||||
char filename[1024];
|
||||
struct dirent *de = NULL;
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
|
||||
|
||||
if ((de->d_type & DT_DIR) && (strncmp(de->d_name, "vnode", 5) == 0)) {
|
||||
memset(filename, 0, 1024);
|
||||
snprintf(filename, 1023, "%s/%s/config.json", vnodeDir, de->d_name);
|
||||
modVnodeCfg(filename);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
|
@ -135,7 +135,8 @@ typedef struct SVgObj {
|
|||
char dbName[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
|
||||
int8_t inUse;
|
||||
int8_t accessState;
|
||||
int8_t reserved0[5];
|
||||
int8_t status;
|
||||
int8_t reserved0[4];
|
||||
SVnodeGid vnodeGid[TSDB_MAX_REPLICA];
|
||||
int8_t reserved1[7];
|
||||
int8_t updateEnd[1];
|
||||
|
|
|
@ -41,7 +41,7 @@ int32_t mnodeInitProfile();
|
|||
void mnodeCleanupProfile();
|
||||
|
||||
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port);
|
||||
SConnObj *mnodeAccquireConn(uint32_t connId, char *user, uint32_t ip, uint16_t port);
|
||||
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port);
|
||||
void mnodeReleaseConn(SConnObj *pConn);
|
||||
int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg);
|
||||
|
||||
|
|
|
@ -367,7 +367,6 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
|||
pAccess++;
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
extern void *tsMnodeTmr;
|
||||
static SCacheObj *tsMnodeConnCache = NULL;
|
||||
static uint32_t tsConnIndex = 0;
|
||||
static int32_t tsConnIndex = 0;
|
||||
|
||||
static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
@ -68,7 +68,7 @@ int32_t mnodeInitProfile() {
|
|||
mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_KILL_STREAM, mnodeProcessKillStreamMsg);
|
||||
mnodeAddWriteMsgHandle(TSDB_MSG_TYPE_CM_KILL_CONN, mnodeProcessKillConnectionMsg);
|
||||
|
||||
tsMnodeConnCache = taosCacheInitWithCb(CONN_CHECK_TIME, mnodeFreeConn);
|
||||
tsMnodeConnCache = taosCacheInit(TSDB_DATA_TYPE_INT, CONN_CHECK_TIME, false, mnodeFreeConn, "conn");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t connId = atomic_add_fetch_32(&tsConnIndex, 1);
|
||||
int32_t connId = atomic_add_fetch_32(&tsConnIndex, 1);
|
||||
if (connId == 0) atomic_add_fetch_32(&tsConnIndex, 1);
|
||||
|
||||
SConnObj connObj = {
|
||||
|
@ -100,9 +100,7 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
|||
};
|
||||
tstrncpy(connObj.user, user, sizeof(connObj.user));
|
||||
|
||||
char key[10];
|
||||
sprintf(key, "%u", connId);
|
||||
SConnObj *pConn = taosCachePut(tsMnodeConnCache, key, &connObj, sizeof(connObj), CONN_KEEP_TIME);
|
||||
SConnObj *pConn = taosCachePut(tsMnodeConnCache, &connId, sizeof(int32_t), &connObj, sizeof(connObj), CONN_KEEP_TIME);
|
||||
|
||||
mDebug("connId:%d, is created, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
|
||||
return pConn;
|
||||
|
@ -113,12 +111,9 @@ void mnodeReleaseConn(SConnObj *pConn) {
|
|||
taosCacheRelease(tsMnodeConnCache, (void **)&pConn, false);
|
||||
}
|
||||
|
||||
SConnObj *mnodeAccquireConn(uint32_t connId, char *user, uint32_t ip, uint16_t port) {
|
||||
char key[10];
|
||||
sprintf(key, "%u", connId);
|
||||
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port) {
|
||||
uint64_t expireTime = CONN_KEEP_TIME * 1000 + (uint64_t)taosGetTimestampMs();
|
||||
|
||||
SConnObj *pConn = taosCacheUpdateExpireTimeByName(tsMnodeConnCache, key, expireTime);
|
||||
SConnObj *pConn = taosCacheUpdateExpireTimeByName(tsMnodeConnCache, &connId, sizeof(int32_t), expireTime);
|
||||
if (pConn == NULL) {
|
||||
mError("connId:%d, is already destroyed, user:%s ip:%s:%u", connId, user, taosIpStr(ip), port);
|
||||
return NULL;
|
||||
|
@ -547,7 +542,8 @@ static int32_t mnodeProcessKillQueryMsg(SMnodeMsg *pMsg) {
|
|||
|
||||
int32_t queryId = (int32_t)strtol(queryIdStr, NULL, 10);
|
||||
|
||||
SConnObj *pConn = taosCacheAcquireByName(tsMnodeConnCache, connIdStr);
|
||||
int32_t connId = atoi(connIdStr);
|
||||
SConnObj *pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
|
||||
if (pConn == NULL) {
|
||||
mError("connId:%s, failed to kill queryId:%d, conn not exist", connIdStr, queryId);
|
||||
return TSDB_CODE_MND_INVALID_CONN_ID;
|
||||
|
@ -576,8 +572,9 @@ static int32_t mnodeProcessKillStreamMsg(SMnodeMsg *pMsg) {
|
|||
}
|
||||
|
||||
int32_t streamId = (int32_t)strtol(streamIdStr, NULL, 10);
|
||||
int32_t connId = atoi(connIdStr);
|
||||
|
||||
SConnObj *pConn = taosCacheAcquireByName(tsMnodeConnCache, connIdStr);
|
||||
SConnObj *pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
|
||||
if (pConn == NULL) {
|
||||
mError("connId:%s, failed to kill streamId:%d, conn not exist", connIdStr, streamId);
|
||||
return TSDB_CODE_MND_INVALID_CONN_ID;
|
||||
|
@ -594,7 +591,8 @@ static int32_t mnodeProcessKillConnectionMsg(SMnodeMsg *pMsg) {
|
|||
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||
|
||||
SCMKillConnMsg *pKill = pMsg->rpcMsg.pCont;
|
||||
SConnObj * pConn = taosCacheAcquireByName(tsMnodeConnCache, pKill->queryId);
|
||||
int32_t connId = atoi(pKill->queryId);
|
||||
SConnObj * pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
|
||||
if (pConn == NULL) {
|
||||
mError("connId:%s, failed to kill, conn not exist", pKill->queryId);
|
||||
return TSDB_CODE_MND_INVALID_CONN_ID;
|
||||
|
|
|
@ -65,7 +65,7 @@ int32_t mnodeInitShow() {
|
|||
mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_CONNECT, mnodeProcessConnectMsg);
|
||||
mnodeAddReadMsgHandle(TSDB_MSG_TYPE_CM_USE_DB, mnodeProcessUseMsg);
|
||||
|
||||
tsMnodeShowCache = taosCacheInitWithCb(5, mnodeFreeShowObj);
|
||||
tsMnodeShowCache = taosCacheInit(TSDB_DATA_TYPE_INT, 5, false, mnodeFreeShowObj, "show");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -364,10 +364,7 @@ static bool mnodeCheckShowFinished(SShowObj *pShow) {
|
|||
}
|
||||
|
||||
static bool mnodeAccquireShowObj(SShowObj *pShow) {
|
||||
char key[10];
|
||||
sprintf(key, "%d", pShow->index);
|
||||
|
||||
SShowObj *pSaved = taosCacheAcquireByName(tsMnodeShowCache, key);
|
||||
SShowObj *pSaved = taosCacheAcquireByKey(tsMnodeShowCache, &pShow->index, sizeof(int32_t));
|
||||
if (pSaved == pShow) {
|
||||
mDebug("%p, show is accquired from cache", pShow);
|
||||
return true;
|
||||
|
@ -378,14 +375,11 @@ static bool mnodeAccquireShowObj(SShowObj *pShow) {
|
|||
|
||||
static void *mnodePutShowObj(SShowObj *pShow, int32_t size) {
|
||||
if (tsMnodeShowCache != NULL) {
|
||||
char key[10];
|
||||
pShow->index = atomic_add_fetch_32(&tsShowObjIndex, 1);
|
||||
sprintf(key, "%d", pShow->index);
|
||||
|
||||
SShowObj *newQhandle = taosCachePut(tsMnodeShowCache, key, pShow, size, 6);
|
||||
SShowObj *newQhandle = taosCachePut(tsMnodeShowCache, &pShow->index, sizeof(int32_t), pShow, size, 6);
|
||||
mDebug("%p, show is put into cache, index:%d", newQhandle, pShow->index);
|
||||
free(pShow);
|
||||
|
||||
mDebug("%p, show is put into cache, index:%s", newQhandle, key);
|
||||
return newQhandle;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "mnodeVgroup.h"
|
||||
#include "mnodePeer.h"
|
||||
|
||||
typedef enum {
|
||||
TAOS_VG_STATUS_READY,
|
||||
TAOS_VG_STATUS_DROPPING
|
||||
} EVgroupStatus;
|
||||
|
||||
static void *tsVgroupSdb = NULL;
|
||||
static int32_t tsVgUpdateSize = 0;
|
||||
|
||||
|
@ -279,7 +284,7 @@ void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t o
|
|||
pNextV++;
|
||||
}
|
||||
|
||||
if (i == openVnodes) {
|
||||
if (i == openVnodes && pVgroup->status == TAOS_VG_STATUS_READY) {
|
||||
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
||||
}
|
||||
|
||||
|
@ -728,6 +733,7 @@ void mnodeSendDropVnodeMsg(int32_t vgId, SRpcIpSet *ipSet, void *ahandle) {
|
|||
}
|
||||
|
||||
static void mnodeSendDropVgroupMsg(SVgObj *pVgroup, void *ahandle) {
|
||||
pVgroup->status = TAOS_VG_STATUS_DROPPING; // deleting
|
||||
mDebug("vgId:%d, send drop all vnodes msg, ahandle:%p", pVgroup->vgId, ahandle);
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SRpcIpSet ipSet = mnodeGetIpSetFromIp(pVgroup->vnodeGid[i].pDnode->dnodeEp);
|
||||
|
|
|
@ -86,9 +86,28 @@ extern "C" {
|
|||
} \
|
||||
}
|
||||
|
||||
#ifdef TAOS_RANDOM_NETWORK_FAIL
|
||||
|
||||
ssize_t taos_send_random_fail(int sockfd, const void *buf, size_t len, int flags);
|
||||
|
||||
ssize_t taos_sendto_random_fail(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen);
|
||||
ssize_t taos_read_random_fail(int fd, void *buf, size_t count);
|
||||
ssize_t taos_write_random_fail(int fd, const void *buf, size_t count);
|
||||
|
||||
#define send(sockfd, buf, len, flags) taos_send_random_fail(sockfd, buf, len, flags)
|
||||
#define sendto(sockfd, buf, len, flags, dest_addr, addrlen) \
|
||||
taos_sendto_random_fail(sockfd, buf, len, flags, dest_addr, addrlen)
|
||||
#define taosWriteSocket(fd, buf, len) taos_write_random_fail(fd, buf, len)
|
||||
#define taosReadSocket(fd, buf, len) taos_read_random_fail(fd, buf, len)
|
||||
|
||||
#else
|
||||
|
||||
#define taosWriteSocket(fd, buf, len) write(fd, buf, len)
|
||||
#define taosReadSocket(fd, buf, len) read(fd, buf, len)
|
||||
|
||||
#endif /* TAOS_RANDOM_NETWORK_FAIL */
|
||||
|
||||
#define atomic_load_8(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST)
|
||||
#define atomic_load_16(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST)
|
||||
#define atomic_load_32(ptr) __atomic_load_n((ptr), __ATOMIC_SEQ_CST)
|
||||
|
|
|
@ -270,3 +270,49 @@ int tSystem(const char * cmd)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef TAOS_RANDOM_NETWORK_FAIL
|
||||
|
||||
#define RANDOM_NETWORK_FAIL_FACTOR 20
|
||||
|
||||
ssize_t taos_send_random_fail(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return send(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
ssize_t taos_sendto_random_fail(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
ssize_t taos_read_random_fail(int fd, void *buf, size_t count)
|
||||
{
|
||||
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t taos_write_random_fail(int fd, const void *buf, size_t count)
|
||||
{
|
||||
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return write(fd, buf, count);
|
||||
}
|
||||
|
||||
#endif /* TAOS_RANDOM_NETWORK_FAIL */
|
||||
|
|
|
@ -160,7 +160,7 @@ static void taosGetSystemTimezone() {
|
|||
|
||||
/* load time zone string from /etc/timezone */
|
||||
FILE *f = fopen("/etc/timezone", "r");
|
||||
char buf[65] = {0};
|
||||
char buf[68] = {0};
|
||||
if (f != NULL) {
|
||||
int len = fread(buf, 64, 1, f);
|
||||
if(len < 64 && ferror(f)) {
|
||||
|
@ -170,18 +170,17 @@ static void taosGetSystemTimezone() {
|
|||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
char *lineEnd = strstr(buf, "\n");
|
||||
if (lineEnd != NULL) {
|
||||
*lineEnd = 0;
|
||||
}
|
||||
char *lineEnd = strstr(buf, "\n");
|
||||
if (lineEnd != NULL) {
|
||||
*lineEnd = 0;
|
||||
}
|
||||
|
||||
// for CentOS system, /etc/timezone does not exist. Ignore the TZ environment variables
|
||||
if (strlen(buf) > 0) {
|
||||
setenv("TZ", buf, 1);
|
||||
// for CentOS system, /etc/timezone does not exist. Ignore the TZ environment variables
|
||||
if (strlen(buf) > 0) {
|
||||
setenv("TZ", buf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// get and set default timezone
|
||||
tzset();
|
||||
|
||||
|
|
|
@ -53,12 +53,12 @@ static void httpDestroyContext(void *data) {
|
|||
httpFreeJsonBuf(pContext);
|
||||
httpFreeMultiCmds(pContext);
|
||||
|
||||
httpDebug("context:%p, is destroyed, refCount:%d", pContext, pContext->refCount);
|
||||
httpDebug("context:%p, is destroyed, refCount:%d data:%p", pContext, pContext->refCount, data);
|
||||
tfree(pContext);
|
||||
}
|
||||
|
||||
bool httpInitContexts() {
|
||||
tsHttpServer.contextCache = taosCacheInitWithCb(2, httpDestroyContext);
|
||||
tsHttpServer.contextCache = taosCacheInit(TSDB_DATA_TYPE_BIGINT, 2, false, httpDestroyContext, "restc");
|
||||
if (tsHttpServer.contextCache == NULL) {
|
||||
httpError("failed to init context cache");
|
||||
return false;
|
||||
|
@ -103,17 +103,14 @@ HttpContext *httpCreateContext(int32_t fd) {
|
|||
HttpContext *pContext = calloc(1, sizeof(HttpContext));
|
||||
if (pContext == NULL) return NULL;
|
||||
|
||||
char contextStr[16] = {0};
|
||||
snprintf(contextStr, sizeof(contextStr), "%p", pContext);
|
||||
|
||||
pContext->fd = fd;
|
||||
pContext->httpVersion = HTTP_VERSION_10;
|
||||
pContext->lastAccessTime = taosGetTimestampSec();
|
||||
pContext->state = HTTP_CONTEXT_STATE_READY;
|
||||
|
||||
HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, contextStr, &pContext, sizeof(HttpContext *), 3);
|
||||
|
||||
HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, &pContext, sizeof(void *), &pContext, sizeof(void *), 3);
|
||||
pContext->ppContext = ppContext;
|
||||
httpDebug("context:%p, fd:%d, is created, item:%p", pContext, fd, ppContext);
|
||||
httpDebug("context:%p, fd:%d, is created, data:%p", pContext, fd, ppContext);
|
||||
|
||||
// set the ref to 0
|
||||
taosCacheRelease(tsHttpServer.contextCache, (void**)&ppContext, false);
|
||||
|
@ -122,16 +119,13 @@ HttpContext *httpCreateContext(int32_t fd) {
|
|||
}
|
||||
|
||||
HttpContext *httpGetContext(void *ptr) {
|
||||
char contextStr[16] = {0};
|
||||
snprintf(contextStr, sizeof(contextStr), "%p", ptr);
|
||||
|
||||
HttpContext **ppContext = taosCacheAcquireByName(tsHttpServer.contextCache, contextStr);
|
||||
|
||||
HttpContext **ppContext = taosCacheAcquireByKey(tsHttpServer.contextCache, &ptr, sizeof(HttpContext *));
|
||||
|
||||
if (ppContext) {
|
||||
HttpContext *pContext = *ppContext;
|
||||
if (pContext) {
|
||||
int32_t refCount = atomic_add_fetch_32(&pContext->refCount, 1);
|
||||
httpDebug("context:%p, fd:%d, is accquired, refCount:%d", pContext, pContext->fd, refCount);
|
||||
httpDebug("context:%p, fd:%d, is accquired, data:%p refCount:%d", pContext, pContext->fd, ppContext, refCount);
|
||||
return pContext;
|
||||
}
|
||||
}
|
||||
|
@ -141,9 +135,10 @@ HttpContext *httpGetContext(void *ptr) {
|
|||
void httpReleaseContext(HttpContext *pContext) {
|
||||
int32_t refCount = atomic_sub_fetch_32(&pContext->refCount, 1);
|
||||
assert(refCount >= 0);
|
||||
httpDebug("context:%p, is releasd, refCount:%d", pContext, refCount);
|
||||
|
||||
HttpContext **ppContext = pContext->ppContext;
|
||||
httpDebug("context:%p, is releasd, data:%p refCount:%d", pContext, ppContext, refCount);
|
||||
|
||||
if (tsHttpServer.contextCache != NULL) {
|
||||
taosCacheRelease(tsHttpServer.contextCache, (void **)(&ppContext), false);
|
||||
} else {
|
||||
|
|
|
@ -441,7 +441,7 @@ void httpJsonPairStatus(JsonBuf* buf, int code) {
|
|||
} else {
|
||||
httpJsonPair(buf, "status", 6, "error", 5);
|
||||
httpJsonItemToken(buf);
|
||||
httpJsonPairIntVal(buf, "code", 4, code);
|
||||
httpJsonPairIntVal(buf, "code", 4, code & 0XFFFF);
|
||||
httpJsonItemToken(buf);
|
||||
if (code == TSDB_CODE_MND_DB_NOT_SELECTED) {
|
||||
httpJsonPair(buf, "desc", 4, "failed to create database", 23);
|
||||
|
|
|
@ -174,9 +174,9 @@ void httpSendErrorRespWithDesc(HttpContext *pContext, int errNo, char *desc) {
|
|||
}
|
||||
|
||||
if (desc == NULL) {
|
||||
httpSendErrorRespImp(pContext, httpCode, httpCodeStr, errNo + 1000, httpMsg[errNo]);
|
||||
httpSendErrorRespImp(pContext, httpCode, httpCodeStr, errNo + 5000, httpMsg[errNo]);
|
||||
} else {
|
||||
httpSendErrorRespImp(pContext, httpCode, httpCodeStr, errNo + 1000, desc);
|
||||
httpSendErrorRespImp(pContext, httpCode, httpCodeStr, errNo + 5000, desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,8 @@ void httpSendErrorResp(HttpContext *pContext, int errNo) { httpSendErrorRespWith
|
|||
|
||||
void httpSendTaosdErrorResp(HttpContext *pContext, int errCode) {
|
||||
int httpCode = 400;
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", 1000, (char*)tstrerror(errCode));
|
||||
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", errCode & 0XFFFF, (char*)tstrerror(errCode));
|
||||
}
|
||||
|
||||
void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char* errMsg) {
|
||||
|
@ -200,7 +201,7 @@ void httpSendTaosdInvalidSqlErrorResp(HttpContext *pContext, char* errMsg) {
|
|||
} else {}
|
||||
}
|
||||
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", 1000, temp);
|
||||
httpSendErrorRespImp(pContext, httpCode, "Bad Request", TSDB_CODE_TSC_INVALID_SQL & 0XFFFF, temp);
|
||||
}
|
||||
|
||||
void httpSendSuccResp(HttpContext *pContext, char *desc) {
|
||||
|
|
|
@ -85,6 +85,7 @@ bool httpReadDataImp(HttpContext *pContext) {
|
|||
} else {
|
||||
httpError("context:%p, fd:%d, ip:%s, read from socket error:%d, close connect",
|
||||
pContext, pContext->fd, pContext->ipstr, errno);
|
||||
httpReleaseContext(pContext);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -153,6 +154,7 @@ static bool httpReadData(HttpContext *pContext) {
|
|||
int ret = httpCheckReadCompleted(pContext);
|
||||
if (ret == HTTP_CHECK_BODY_CONTINUE) {
|
||||
//httpDebug("context:%p, fd:%d, ip:%s, not finished yet, wait another event", pContext, pContext->fd, pContext->ipstr);
|
||||
httpReleaseContext(pContext);
|
||||
return false;
|
||||
} else if (ret == HTTP_CHECK_BODY_SUCCESS){
|
||||
httpDebug("context:%p, fd:%d, ip:%s, thread:%s, read size:%d, dataLen:%d",
|
||||
|
@ -161,11 +163,13 @@ static bool httpReadData(HttpContext *pContext) {
|
|||
return true;
|
||||
} else {
|
||||
httpNotifyContextClose(pContext);
|
||||
httpReleaseContext(pContext);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
httpError("context:%p, fd:%d, ip:%s, failed to read http body, close connect", pContext, pContext->fd, pContext->ipstr);
|
||||
httpNotifyContextClose(pContext);
|
||||
httpReleaseContext(pContext);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ void httpCreateSession(HttpContext *pContext, void *taos) {
|
|||
memset(&session, 0, sizeof(HttpSession));
|
||||
session.taos = taos;
|
||||
session.refCount = 1;
|
||||
snprintf(session.id, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||
int32_t len = snprintf(session.id, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||
|
||||
pContext->session = taosCachePut(server->sessionCache, session.id, &session, sizeof(HttpSession), tsHttpSessionExpire);
|
||||
pContext->session = taosCachePut(server->sessionCache, session.id, len, &session, sizeof(HttpSession), tsHttpSessionExpire);
|
||||
// void *temp = pContext->session;
|
||||
// taosCacheRelease(server->sessionCache, (void **)&temp, false);
|
||||
|
||||
|
@ -57,9 +57,9 @@ static void httpFetchSessionImp(HttpContext *pContext) {
|
|||
pthread_mutex_lock(&server->serverMutex);
|
||||
|
||||
char sessionId[HTTP_SESSION_ID_LEN];
|
||||
snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||
int32_t len = snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||
|
||||
pContext->session = taosCacheAcquireByName(server->sessionCache, sessionId);
|
||||
pContext->session = taosCacheAcquireByKey(server->sessionCache, sessionId, len);
|
||||
if (pContext->session != NULL) {
|
||||
atomic_add_fetch_32(&pContext->session->refCount, 1);
|
||||
httpDebug("context:%p, fd:%d, ip:%s, user:%s, find an exist session:%p:%p, sessionRef:%d", pContext, pContext->fd,
|
||||
|
@ -115,7 +115,7 @@ void httpCleanUpSessions() {
|
|||
}
|
||||
|
||||
bool httpInitSessions() {
|
||||
tsHttpServer.sessionCache = taosCacheInitWithCb(5, httpDestroySession);
|
||||
tsHttpServer.sessionCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, 5, false, httpDestroySession, "rests");
|
||||
if (tsHttpServer.sessionCache == NULL) {
|
||||
httpError("failed to init session cache");
|
||||
return false;
|
||||
|
|
|
@ -111,7 +111,7 @@ void mqttStopSystem() {
|
|||
}
|
||||
|
||||
void mqttCleanUpSystem() {
|
||||
mqttInfo("starting to clean up mqtt");
|
||||
mqttInfo("starting to cleanup mqtt");
|
||||
free(recntStatus.user_name);
|
||||
free(recntStatus.password);
|
||||
free(recntStatus.hostname);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "tref.h"
|
||||
#include "tsdb.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "query.h"
|
||||
|
||||
struct SColumnFilterElem;
|
||||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, char* val1, char* val2);
|
||||
|
@ -94,16 +95,13 @@ typedef struct SSingleColumnFilterInfo {
|
|||
} SSingleColumnFilterInfo;
|
||||
|
||||
typedef struct STableQueryInfo { // todo merge with the STableQueryInfo struct
|
||||
int32_t tableIndex;
|
||||
int32_t groupIndex; // group id in table list
|
||||
TSKEY lastKey;
|
||||
int32_t numOfRes;
|
||||
int32_t groupIndex; // group id in table list
|
||||
int16_t queryRangeSet; // denote if the query range is set, only available for interval query
|
||||
int64_t tag;
|
||||
STimeWindow win;
|
||||
STSCursor cur;
|
||||
void* pTable; // for retrieve the page id list
|
||||
|
||||
void* pTable; // for retrieve the page id list
|
||||
SWindowResInfo windowResInfo;
|
||||
} STableQueryInfo;
|
||||
|
||||
|
@ -126,11 +124,6 @@ typedef struct SQueryCostInfo {
|
|||
uint64_t computTime;
|
||||
} SQueryCostInfo;
|
||||
|
||||
//typedef struct SGroupItem {
|
||||
// void *pTable;
|
||||
// STableQueryInfo *info;
|
||||
//} SGroupItem;
|
||||
|
||||
typedef struct SQuery {
|
||||
int16_t numOfCols;
|
||||
int16_t numOfTags;
|
||||
|
@ -172,22 +165,22 @@ typedef struct SQueryRuntimeEnv {
|
|||
STSBuf* pTSBuf;
|
||||
STSCursor cur;
|
||||
SQueryCostInfo summary;
|
||||
bool stableQuery; // super table query or not
|
||||
void* pQueryHandle;
|
||||
void* pSecQueryHandle; // another thread for
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
bool stableQuery; // super table query or not
|
||||
bool topBotQuery; // false
|
||||
int32_t prevGroupId; // previous executed group id
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
} SQueryRuntimeEnv;
|
||||
|
||||
typedef struct SQInfo {
|
||||
void* signature;
|
||||
int32_t pointsInterpo;
|
||||
int32_t code; // error code to returned to client
|
||||
sem_t dataReady;
|
||||
void* tsdb;
|
||||
int32_t vgId;
|
||||
|
||||
void* signature;
|
||||
int32_t pointsInterpo;
|
||||
int32_t code; // error code to returned to client
|
||||
sem_t dataReady;
|
||||
void* tsdb;
|
||||
void* param;
|
||||
int32_t vgId;
|
||||
STableGroupInfo tableGroupInfo; // table id list < only includes the STable list>
|
||||
STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray<STableQueryInfo*> structure
|
||||
SQueryRuntimeEnv runtimeEnv;
|
||||
|
@ -202,8 +195,10 @@ typedef struct SQInfo {
|
|||
* We later may refactor to remove this attribution by using another flag to denote
|
||||
* whether a multimeter query is completed or not.
|
||||
*/
|
||||
int32_t tableIndex;
|
||||
int32_t numOfGroupResultPages;
|
||||
int32_t tableIndex;
|
||||
int32_t numOfGroupResultPages;
|
||||
_qinfo_free_fn_t freeFn;
|
||||
jmp_buf env;
|
||||
} SQInfo;
|
||||
|
||||
#endif // TDENGINE_QUERYEXECUTOR_H
|
||||
|
|
|
@ -13,7 +13,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tglobal.h"
|
||||
#include "qfill.h"
|
||||
#include "taosmsg.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "qExecutor.h"
|
||||
|
@ -22,11 +25,11 @@
|
|||
#include "qresultBuf.h"
|
||||
#include "query.h"
|
||||
#include "queryLog.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscUtil.h" // todo move the function to common module
|
||||
#include "exception.h"
|
||||
#include "tscompression.h"
|
||||
#include "ttime.h"
|
||||
#include "tfile.h"
|
||||
|
||||
/**
|
||||
* check if the primary column is load by default, otherwise, the program will
|
||||
|
@ -87,6 +90,19 @@ typedef struct {
|
|||
STSCursor cur;
|
||||
} SQueryStatusInfo;
|
||||
|
||||
#if 0
|
||||
static UNUSED_FUNC void *u_malloc (size_t __size) {
|
||||
uint32_t v = rand();
|
||||
if (v % 5 <= 1) {
|
||||
return NULL;
|
||||
} else {
|
||||
return malloc(__size);
|
||||
}
|
||||
}
|
||||
|
||||
#define malloc u_malloc
|
||||
#endif
|
||||
|
||||
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
|
||||
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
|
||||
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
|
||||
|
@ -1509,7 +1525,6 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
|
|||
}
|
||||
|
||||
static bool isQueryKilled(SQInfo *pQInfo) {
|
||||
return false;
|
||||
return (pQInfo->code == TSDB_CODE_TSC_QUERY_CANCELLED);
|
||||
}
|
||||
|
||||
|
@ -2586,7 +2601,6 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
|
|||
}
|
||||
|
||||
int64_t getNumOfResultWindowRes(SQuery *pQuery, SWindowResult *pWindowRes) {
|
||||
// int64_t maxOutput = 0;
|
||||
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
|
||||
int32_t functionId = pQuery->pSelectExpr[j].base.functionId;
|
||||
|
||||
|
@ -2604,15 +2618,6 @@ int64_t getNumOfResultWindowRes(SQuery *pQuery, SWindowResult *pWindowRes) {
|
|||
if (pResultInfo->numOfRes > 0) {
|
||||
return pResultInfo->numOfRes;
|
||||
}
|
||||
// if (pResultInfo != NULL && maxOutput < pResultInfo->numOfRes) {
|
||||
// maxOutput = pResultInfo->numOfRes;
|
||||
//
|
||||
// if (maxOutput > 0) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// assert(pResultInfo != NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2623,12 +2628,19 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
|
|||
SQuery * pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
size_t size = taosArrayGetSize(pGroup);
|
||||
|
||||
tFilePage **buffer = pQuery->sdata;
|
||||
int32_t * posList = calloc(size, sizeof(int32_t));
|
||||
|
||||
int32_t* posList = calloc(size, sizeof(int32_t));
|
||||
STableQueryInfo **pTableList = malloc(POINTER_BYTES * size);
|
||||
|
||||
if (pTableList == NULL || posList == NULL) {
|
||||
tfree(posList);
|
||||
tfree(pTableList);
|
||||
|
||||
qError("QInfo:%p failed alloc memory", pQInfo);
|
||||
longjmp(pQInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// todo opt for the case of one table per group
|
||||
int32_t numOfTables = 0;
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
|
@ -4069,7 +4081,7 @@ static SFillColInfo* taosCreateFillColInfo(SQuery* pQuery) {
|
|||
return pFillCol;
|
||||
}
|
||||
|
||||
int32_t doInitQInfo(SQInfo *pQInfo, void *param, void *tsdb, int32_t vgId, bool isSTableQuery) {
|
||||
int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||
|
@ -4085,12 +4097,12 @@ int32_t doInitQInfo(SQInfo *pQInfo, void *param, void *tsdb, int32_t vgId, bool
|
|||
pQInfo->vgId = vgId;
|
||||
|
||||
pRuntimeEnv->pQuery = pQuery;
|
||||
pRuntimeEnv->pTSBuf = param;
|
||||
pRuntimeEnv->pTSBuf = pTsBuf;
|
||||
pRuntimeEnv->cur.vgroupIndex = -1;
|
||||
pRuntimeEnv->stableQuery = isSTableQuery;
|
||||
pRuntimeEnv->prevGroupId = INT32_MIN;
|
||||
|
||||
if (param != NULL) {
|
||||
if (pTsBuf != NULL) {
|
||||
int16_t order = (pQuery->order.order == pRuntimeEnv->pTSBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC;
|
||||
tsBufSetTraverseOrder(pRuntimeEnv->pTSBuf, order);
|
||||
}
|
||||
|
@ -4331,7 +4343,9 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
|||
taosArrayDestroy(s);
|
||||
|
||||
// here we simply set the first table as current table
|
||||
pQuery->current = (STableQueryInfo*) GET_TABLEGROUP(pQInfo, 0);
|
||||
SArray* first = GET_TABLEGROUP(pQInfo, pQInfo->groupIndex);
|
||||
pQuery->current = taosArrayGetP(first, 0);
|
||||
|
||||
scanOneTableDataBlocks(pRuntimeEnv, pQuery->current->lastKey);
|
||||
|
||||
int64_t numOfRes = getNumOfResult(pRuntimeEnv);
|
||||
|
@ -4930,14 +4944,6 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
|||
// record the total elapsed time
|
||||
pRuntimeEnv->summary.elapsedTime += (taosGetTimestampUs() - st);
|
||||
assert(pQInfo->tableqinfoGroupInfo.numOfTables == 1);
|
||||
|
||||
/* check if query is killed or not */
|
||||
if (isQueryKilled(pQInfo)) {
|
||||
qDebug("QInfo:%p query is killed", pQInfo);
|
||||
} else {
|
||||
qDebug("QInfo:%p query paused, %" PRId64 " rows returned, numOfTotal:%" PRId64 " rows",
|
||||
pQInfo, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
||||
}
|
||||
}
|
||||
|
||||
static void stableQueryImpl(SQInfo *pQInfo) {
|
||||
|
@ -4959,10 +4965,6 @@ static void stableQueryImpl(SQInfo *pQInfo) {
|
|||
|
||||
// record the total elapsed time
|
||||
pQInfo->runtimeEnv.summary.elapsedTime += (taosGetTimestampUs() - st);
|
||||
|
||||
if (pQuery->rec.rows == 0) {
|
||||
qDebug("QInfo:%p over, %zu tables queried, %"PRId64" rows are returned", pQInfo, pQInfo->tableqinfoGroupInfo.numOfTables, pQuery->rec.total);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t getColumnIndexInSource(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pExprMsg, SColumnInfo* pTagCols) {
|
||||
|
@ -5074,6 +5076,8 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
|
|||
*/
|
||||
static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList, SSqlFuncMsg ***pExpr,
|
||||
char **tagCond, char** tbnameCond, SColIndex **groupbyCols, SColumnInfo** tagCols) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables);
|
||||
|
||||
pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey);
|
||||
|
@ -5100,7 +5104,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
|
||||
// query msg safety check
|
||||
if (!validateQueryMsg(pQueryMsg)) {
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
code = TSDB_CODE_QRY_INVALID_MSG;
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
char *pMsg = (char *)(pQueryMsg->colList) + sizeof(SColumnInfo) * pQueryMsg->numOfCols;
|
||||
|
@ -5172,7 +5177,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
int16_t functionId = pExprMsg->functionId;
|
||||
if (functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG_DUMMY) {
|
||||
if (pExprMsg->colInfo.flag != TSDB_COL_TAG) { // ignore the column index check for arithmetic expression.
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
code = TSDB_CODE_QRY_INVALID_MSG;
|
||||
goto _cleanup;
|
||||
}
|
||||
} else {
|
||||
// if (!validateExprColumnInfo(pQueryMsg, pExprMsg)) {
|
||||
|
@ -5184,6 +5190,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
}
|
||||
|
||||
if (!validateQuerySourceCols(pQueryMsg, *pExpr)) {
|
||||
code = TSDB_CODE_QRY_INVALID_MSG;
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
|
@ -5191,6 +5198,10 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
|
||||
if (pQueryMsg->numOfGroupCols > 0) { // group by tag columns
|
||||
*groupbyCols = malloc(pQueryMsg->numOfGroupCols * sizeof(SColIndex));
|
||||
if (*groupbyCols == NULL) {
|
||||
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pQueryMsg->numOfGroupCols; ++i) {
|
||||
(*groupbyCols)[i].colId = *(int16_t *)pMsg;
|
||||
|
@ -5246,7 +5257,13 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
|
||||
if (*pMsg != 0) {
|
||||
size_t len = strlen(pMsg) + 1;
|
||||
|
||||
*tbnameCond = malloc(len);
|
||||
if (*tbnameCond == NULL) {
|
||||
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
strcpy(*tbnameCond, pMsg);
|
||||
pMsg += len;
|
||||
}
|
||||
|
@ -5256,7 +5273,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->queryType, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols,
|
||||
pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->intervalTime,
|
||||
pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset);
|
||||
return 0;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_cleanup:
|
||||
tfree(*pExpr);
|
||||
|
@ -5266,7 +5284,8 @@ _cleanup:
|
|||
tfree(*groupbyCols);
|
||||
tfree(*tagCols);
|
||||
tfree(*tagCond);
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t buildAirthmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTableMsg *pQueryMsg) {
|
||||
|
@ -5654,7 +5673,6 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
|
|||
|
||||
STableQueryInfo* item = createTableQueryInfo(&pQInfo->runtimeEnv, pTable, window);
|
||||
item->groupIndex = i;
|
||||
item->tableIndex = tableIndex++;
|
||||
taosArrayPush(p1, &item);
|
||||
taosHashPut(pQInfo->tableqinfoGroupInfo.map, &id.tid, sizeof(id.tid), &item, POINTER_BYTES);
|
||||
}
|
||||
|
@ -5668,7 +5686,8 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
|
|||
pQuery->window = pQueryMsg->window;
|
||||
|
||||
if (sem_init(&pQInfo->dataReady, 0, 0) != 0) {
|
||||
qError("QInfo:%p init dataReady sem failed, reason:%s", pQInfo, strerror(errno));
|
||||
int32_t code = TAOS_SYSTEM_ERROR(errno);
|
||||
qError("QInfo:%p init dataReady sem failed, reason:%s", pQInfo, tstrerror(code));
|
||||
goto _cleanup;
|
||||
}
|
||||
|
||||
|
@ -5679,7 +5698,6 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
|
|||
|
||||
_cleanup:
|
||||
freeQInfo(pQInfo);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -5697,8 +5715,7 @@ static bool isValidQInfo(void *param) {
|
|||
return (sig == (uint64_t)pQInfo);
|
||||
}
|
||||
|
||||
|
||||
static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, bool isSTable) {
|
||||
static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, bool isSTable, void* param, _qinfo_free_fn_t fn) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
||||
|
||||
|
@ -5722,6 +5739,9 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
pQInfo->param = param;
|
||||
pQInfo->freeFn = fn;
|
||||
|
||||
if (pQInfo->tableqinfoGroupInfo.numOfTables == 0) {
|
||||
qDebug("QInfo:%p no table qualified for tag filter, abort query", pQInfo);
|
||||
setQueryStatus(pQuery, QUERY_COMPLETED);
|
||||
|
@ -5785,7 +5805,7 @@ static void freeQInfo(SQInfo *pQInfo) {
|
|||
// todo refactor, extract method to destroytableDataInfo
|
||||
int32_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo);
|
||||
for (int32_t i = 0; i < numOfGroups; ++i) {
|
||||
SArray *p = GET_TABLEGROUP(pQInfo, i);;
|
||||
SArray *p = GET_TABLEGROUP(pQInfo, i);
|
||||
|
||||
size_t num = taosArrayGetSize(p);
|
||||
for(int32_t j = 0; j < num; ++j) {
|
||||
|
@ -5894,8 +5914,16 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qCreateQueryInfo(void *tsdb, int32_t vgId, SQueryTableMsg *pQueryMsg, qinfo_t *pQInfo) {
|
||||
assert(pQueryMsg != NULL);
|
||||
typedef struct SQueryMgmt {
|
||||
SCacheObj *qinfoPool; // query handle pool
|
||||
int32_t vgId;
|
||||
bool closed;
|
||||
pthread_mutex_t lock;
|
||||
} SQueryMgmt;
|
||||
|
||||
int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, void* param, _qinfo_free_fn_t fn,
|
||||
qinfo_t* pQInfo) {
|
||||
assert(pQueryMsg != NULL && tsdb != NULL);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -5984,7 +6012,7 @@ int32_t qCreateQueryInfo(void *tsdb, int32_t vgId, SQueryTableMsg *pQueryMsg, qi
|
|||
goto _over;
|
||||
}
|
||||
|
||||
code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, isSTableQuery);
|
||||
code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, isSTableQuery, param, fn);
|
||||
|
||||
_over:
|
||||
free(tagCond);
|
||||
|
@ -6020,7 +6048,7 @@ static void doDestoryQueryInfo(SQInfo* pQInfo) {
|
|||
freeQInfo(pQInfo);
|
||||
}
|
||||
|
||||
void qDestroyQueryInfo(qinfo_t qHandle, void (*fp)(void*), void* param) {
|
||||
void qDestroyQueryInfo(qinfo_t qHandle) {
|
||||
SQInfo* pQInfo = (SQInfo*) qHandle;
|
||||
if (!isValidQInfo(pQInfo)) {
|
||||
return;
|
||||
|
@ -6030,15 +6058,19 @@ void qDestroyQueryInfo(qinfo_t qHandle, void (*fp)(void*), void* param) {
|
|||
qDebug("QInfo:%p dec refCount, value:%d", pQInfo, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
doDestoryQueryInfo(pQInfo);
|
||||
_qinfo_free_fn_t freeFp = pQInfo->freeFn;
|
||||
void* param = pQInfo->param;
|
||||
|
||||
if (fp != NULL) {
|
||||
fp(param);
|
||||
doDestoryQueryInfo(pQInfo);
|
||||
if (freeFp != NULL) {
|
||||
assert(param != NULL);
|
||||
freeFp(param);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
||||
void qTableQuery(qinfo_t qinfo) {
|
||||
SQInfo *pQInfo = (SQInfo *)qinfo;
|
||||
|
||||
if (pQInfo == NULL || pQInfo->signature != pQInfo) {
|
||||
|
@ -6048,17 +6080,34 @@ void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
|||
|
||||
if (isQueryKilled(pQInfo)) {
|
||||
qDebug("QInfo:%p it is already killed, abort", pQInfo);
|
||||
qDestroyQueryInfo(pQInfo, fp, param);
|
||||
|
||||
sem_post(&pQInfo->dataReady);
|
||||
qDestroyQueryInfo(pQInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pQInfo->tableqinfoGroupInfo.numOfTables == 0) {
|
||||
qDebug("QInfo:%p no table exists for query, abort", pQInfo);
|
||||
|
||||
sem_post(&pQInfo->dataReady);
|
||||
qDestroyQueryInfo(pQInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t ret = setjmp(pQInfo->env);
|
||||
// error occurs, record the error code and return to client
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
pQInfo->code = ret;
|
||||
qDebug("QInfo:%p query abort due to error occurs, code:%s", pQInfo, tstrerror(pQInfo->code));
|
||||
sem_post(&pQInfo->dataReady);
|
||||
qDestroyQueryInfo(pQInfo);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug("QInfo:%p query task is launched", pQInfo);
|
||||
|
||||
SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||
if (onlyQueryTags(pQInfo->runtimeEnv.pQuery)) {
|
||||
assert(pQInfo->runtimeEnv.pQueryHandle == NULL);
|
||||
buildTagQueryResult(pQInfo); // todo support the limit/offset
|
||||
|
@ -6068,8 +6117,18 @@ void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
|||
tableQueryImpl(pQInfo);
|
||||
}
|
||||
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
if (isQueryKilled(pQInfo)) {
|
||||
qDebug("QInfo:%p query is killed", pQInfo);
|
||||
} else if (pQuery->rec.rows == 0) {
|
||||
qDebug("QInfo:%p over, %zu tables queried, %"PRId64" rows are returned", pQInfo, pQInfo->tableqinfoGroupInfo.numOfTables, pQuery->rec.total);
|
||||
} else {
|
||||
qDebug("QInfo:%p query paused, %" PRId64 " rows returned, numOfTotal:%" PRId64 " rows",
|
||||
pQInfo, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
||||
}
|
||||
|
||||
sem_post(&pQInfo->dataReady);
|
||||
qDestroyQueryInfo(pQInfo, fp, param);
|
||||
qDestroyQueryInfo(pQInfo);
|
||||
}
|
||||
|
||||
int32_t qRetrieveQueryResultInfo(qinfo_t qinfo) {
|
||||
|
@ -6162,7 +6221,7 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t qKillQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
||||
int32_t qKillQuery(qinfo_t qinfo) {
|
||||
SQInfo *pQInfo = (SQInfo *)qinfo;
|
||||
|
||||
if (pQInfo == NULL || !isValidQInfo(pQInfo)) {
|
||||
|
@ -6170,8 +6229,7 @@ int32_t qKillQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
|||
}
|
||||
|
||||
setQueryKilled(pQInfo);
|
||||
qDestroyQueryInfo(pQInfo, fp, param);
|
||||
|
||||
qDestroyQueryInfo(pQInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -6309,3 +6367,112 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
|
|||
setQueryStatus(pQuery, QUERY_COMPLETED);
|
||||
}
|
||||
|
||||
void freeqinfoFn(void *qhandle) {
|
||||
void** handle = qhandle;
|
||||
if (handle == NULL || *handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
qKillQuery(*handle);
|
||||
}
|
||||
|
||||
void* qOpenQueryMgmt(int32_t vgId) {
|
||||
const int32_t REFRESH_HANDLE_INTERVAL = 2; // every 2 seconds, refresh handle pool
|
||||
|
||||
char cacheName[128] = {0};
|
||||
sprintf(cacheName, "qhandle_%d", vgId);
|
||||
|
||||
SQueryMgmt* pQueryHandle = calloc(1, sizeof(SQueryMgmt));
|
||||
|
||||
pQueryHandle->qinfoPool = taosCacheInit(TSDB_DATA_TYPE_BIGINT, REFRESH_HANDLE_INTERVAL, true, freeqinfoFn, cacheName);
|
||||
pQueryHandle->closed = false;
|
||||
pthread_mutex_init(&pQueryHandle->lock, NULL);
|
||||
|
||||
qDebug("vgId:%d, open querymgmt success", vgId);
|
||||
return pQueryHandle;
|
||||
}
|
||||
|
||||
void qSetQueryMgmtClosed(void* pQMgmt) {
|
||||
if (pQMgmt == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SQueryMgmt* pQueryMgmt = pQMgmt;
|
||||
qDebug("vgId:%d, set querymgmt closed, wait for all queries cancelled", pQueryMgmt->vgId);
|
||||
|
||||
pthread_mutex_lock(&pQueryMgmt->lock);
|
||||
pQueryMgmt->closed = true;
|
||||
pthread_mutex_unlock(&pQueryMgmt->lock);
|
||||
|
||||
taosCacheEmpty(pQueryMgmt->qinfoPool, true);
|
||||
}
|
||||
|
||||
void qCleanupQueryMgmt(void* pQMgmt) {
|
||||
if (pQMgmt == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SQueryMgmt* pQueryMgmt = pQMgmt;
|
||||
int32_t vgId = pQueryMgmt->vgId;
|
||||
|
||||
assert(pQueryMgmt->closed);
|
||||
|
||||
SCacheObj* pqinfoPool = pQueryMgmt->qinfoPool;
|
||||
pQueryMgmt->qinfoPool = NULL;
|
||||
|
||||
taosCacheCleanup(pqinfoPool);
|
||||
pthread_mutex_destroy(&pQueryMgmt->lock);
|
||||
tfree(pQueryMgmt);
|
||||
|
||||
qDebug("vgId:%d querymgmt cleanup completed", vgId);
|
||||
}
|
||||
|
||||
void** qRegisterQInfo(void* pMgmt, void* qInfo) {
|
||||
if (pMgmt == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SQueryMgmt *pQueryMgmt = pMgmt;
|
||||
if (pQueryMgmt->qinfoPool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&pQueryMgmt->lock);
|
||||
if (pQueryMgmt->closed) {
|
||||
pthread_mutex_unlock(&pQueryMgmt->lock);
|
||||
|
||||
return NULL;
|
||||
} else {
|
||||
void** handle = taosCachePut(pQueryMgmt->qinfoPool, qInfo, POINTER_BYTES, &qInfo, POINTER_BYTES, tsShellActivityTimer*2);
|
||||
pthread_mutex_unlock(&pQueryMgmt->lock);
|
||||
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
void** qAcquireQInfo(void* pMgmt, void** key) {
|
||||
SQueryMgmt *pQueryMgmt = pMgmt;
|
||||
|
||||
if (pQueryMgmt->qinfoPool == NULL || pQueryMgmt->closed) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void** handle = taosCacheAcquireByKey(pQueryMgmt->qinfoPool, key, POINTER_BYTES);
|
||||
if (handle == NULL || *handle == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
void** qReleaseQInfo(void* pMgmt, void* pQInfo, bool needFree) {
|
||||
SQueryMgmt *pQueryMgmt = pMgmt;
|
||||
|
||||
if (pQueryMgmt->qinfoPool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
taosCacheRelease(pQueryMgmt->qinfoPool, pQInfo, needFree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1173,9 +1173,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
size_t len = strlen(cond) + VARSTR_HEADER_SIZE;
|
||||
|
||||
char* p = exception_malloc(len);
|
||||
varDataSetLen(p, len - VARSTR_HEADER_SIZE);
|
||||
memcpy(varDataVal(p), cond, len);
|
||||
|
||||
STR_WITH_SIZE_TO_VARSTR(p, cond, len - VARSTR_HEADER_SIZE);
|
||||
taosArrayPush(pVal->arr, &p);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,16 +15,16 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "qsqlparser.h"
|
||||
#include "queryLog.h"
|
||||
#include "taosdef.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcmdtype.h"
|
||||
#include "tglobal.h"
|
||||
#include "tstoken.h"
|
||||
#include "tstrbuild.h"
|
||||
#include "ttime.h"
|
||||
#include "ttokendef.h"
|
||||
#include "tutil.h"
|
||||
#include "qsqltype.h"
|
||||
#include "tstrbuild.h"
|
||||
#include "queryLog.h"
|
||||
|
||||
SSqlInfo qSQLParse(const char *pStr) {
|
||||
void *pParser = ParseAlloc(malloc);
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
#include <stdio.h>
|
||||
/************ Begin %include sections from the grammar ************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include "tutil.h"
|
||||
#include "qsqlparser.h"
|
||||
#include "tcmdtype.h"
|
||||
#include "tstoken.h"
|
||||
#include "tvariant.h"
|
||||
#include "ttokendef.h"
|
||||
#include "qsqltype.h"
|
||||
#include "tutil.h"
|
||||
#include "tvariant.h"
|
||||
/**************** End of %include directives **********************************/
|
||||
/* These constants specify the various numeric values for terminal symbols
|
||||
** in a format understandable to "makeheaders". This section is blank unless
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct {
|
|||
SRpcInfo *pRpc; // associated SRpcInfo
|
||||
SRpcIpSet ipSet; // ip list provided by app
|
||||
void *ahandle; // handle provided by app
|
||||
void *signature; // for validation
|
||||
struct SRpcConn *pConn; // pConn allocated
|
||||
char msgType; // message type
|
||||
uint8_t *pCont; // content provided by app
|
||||
|
@ -361,6 +362,7 @@ void rpcSendRequest(void *shandle, const SRpcIpSet *pIpSet, SRpcMsg *pMsg) {
|
|||
int contLen = rpcCompressRpcMsg(pMsg->pCont, pMsg->contLen);
|
||||
pContext = (SRpcReqContext *) (pMsg->pCont-sizeof(SRpcHead)-sizeof(SRpcReqContext));
|
||||
pContext->ahandle = pMsg->ahandle;
|
||||
pContext->signature = pContext;
|
||||
pContext->pRpc = (SRpcInfo *)shandle;
|
||||
pContext->ipSet = *pIpSet;
|
||||
pContext->contLen = contLen;
|
||||
|
@ -527,11 +529,13 @@ int rpcReportProgress(void *handle, char *pCont, int contLen) {
|
|||
return code;
|
||||
}
|
||||
|
||||
/* todo: cancel process may have race condition, pContext may have been released
|
||||
just before app calls the rpcCancelRequest */
|
||||
void rpcCancelRequest(void *handle) {
|
||||
SRpcReqContext *pContext = handle;
|
||||
|
||||
// signature is used to check if pContext is freed.
|
||||
// pContext may have been released just before app calls the rpcCancelRequest
|
||||
if (pContext->signature != pContext) return;
|
||||
|
||||
if (pContext->pConn) {
|
||||
tDebug("%s, app trys to cancel request", pContext->pConn->info);
|
||||
rpcCloseConn(pContext->pConn);
|
||||
|
@ -1005,6 +1009,7 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) {
|
|||
static void rpcNotifyClient(SRpcReqContext *pContext, SRpcMsg *pMsg) {
|
||||
SRpcInfo *pRpc = pContext->pRpc;
|
||||
|
||||
pContext->signature = NULL;
|
||||
pContext->pConn = NULL;
|
||||
if (pContext->pRsp) {
|
||||
// for synchronous API
|
||||
|
@ -1529,10 +1534,10 @@ static void rpcAddRef(SRpcInfo *pRpc)
|
|||
static void rpcDecRef(SRpcInfo *pRpc)
|
||||
{
|
||||
if (atomic_sub_fetch_32(&pRpc->refCount, 1) == 0) {
|
||||
rpcCloseConnCache(pRpc->pCache);
|
||||
taosHashCleanup(pRpc->hash);
|
||||
taosTmrCleanUp(pRpc->tmrCtrl);
|
||||
taosIdPoolCleanUp(pRpc->idPool);
|
||||
rpcCloseConnCache(pRpc->pCache);
|
||||
|
||||
tfree(pRpc->connList);
|
||||
pthread_mutex_destroy(&pRpc->mutex);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "tsdbMain.h"
|
||||
#include "tutil.h"
|
||||
#include "ttime.h"
|
||||
#include "tfile.h"
|
||||
|
||||
const char *tsdbFileSuffix[] = {".head", ".data", ".last", "", ".h", ".l"};
|
||||
|
||||
|
|
|
@ -415,11 +415,11 @@ static int32_t tsdbCheckAndSetDefaultCfg(STsdbCfg *pCfg) {
|
|||
|
||||
// Check maxTables
|
||||
if (pCfg->maxTables == -1) {
|
||||
pCfg->maxTables = TSDB_DEFAULT_TABLES;
|
||||
pCfg->maxTables = TSDB_DEFAULT_TABLES+1;
|
||||
} else {
|
||||
if (pCfg->maxTables < TSDB_MIN_TABLES || pCfg->maxTables > TSDB_MAX_TABLES) {
|
||||
if (pCfg->maxTables - 1 < TSDB_MIN_TABLES || pCfg->maxTables - 1 > TSDB_MAX_TABLES) {
|
||||
tsdbError("vgId:%d invalid maxTables configuration! maxTables %d TSDB_MIN_TABLES %d TSDB_MAX_TABLES %d",
|
||||
pCfg->tsdbId, pCfg->maxTables, TSDB_MIN_TABLES, TSDB_MAX_TABLES);
|
||||
pCfg->tsdbId, pCfg->maxTables - 1, TSDB_MIN_TABLES, TSDB_MAX_TABLES);
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,17 +255,46 @@ _err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t colIdCompar(const void* left, const void* right) {
|
||||
int16_t colId = *(int16_t*) left;
|
||||
STColumn* p2 = (STColumn*) right;
|
||||
|
||||
if (colId == p2->colId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (colId < p2->colId)? -1:1;
|
||||
}
|
||||
|
||||
int tsdbUpdateTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg) {
|
||||
STsdbRepo *pRepo = (STsdbRepo *)repo;
|
||||
STsdbMeta *pMeta = pRepo->tsdbMeta;
|
||||
int16_t tversion = htons(pMsg->tversion);
|
||||
|
||||
STable *pTable = tsdbGetTableByUid(pMeta, htobe64(pMsg->uid));
|
||||
pMsg->uid = htobe64(pMsg->uid);
|
||||
pMsg->tid = htonl(pMsg->tid);
|
||||
pMsg->tversion = htons(pMsg->tversion);
|
||||
pMsg->colId = htons(pMsg->colId);
|
||||
pMsg->tagValLen = htonl(pMsg->tagValLen);
|
||||
pMsg->numOfTags = htons(pMsg->numOfTags);
|
||||
pMsg->schemaLen = htonl(pMsg->schemaLen);
|
||||
assert(pMsg->schemaLen == sizeof(STColumn) * pMsg->numOfTags);
|
||||
|
||||
char* d = pMsg->data;
|
||||
for(int32_t i = 0; i < pMsg->numOfTags; ++i) {
|
||||
STColumn* pCol = (STColumn*) d;
|
||||
pCol->colId = htons(pCol->colId);
|
||||
pCol->bytes = htons(pCol->bytes);
|
||||
pCol->offset = 0;
|
||||
|
||||
d += sizeof(STColumn);
|
||||
}
|
||||
|
||||
STable *pTable = tsdbGetTableByUid(pMeta, pMsg->uid);
|
||||
if (pTable == NULL) {
|
||||
terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
|
||||
return -1;
|
||||
}
|
||||
if (TABLE_TID(pTable) != htonl(pMsg->tid)) {
|
||||
if (TABLE_TID(pTable) != pMsg->tid) {
|
||||
terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
|
||||
return -1;
|
||||
}
|
||||
|
@ -277,10 +306,10 @@ int tsdbUpdateTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (schemaVersion(tsdbGetTableTagSchema(pTable)) < tversion) {
|
||||
if (schemaVersion(tsdbGetTableTagSchema(pTable)) < pMsg->tversion) {
|
||||
tsdbDebug("vgId:%d server tag version %d is older than client tag version %d, try to config", REPO_ID(pRepo),
|
||||
schemaVersion(tsdbGetTableTagSchema(pTable)), tversion);
|
||||
void *msg = (*pRepo->appH.configFunc)(pRepo->config.tsdbId, htonl(pMsg->tid));
|
||||
schemaVersion(tsdbGetTableTagSchema(pTable)), pMsg->tversion);
|
||||
void *msg = (*pRepo->appH.configFunc)(pRepo->config.tsdbId, pMsg->tid);
|
||||
if (msg == NULL) return -1;
|
||||
|
||||
// Deal with error her
|
||||
|
@ -299,19 +328,24 @@ int tsdbUpdateTagValue(TSDB_REPO_T *repo, SUpdateTableTagValMsg *pMsg) {
|
|||
|
||||
STSchema *pTagSchema = tsdbGetTableTagSchema(pTable);
|
||||
|
||||
if (schemaVersion(pTagSchema) > tversion) {
|
||||
if (schemaVersion(pTagSchema) > pMsg->tversion) {
|
||||
tsdbError(
|
||||
"vgId:%d failed to update tag value of table %s since version out of date, client tag version %d server tag "
|
||||
"version %d",
|
||||
REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), tversion, schemaVersion(pTable->tagSchema));
|
||||
REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), pMsg->tversion, schemaVersion(pTable->tagSchema));
|
||||
return TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE;
|
||||
}
|
||||
if (schemaColAt(pTagSchema, DEFAULT_TAG_INDEX_COLUMN)->colId == htons(pMsg->colId)) {
|
||||
if (schemaColAt(pTagSchema, DEFAULT_TAG_INDEX_COLUMN)->colId == pMsg->colId) {
|
||||
tsdbRemoveTableFromIndex(pMeta, pTable);
|
||||
}
|
||||
// TODO: remove table from index if it is the first column of tag
|
||||
tdSetKVRowDataOfCol(&pTable->tagVal, htons(pMsg->colId), htons(pMsg->type), pMsg->data);
|
||||
if (schemaColAt(pTagSchema, DEFAULT_TAG_INDEX_COLUMN)->colId == htons(pMsg->colId)) {
|
||||
|
||||
// TODO: convert the tag schema from client, and then extract the type and bytes from schema according to colId
|
||||
STColumn* res = bsearch(&pMsg->colId, pMsg->data, pMsg->numOfTags, sizeof(STColumn), colIdCompar);
|
||||
assert(res != NULL);
|
||||
|
||||
tdSetKVRowDataOfCol(&pTable->tagVal, pMsg->colId, res->type, pMsg->data + pMsg->schemaLen);
|
||||
if (schemaColAt(pTagSchema, DEFAULT_TAG_INDEX_COLUMN)->colId == pMsg->colId) {
|
||||
tsdbAddTableIntoIndex(pMeta, pTable);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -541,7 +575,7 @@ void tsdbRefTable(STable *pTable) {
|
|||
|
||||
void tsdbUnRefTable(STable *pTable) {
|
||||
int32_t ref = T_REF_DEC(pTable);
|
||||
tsdbDebug("unref table uid:%"PRIu64", tid:%d, refCount:%d", TABLE_UID(pTable), TABLE_TID(pTable), ref);
|
||||
tsdbTrace("unref table uid:%"PRIu64", tid:%d, refCount:%d", TABLE_UID(pTable), TABLE_TID(pTable), ref);
|
||||
|
||||
if (ref == 0) {
|
||||
// tsdbDebug("destory table name:%s uid:%"PRIu64", tid:%d", TABLE_CHAR_NAME(pTable), TABLE_UID(pTable), TABLE_TID(pTable));
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "tcoding.h"
|
||||
#include "tscompression.h"
|
||||
#include "tsdbMain.h"
|
||||
#include "tfile.h"
|
||||
|
||||
#define TSDB_GET_COMPCOL_LEN(nCols) (sizeof(SCompData) + sizeof(SCompCol) * (nCols) + sizeof(TSCKSUM))
|
||||
|
||||
|
|
|
@ -74,9 +74,6 @@ typedef struct STableCheckInfo {
|
|||
SDataCols* pDataCols;
|
||||
int32_t chosen; // indicate which iterator should move forward
|
||||
bool initBuf; // whether to initialize the in-memory skip list iterator or not
|
||||
SMemTable* mem; // in-mem buffer, hold the ref count
|
||||
SMemTable* imem; // imem buffer, hold the ref count to avoid release
|
||||
|
||||
SSkipListIterator* iter; // mem buffer skip list iterator
|
||||
SSkipListIterator* iiter; // imem buffer skip list iterator
|
||||
} STableCheckInfo;
|
||||
|
@ -113,6 +110,8 @@ typedef struct STsdbQueryHandle {
|
|||
SFileGroupIter fileIter;
|
||||
SRWHelper rhelper;
|
||||
STableBlockInfo* pDataBlockInfo;
|
||||
SMemTable* mem; // mem-table
|
||||
SMemTable* imem; // imem-table, acquired from snapshot
|
||||
|
||||
SDataBlockLoadInfo dataBlockLoadInfo; /* record current block load information */
|
||||
SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQuery */
|
||||
|
@ -138,9 +137,6 @@ static void tsdbInitCompBlockLoadInfo(SLoadCompBlockInfo* pCompBlockLoadInfo) {
|
|||
}
|
||||
|
||||
TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STableGroupInfo* groupList, void* qinfo) {
|
||||
// todo 1. filter not exist table
|
||||
// todo 2. add the reference count for each table that is involved in query
|
||||
|
||||
STsdbQueryHandle* pQueryHandle = calloc(1, sizeof(STsdbQueryHandle));
|
||||
pQueryHandle->order = pCond->order;
|
||||
pQueryHandle->window = pCond->twindow;
|
||||
|
@ -154,6 +150,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
|
|||
pQueryHandle->outputCapacity = ((STsdbRepo*)tsdb)->config.maxRowsPerFileBlock;
|
||||
|
||||
tsdbInitReadHelper(&pQueryHandle->rhelper, (STsdbRepo*) tsdb);
|
||||
tsdbTakeMemSnapshot(pQueryHandle->pTsdb, &pQueryHandle->mem, &pQueryHandle->imem);
|
||||
|
||||
size_t sizeOfGroup = taosArrayGetSize(groupList->pGroupList);
|
||||
assert(sizeOfGroup >= 1 && pCond != NULL && pCond->numOfCols > 0);
|
||||
|
@ -252,22 +249,22 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
|
|||
pCheckInfo->initBuf = true;
|
||||
int32_t order = pHandle->order;
|
||||
|
||||
tsdbTakeMemSnapshot(pHandle->pTsdb, &pCheckInfo->mem, &pCheckInfo->imem);
|
||||
// tsdbTakeMemSnapshot(pHandle->pTsdb, &pCheckInfo->mem, &pCheckInfo->imem);
|
||||
|
||||
// no data in buffer, abort
|
||||
if (pCheckInfo->mem == NULL && pCheckInfo->imem == NULL) {
|
||||
if (pHandle->mem == NULL && pHandle->imem == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL);
|
||||
|
||||
if (pCheckInfo->mem && pCheckInfo->mem->tData[pCheckInfo->tableId.tid] != NULL) {
|
||||
pCheckInfo->iter = tSkipListCreateIterFromVal(pCheckInfo->mem->tData[pCheckInfo->tableId.tid]->pData,
|
||||
if (pHandle->mem && pHandle->mem->tData[pCheckInfo->tableId.tid] != NULL) {
|
||||
pCheckInfo->iter = tSkipListCreateIterFromVal(pHandle->mem->tData[pCheckInfo->tableId.tid]->pData,
|
||||
(const char*) &pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
|
||||
}
|
||||
|
||||
if (pCheckInfo->imem && pCheckInfo->imem->tData[pCheckInfo->tableId.tid] != NULL) {
|
||||
pCheckInfo->iiter = tSkipListCreateIterFromVal(pCheckInfo->imem->tData[pCheckInfo->tableId.tid]->pData,
|
||||
if (pHandle->imem && pHandle->imem->tData[pCheckInfo->tableId.tid] != NULL) {
|
||||
pCheckInfo->iiter = tSkipListCreateIterFromVal(pHandle->imem->tData[pCheckInfo->tableId.tid]->pData,
|
||||
(const char*) &pCheckInfo->lastKey, TSDB_DATA_TYPE_TIMESTAMP, order);
|
||||
}
|
||||
|
||||
|
@ -685,6 +682,7 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
|
|||
// query ended in current block
|
||||
if (pQueryHandle->window.ekey < pBlock->keyLast || pCheckInfo->lastKey > pBlock->keyFirst) {
|
||||
if (!doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo)) {
|
||||
taosArrayDestroy(sa);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1504,6 +1502,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
|
|||
pQueryHandle->window = pQueryHandle->cur.win;
|
||||
pQueryHandle->cur.rows = 1;
|
||||
pQueryHandle->type = TSDB_QUERY_TYPE_EXTERNAL;
|
||||
taosArrayDestroy(sa);
|
||||
return true;
|
||||
} else {
|
||||
STsdbQueryHandle* pSecQueryHandle = calloc(1, sizeof(STsdbQueryHandle));
|
||||
|
@ -1518,7 +1517,8 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
|
|||
pSecQueryHandle->outputCapacity = ((STsdbRepo*)pSecQueryHandle->pTsdb)->config.maxRowsPerFileBlock;
|
||||
|
||||
tsdbInitReadHelper(&pSecQueryHandle->rhelper, (STsdbRepo*) pSecQueryHandle->pTsdb);
|
||||
|
||||
tsdbTakeMemSnapshot(pSecQueryHandle->pTsdb, &pSecQueryHandle->mem, &pSecQueryHandle->imem);
|
||||
|
||||
// allocate buffer in order to load data blocks from file
|
||||
int32_t numOfCols = QH_GET_NUM_OF_COLS(pQueryHandle);
|
||||
|
||||
|
@ -2083,26 +2083,15 @@ bool indexedNodeFilterFp(const void* pNode, void* param) {
|
|||
STable* pTable = *(STable**)(SL_GET_NODE_DATA((SSkipListNode*)pNode));
|
||||
|
||||
char* val = NULL;
|
||||
int8_t type = pInfo->sch.type;
|
||||
|
||||
if (pInfo->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
val = (char*) pTable->name;
|
||||
type = TSDB_DATA_TYPE_BINARY;
|
||||
} else {
|
||||
val = tdGetKVRowValOfCol(pTable->tagVal, pInfo->sch.colId);
|
||||
}
|
||||
|
||||
//todo :the val is possible to be null, so check it out carefully
|
||||
int32_t ret = 0;
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||
if (pInfo->optr == TSDB_RELATION_IN) {
|
||||
ret = pInfo->compare(val, pInfo->q);
|
||||
} else {
|
||||
ret = pInfo->compare(val, pInfo->q);
|
||||
}
|
||||
} else {
|
||||
ret = pInfo->compare(val, pInfo->q);
|
||||
}
|
||||
int32_t ret = pInfo->compare(val, pInfo->q);
|
||||
|
||||
switch (pInfo->optr) {
|
||||
case TSDB_RELATION_EQUAL: {
|
||||
|
@ -2271,7 +2260,9 @@ int32_t tsdbGetOneTableGroup(TSDB_REPO_T* tsdb, uint64_t uid, STableGroupInfo* p
|
|||
}
|
||||
|
||||
int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STableGroupInfo* pGroupInfo) {
|
||||
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
|
||||
if (tsdbRLockRepoMeta(tsdb) < 0) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
assert(pTableIdList != NULL);
|
||||
size_t size = taosArrayGetSize(pTableIdList);
|
||||
|
@ -2297,15 +2288,15 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
|
|||
taosArrayPush(group, &pTable);
|
||||
}
|
||||
|
||||
if (tsdbUnlockRepoMeta(tsdb) < 0) goto _error;
|
||||
if (tsdbUnlockRepoMeta(tsdb) < 0) {
|
||||
taosArrayDestroy(group);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
pGroupInfo->numOfTables = i;
|
||||
taosArrayPush(pGroupInfo->pGroupList, &group);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_error:
|
||||
return terrno;
|
||||
}
|
||||
|
||||
void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) {
|
||||
|
@ -2319,9 +2310,6 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) {
|
|||
STableCheckInfo* pTableCheckInfo = taosArrayGet(pQueryHandle->pTableCheckInfo, i);
|
||||
tSkipListDestroyIter(pTableCheckInfo->iter);
|
||||
|
||||
tsdbUnRefMemTable(pQueryHandle->pTsdb, pTableCheckInfo->mem);
|
||||
tsdbUnRefMemTable(pQueryHandle->pTsdb, pTableCheckInfo->imem);
|
||||
|
||||
if (pTableCheckInfo->pDataCols != NULL) {
|
||||
tfree(pTableCheckInfo->pDataCols->buf);
|
||||
}
|
||||
|
@ -2341,9 +2329,12 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) {
|
|||
taosArrayDestroy(pQueryHandle->pColumns);
|
||||
tfree(pQueryHandle->pDataBlockInfo);
|
||||
tfree(pQueryHandle->statis);
|
||||
|
||||
|
||||
// todo check error
|
||||
tsdbUnRefMemTable(pQueryHandle->pTsdb, pQueryHandle->mem);
|
||||
tsdbUnRefMemTable(pQueryHandle->pTsdb, pQueryHandle->imem);
|
||||
|
||||
tsdbDestroyHelper(&pQueryHandle->rhelper);
|
||||
|
||||
tfree(pQueryHandle);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ extern "C" {
|
|||
#include "tref.h"
|
||||
#include "hash.h"
|
||||
|
||||
typedef void (*__cache_freeres_fn_t)(void*);
|
||||
|
||||
typedef struct SCacheStatis {
|
||||
int64_t missCount;
|
||||
int64_t hitCount;
|
||||
|
@ -34,14 +36,15 @@ typedef struct SCacheStatis {
|
|||
|
||||
typedef struct SCacheDataNode {
|
||||
uint64_t addedTime; // the added time when this element is added or updated into cache
|
||||
uint64_t expiredTime; // expiredTime expiredTime when this element should be remove from cache
|
||||
uint64_t lifespan; // expiredTime expiredTime when this element should be remove from cache
|
||||
uint64_t signature;
|
||||
uint32_t size; // allocated size for current SCacheDataNode
|
||||
uint16_t keySize: 15;
|
||||
bool inTrashCan: 1;// denote if it is in trash or not
|
||||
T_REF_DECLARE()
|
||||
char *key;
|
||||
char data[];
|
||||
uint16_t keySize: 15; // max key size: 32kb
|
||||
bool inTrashCan: 1;// denote if it is in trash or not
|
||||
int32_t extendFactor; // number of life span extend
|
||||
char *key;
|
||||
char data[];
|
||||
} SCacheDataNode;
|
||||
|
||||
typedef struct STrashElem {
|
||||
|
@ -62,29 +65,33 @@ typedef struct {
|
|||
int64_t totalSize; // total allocated buffer in this hash table, SCacheObj is not included.
|
||||
int64_t refreshTime;
|
||||
STrashElem * pTrash;
|
||||
void * tmrCtrl;
|
||||
void * pTimer;
|
||||
char* name;
|
||||
// void * tmrCtrl;
|
||||
// void * pTimer;
|
||||
SCacheStatis statistics;
|
||||
SHashObj * pHashTable;
|
||||
_hash_free_fn_t freeFp;
|
||||
__cache_freeres_fn_t freeFp;
|
||||
uint32_t numOfElemsInTrash; // number of element in trash
|
||||
uint8_t deleting; // set the deleting flag to stop refreshing ASAP.
|
||||
pthread_t refreshWorker;
|
||||
|
||||
bool extendLifespan; // auto extend life span when one item is accessed.
|
||||
#if defined(LINUX)
|
||||
pthread_rwlock_t lock;
|
||||
#else
|
||||
pthread_mutex_t lock;
|
||||
pthread_mutex_t lock;
|
||||
#endif
|
||||
} SCacheObj;
|
||||
|
||||
/**
|
||||
* initialize the cache object
|
||||
* @param refreshTime refresh operation interval time, the maximum survival time when one element is expired and
|
||||
* not referenced by other objects
|
||||
* @param keyType key type
|
||||
* @param refreshTimeInSeconds refresh operation interval time, the maximum survival time when one element is expired
|
||||
* and not referenced by other objects
|
||||
* @param extendLifespan auto extend lifespan, if accessed
|
||||
* @param fn free resource callback function
|
||||
* @return
|
||||
*/
|
||||
SCacheObj *taosCacheInit(int64_t refreshTimeInSeconds);
|
||||
SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool extendLifespan, __cache_freeres_fn_t fn, const char *cacheName);
|
||||
|
||||
/**
|
||||
* initialize the cache object and set the free object callback function
|
||||
|
@ -92,7 +99,7 @@ SCacheObj *taosCacheInit(int64_t refreshTimeInSeconds);
|
|||
* @param freeCb
|
||||
* @return
|
||||
*/
|
||||
SCacheObj *taosCacheInitWithCb(int64_t refreshTimeInSeconds, void (*freeCb)(void *data));
|
||||
SCacheObj *taosCacheInitWithCb(int32_t keyType, int64_t refreshTimeInSeconds, bool extendLifespan, __cache_freeres_fn_t fn, const char *cacheName);
|
||||
|
||||
/**
|
||||
* add data into cache
|
||||
|
@ -104,7 +111,7 @@ SCacheObj *taosCacheInitWithCb(int64_t refreshTimeInSeconds, void (*freeCb)(void
|
|||
* @param keepTime survival time in second
|
||||
* @return cached element
|
||||
*/
|
||||
void *taosCachePut(SCacheObj *pCacheObj, const char *key, const void *pData, size_t dataSize, int keepTimeInSeconds);
|
||||
void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const void *pData, size_t dataSize, int keepTimeInSeconds);
|
||||
|
||||
/**
|
||||
* get data from cache
|
||||
|
@ -112,22 +119,23 @@ void *taosCachePut(SCacheObj *pCacheObj, const char *key, const void *pData, siz
|
|||
* @param key key
|
||||
* @return cached data or NULL
|
||||
*/
|
||||
void *taosCacheAcquireByName(SCacheObj *pCacheObj, const char *key);
|
||||
void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen);
|
||||
|
||||
/**
|
||||
* update the expire time of data in cache
|
||||
* @param pCacheObj cache object
|
||||
* @param key key
|
||||
* @param keyLen keyLen
|
||||
* @param expireTime new expire time of data
|
||||
* @return
|
||||
*/
|
||||
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, const char *key, uint64_t expireTime);
|
||||
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, void *key, size_t keyLen, uint64_t expireTime);
|
||||
|
||||
/**
|
||||
* Add one reference count for the exist data, and assign this data for a new owner.
|
||||
* The new owner needs to invoke the taosCacheRelease when it does not need this data anymore.
|
||||
* This procedure is a faster version of taosCacheAcquireByName function, which avoids the sideeffect of the problem of
|
||||
* the data is moved to trash, and taosCacheAcquireByName will fail to retrieve it again.
|
||||
* This procedure is a faster version of taosCacheAcquireByKey function, which avoids the sideeffect of the problem of
|
||||
* the data is moved to trash, and taosCacheAcquireByKey will fail to retrieve it again.
|
||||
*
|
||||
* @param handle
|
||||
* @param data
|
||||
|
@ -148,16 +156,16 @@ void *taosCacheTransfer(SCacheObj *pCacheObj, void **data);
|
|||
* if it is referenced by other object, it will be remain in cache
|
||||
* @param handle cache object
|
||||
* @param data not the key, actually referenced data
|
||||
* @param _remove force model, reduce the ref count and move the data into
|
||||
* pTrash
|
||||
* @param _remove force model, reduce the ref count and move the data into pTrash
|
||||
*/
|
||||
void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove);
|
||||
|
||||
/**
|
||||
* move all data node into trash, clear node in trash can if it is not referenced by any clients
|
||||
* @param handle
|
||||
* @param _remove remove the data or not if refcount is greater than 0
|
||||
*/
|
||||
void taosCacheEmpty(SCacheObj *pCacheObj);
|
||||
void taosCacheEmpty(SCacheObj *pCacheObj, bool _remove);
|
||||
|
||||
/**
|
||||
* release all allocated memory and destroy the cache object.
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TFILE_H
|
||||
#define TDENGINE_TFILE_H
|
||||
|
||||
#ifdef TAOS_RANDOM_FILE_FAIL
|
||||
|
||||
ssize_t taos_tread(int fd, void *buf, size_t count);
|
||||
ssize_t taos_twrite(int fd, void *buf, size_t count);
|
||||
off_t taos_lseek(int fd, off_t offset, int whence);
|
||||
|
||||
#define tread(fd, buf, count) taos_tread(fd, buf, count)
|
||||
#define twrite(fd, buf, count) taos_twrite(fd, buf, count)
|
||||
#define lseek(fd, offset, whence) taos_lseek(fd, offset, whence)
|
||||
|
||||
#endif // TAOS_RANDOM_FILE_FAIL
|
||||
|
||||
#endif // TDENGINE_TFILE_H
|
|
@ -118,8 +118,9 @@ static FORCE_INLINE void taosCacheReleaseNode(SCacheObj *pCacheObj, SCacheDataNo
|
|||
|
||||
int32_t size = pNode->size;
|
||||
taosHashRemove(pCacheObj->pHashTable, pNode->key, pNode->keySize);
|
||||
|
||||
uDebug("key:%s, is removed from cache, total:%" PRId64 " size:%d bytes", pNode->key, pCacheObj->totalSize, size);
|
||||
|
||||
uDebug("cache:%s, key:%p, %p is destroyed from cache, totalNum:%d totalSize:%" PRId64 "bytes size:%dbytes",
|
||||
pCacheObj->name, pNode->key, pNode->data, (int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, size);
|
||||
if (pCacheObj->freeFp) pCacheObj->freeFp(pNode->data);
|
||||
free(pNode);
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ static SCacheDataNode *taosUpdateCacheImpl(SCacheObj *pCacheObj, SCacheDataNode
|
|||
|
||||
// update the timestamp information for updated key/value
|
||||
pNewNode->addedTime = taosGetTimestampMs();
|
||||
pNewNode->expiredTime = pNewNode->addedTime + duration;
|
||||
pNewNode->lifespan = duration;
|
||||
|
||||
T_REF_INC(pNewNode);
|
||||
|
||||
|
@ -224,8 +225,8 @@ static void doCleanupDataCache(SCacheObj *pCacheObj);
|
|||
*/
|
||||
static void* taosCacheRefresh(void *handle);
|
||||
|
||||
SCacheObj *taosCacheInitWithCb(int64_t refreshTime, void (*freeCb)(void *data)) {
|
||||
if (refreshTime <= 0) {
|
||||
SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool extendLifespan, __cache_freeres_fn_t fn, const char* cacheName) {
|
||||
if (refreshTimeInSeconds <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -235,7 +236,8 @@ SCacheObj *taosCacheInitWithCb(int64_t refreshTime, void (*freeCb)(void *data))
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pCacheObj->pHashTable = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false);
|
||||
pCacheObj->pHashTable = taosHashInit(128, taosGetDefaultHashFunction(keyType), false);
|
||||
pCacheObj->name = strdup(cacheName);
|
||||
if (pCacheObj->pHashTable == NULL) {
|
||||
free(pCacheObj);
|
||||
uError("failed to allocate memory, reason:%s", strerror(errno));
|
||||
|
@ -243,10 +245,9 @@ SCacheObj *taosCacheInitWithCb(int64_t refreshTime, void (*freeCb)(void *data))
|
|||
}
|
||||
|
||||
// set free cache node callback function for hash table
|
||||
// taosHashSetFreecb(pCacheObj->pHashTable, taosFreeNode);
|
||||
|
||||
pCacheObj->freeFp = freeCb;
|
||||
pCacheObj->refreshTime = refreshTime * 1000;
|
||||
pCacheObj->freeFp = fn;
|
||||
pCacheObj->refreshTime = refreshTimeInSeconds * 1000;
|
||||
pCacheObj->extendLifespan = extendLifespan;
|
||||
|
||||
if (__cache_lock_init(pCacheObj) != 0) {
|
||||
taosHashCleanup(pCacheObj->pHashTable);
|
||||
|
@ -256,7 +257,7 @@ SCacheObj *taosCacheInitWithCb(int64_t refreshTime, void (*freeCb)(void *data))
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pthread_attr_t thattr;
|
||||
pthread_attr_t thattr = {{0}};
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
|
@ -266,19 +267,13 @@ SCacheObj *taosCacheInitWithCb(int64_t refreshTime, void (*freeCb)(void *data))
|
|||
return pCacheObj;
|
||||
}
|
||||
|
||||
SCacheObj *taosCacheInit(int64_t refreshTime) {
|
||||
return taosCacheInitWithCb(refreshTime, NULL);
|
||||
}
|
||||
|
||||
void *taosCachePut(SCacheObj *pCacheObj, const char *key, const void *pData, size_t dataSize, int duration) {
|
||||
void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const void *pData, size_t dataSize, int duration) {
|
||||
SCacheDataNode *pNode;
|
||||
|
||||
if (pCacheObj == NULL || pCacheObj->pHashTable == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t keyLen = strlen(key);
|
||||
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
SCacheDataNode **pt = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen);
|
||||
SCacheDataNode * pOld = (pt != NULL) ? (*pt) : NULL;
|
||||
|
@ -287,75 +282,86 @@ void *taosCachePut(SCacheObj *pCacheObj, const char *key, const void *pData, siz
|
|||
pNode = taosAddToCacheImpl(pCacheObj, key, keyLen, pData, dataSize, duration * 1000L);
|
||||
if (NULL != pNode) {
|
||||
pCacheObj->totalSize += pNode->size;
|
||||
|
||||
uDebug("key:%s, %p added into cache, added:%" PRIu64 ", expire:%" PRIu64 ", total:%" PRId64 ", size:%" PRId64 " bytes",
|
||||
key, pNode, pNode->addedTime, pNode->expiredTime, pCacheObj->totalSize, dataSize);
|
||||
|
||||
uDebug("cache:%s, key:%p, %p added into cache, added:%" PRIu64 ", expire:%" PRIu64 ", totalNum:%d totalSize:%" PRId64
|
||||
"bytes size:%" PRId64 "bytes",
|
||||
pCacheObj->name, key, pNode->data, pNode->addedTime, (pNode->lifespan * pNode->extendFactor + pNode->addedTime),
|
||||
(int32_t)taosHashGetSize(pCacheObj->pHashTable), pCacheObj->totalSize, dataSize);
|
||||
} else {
|
||||
uError("key:%s, failed to added into cache, out of memory", key);
|
||||
uError("cache:%s, key:%p, failed to added into cache, out of memory", pCacheObj->name, key);
|
||||
}
|
||||
} else { // old data exists, update the node
|
||||
pNode = taosUpdateCacheImpl(pCacheObj, pOld, key, keyLen, pData, dataSize, duration * 1000L);
|
||||
uDebug("key:%s, %p exist in cache, updated", key, pNode);
|
||||
uDebug("cache:%s, key:%p, %p exist in cache, updated", pCacheObj->name, key, pNode->data);
|
||||
}
|
||||
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
|
||||
return (pNode != NULL) ? pNode->data : NULL;
|
||||
}
|
||||
|
||||
void *taosCacheAcquireByName(SCacheObj *pCacheObj, const char *key) {
|
||||
void *taosCacheAcquireByKey(SCacheObj *pCacheObj, const void *key, size_t keyLen) {
|
||||
if (pCacheObj == NULL || taosHashGetSize(pCacheObj->pHashTable) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t keyLen = (uint32_t)strlen(key);
|
||||
|
||||
|
||||
__cache_rd_lock(pCacheObj);
|
||||
|
||||
SCacheDataNode **ptNode = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen);
|
||||
|
||||
int32_t ref = 0;
|
||||
if (ptNode != NULL) {
|
||||
T_REF_INC(*ptNode);
|
||||
ref = T_REF_INC(*ptNode);
|
||||
|
||||
// if the remained life span is less then the (*ptNode)->lifeSpan, add up one lifespan
|
||||
if (pCacheObj->extendLifespan) {
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
if ((now - (*ptNode)->addedTime) < (*ptNode)->lifespan * (*ptNode)->extendFactor) {
|
||||
(*ptNode)->extendFactor += 1;
|
||||
uDebug("key:%p extend life time to %"PRId64, key, (*ptNode)->lifespan * (*ptNode)->extendFactor + (*ptNode)->addedTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
if (ptNode != NULL) {
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.hitCount, 1);
|
||||
uDebug("key:%s, is retrieved from cache, %p refcnt:%d", key, (*ptNode), T_REF_VAL_GET(*ptNode));
|
||||
uDebug("cache:%s, key:%p, %p is retrieved from cache, refcnt:%d", pCacheObj->name, key, (*ptNode)->data, ref);
|
||||
} else {
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.missCount, 1);
|
||||
uDebug("key:%s, not in cache, retrieved failed", key);
|
||||
uDebug("cache:%s, key:%p, not in cache, retrieved failed", pCacheObj->name, key);
|
||||
}
|
||||
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.totalAccess, 1);
|
||||
return (ptNode != NULL) ? (*ptNode)->data : NULL;
|
||||
}
|
||||
|
||||
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, const char *key, uint64_t expireTime) {
|
||||
void* taosCacheUpdateExpireTimeByName(SCacheObj *pCacheObj, void *key, size_t keyLen, uint64_t expireTime) {
|
||||
if (pCacheObj == NULL || taosHashGetSize(pCacheObj->pHashTable) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t keyLen = (uint32_t)strlen(key);
|
||||
|
||||
|
||||
__cache_rd_lock(pCacheObj);
|
||||
|
||||
SCacheDataNode **ptNode = (SCacheDataNode **)taosHashGet(pCacheObj->pHashTable, key, keyLen);
|
||||
if (ptNode != NULL) {
|
||||
T_REF_INC(*ptNode);
|
||||
(*ptNode)->expiredTime = expireTime;
|
||||
(*ptNode)->extendFactor += 1;
|
||||
// (*ptNode)->lifespan = expireTime;
|
||||
}
|
||||
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
|
||||
if (ptNode != NULL) {
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.hitCount, 1);
|
||||
uDebug("key:%s, expireTime is updated in cache, %p refcnt:%d", key, (*ptNode), T_REF_VAL_GET(*ptNode));
|
||||
uDebug("cache:%s, key:%p, %p expireTime is updated in cache, refcnt:%d", pCacheObj->name, key,
|
||||
(*ptNode)->data, T_REF_VAL_GET(*ptNode));
|
||||
} else {
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.missCount, 1);
|
||||
uDebug("key:%s, not in cache, retrieved failed", key);
|
||||
uDebug("cache:%s, key:%p, not in cache, retrieved failed", pCacheObj->name, key);
|
||||
}
|
||||
|
||||
|
||||
atomic_add_fetch_32(&pCacheObj->statistics.totalAccess, 1);
|
||||
return (ptNode != NULL) ? (*ptNode)->data : NULL;
|
||||
}
|
||||
|
@ -370,10 +376,21 @@ void *taosCacheAcquireByData(SCacheObj *pCacheObj, void *data) {
|
|||
uError("key: %p the data from cache is invalid", ptNode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int32_t ref = T_REF_INC(ptNode);
|
||||
uDebug("%p acquired by data in cache, refcnt:%d", ptNode, ref)
|
||||
|
||||
uDebug("cache:%s, data: %p acquired by data in cache, refcnt:%d", pCacheObj->name, ptNode->data, ref);
|
||||
|
||||
// if the remained life span is less then the (*ptNode)->lifeSpan, add up one lifespan
|
||||
if (pCacheObj->extendLifespan) {
|
||||
int64_t now = taosGetTimestampMs();
|
||||
|
||||
if ((now - ptNode->addedTime) < ptNode->lifespan * ptNode->extendFactor) {
|
||||
ptNode->extendFactor += 1;
|
||||
uDebug("cache:%s, %p extend life time to %" PRId64, pCacheObj->name, ptNode->data,
|
||||
ptNode->lifespan * ptNode->extendFactor + ptNode->addedTime);
|
||||
}
|
||||
}
|
||||
|
||||
// the data if referenced by at least one object, so the reference count must be greater than the value of 2.
|
||||
assert(ref >= 2);
|
||||
return data;
|
||||
|
@ -408,26 +425,32 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
|
|||
size_t offset = offsetof(SCacheDataNode, data);
|
||||
|
||||
SCacheDataNode *pNode = (SCacheDataNode *)((char *)(*data) - offset);
|
||||
|
||||
if (pNode->signature != (uint64_t)pNode) {
|
||||
uError("%p release invalid cache data", pNode);
|
||||
uError("%p, release invalid cache data", pNode);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
*data = NULL;
|
||||
int32_t ref = T_REF_DEC(pNode);
|
||||
uDebug("key:%s, is released, %p refcnt:%d", pNode->key, pNode, ref);
|
||||
|
||||
if (_remove) {
|
||||
int16_t ref = T_REF_DEC(pNode);
|
||||
uDebug("cache:%s, key:%p, %p is released, refcnt:%d", pCacheObj->name, pNode->key, pNode->data, ref);
|
||||
|
||||
if (_remove && (!pNode->inTrashCan)) {
|
||||
__cache_wr_lock(pCacheObj);
|
||||
// pNode may be released immediately by other thread after the reference count of pNode is set to 0,
|
||||
// So we need to lock it in the first place.
|
||||
taosCacheMoveToTrash(pCacheObj, pNode);
|
||||
|
||||
if (T_REF_VAL_GET(pNode) == 0) {
|
||||
// remove directly, if not referenced by other users
|
||||
taosCacheReleaseNode(pCacheObj, pNode);
|
||||
} else {
|
||||
// pNode may be released immediately by other thread after the reference count of pNode is set to 0,
|
||||
// So we need to lock it in the first place.
|
||||
taosCacheMoveToTrash(pCacheObj, pNode);
|
||||
}
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
}
|
||||
}
|
||||
|
||||
void taosCacheEmpty(SCacheObj *pCacheObj) {
|
||||
void taosCacheEmpty(SCacheObj *pCacheObj, bool _remove) {
|
||||
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable);
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
|
@ -437,12 +460,16 @@ void taosCacheEmpty(SCacheObj *pCacheObj) {
|
|||
}
|
||||
|
||||
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter);
|
||||
taosCacheMoveToTrash(pCacheObj, pNode);
|
||||
if (T_REF_VAL_GET(pNode) == 0 || _remove) {
|
||||
taosCacheReleaseNode(pCacheObj, pNode);
|
||||
} else {
|
||||
taosCacheMoveToTrash(pCacheObj, pNode);
|
||||
}
|
||||
}
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
taosHashDestroyIter(pIter);
|
||||
taosTrashCanEmpty(pCacheObj, false);
|
||||
taosTrashCanEmpty(pCacheObj, _remove);
|
||||
}
|
||||
|
||||
void taosCacheCleanup(SCacheObj *pCacheObj) {
|
||||
|
@ -453,6 +480,7 @@ void taosCacheCleanup(SCacheObj *pCacheObj) {
|
|||
pCacheObj->deleting = 1;
|
||||
pthread_join(pCacheObj->refreshWorker, NULL);
|
||||
|
||||
uInfo("cache:%s will be cleaned up", pCacheObj->name);
|
||||
doCleanupDataCache(pCacheObj);
|
||||
}
|
||||
|
||||
|
@ -473,11 +501,11 @@ SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const char *
|
|||
|
||||
memcpy(pNewNode->key, key, keyLen);
|
||||
|
||||
pNewNode->addedTime = (uint64_t)taosGetTimestampMs();
|
||||
pNewNode->expiredTime = pNewNode->addedTime + duration;
|
||||
|
||||
pNewNode->signature = (uint64_t)pNewNode;
|
||||
pNewNode->size = (uint32_t)totalSize;
|
||||
pNewNode->addedTime = (uint64_t)taosGetTimestampMs();
|
||||
pNewNode->lifespan = duration;
|
||||
pNewNode->extendFactor = 1;
|
||||
pNewNode->signature = (uint64_t)pNewNode;
|
||||
pNewNode->size = (uint32_t)totalSize;
|
||||
|
||||
return pNewNode;
|
||||
}
|
||||
|
@ -501,7 +529,7 @@ void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
|
|||
pNode->inTrashCan = true;
|
||||
pCacheObj->numOfElemsInTrash++;
|
||||
|
||||
uDebug("key:%s, %p move to trash, numOfElem in trash:%d", pNode->key, pNode, pCacheObj->numOfElemsInTrash);
|
||||
uDebug("key:%p, %p move to trash, numOfElem in trash:%d", pNode->key, pNode->data, pCacheObj->numOfElemsInTrash);
|
||||
}
|
||||
|
||||
void taosRemoveFromTrashCan(SCacheObj *pCacheObj, STrashElem *pElem) {
|
||||
|
@ -522,7 +550,10 @@ void taosRemoveFromTrashCan(SCacheObj *pCacheObj, STrashElem *pElem) {
|
|||
}
|
||||
|
||||
pElem->pData->signature = 0;
|
||||
if (pCacheObj->freeFp) pCacheObj->freeFp(pElem->pData->data);
|
||||
if (pCacheObj->freeFp) {
|
||||
pCacheObj->freeFp(pElem->pData->data);
|
||||
}
|
||||
|
||||
free(pElem->pData);
|
||||
free(pElem);
|
||||
}
|
||||
|
@ -549,7 +580,7 @@ void taosTrashCanEmpty(SCacheObj *pCacheObj, bool force) {
|
|||
}
|
||||
|
||||
if (force || (T_REF_VAL_GET(pElem->pData) == 0)) {
|
||||
uDebug("key:%s, %p removed from trash. numOfElem in trash:%d", pElem->pData->key, pElem->pData,
|
||||
uDebug("key:%p, %p removed from trash. numOfElem in trash:%d", pElem->pData->key, pElem->pData->data,
|
||||
pCacheObj->numOfElemsInTrash - 1);
|
||||
STrashElem *p = pElem;
|
||||
|
||||
|
@ -569,21 +600,25 @@ void doCleanupDataCache(SCacheObj *pCacheObj) {
|
|||
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable);
|
||||
while (taosHashIterNext(pIter)) {
|
||||
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter);
|
||||
// if (pNode->expiredTime <= expiredTime && T_REF_VAL_GET(pNode) <= 0) {
|
||||
if (T_REF_VAL_GET(pNode) <= 0) {
|
||||
|
||||
int32_t c = T_REF_VAL_GET(pNode);
|
||||
if (c <= 0) {
|
||||
taosCacheReleaseNode(pCacheObj, pNode);
|
||||
} else {
|
||||
uDebug("key:%s, will not remove from cache, refcnt:%d", pNode->key, T_REF_VAL_GET(pNode));
|
||||
uDebug("cache:%s key:%p, %p will not remove from cache, refcnt:%d", pCacheObj->name, pNode->key,
|
||||
pNode->data, T_REF_VAL_GET(pNode));
|
||||
}
|
||||
}
|
||||
taosHashDestroyIter(pIter);
|
||||
|
||||
taosHashCleanup(pCacheObj->pHashTable);
|
||||
// todo memory leak if there are object with refcount greater than 0 in hash table?
|
||||
taosHashCleanup(pCacheObj->pHashTable);
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
taosTrashCanEmpty(pCacheObj, true);
|
||||
__cache_lock_destroy(pCacheObj);
|
||||
|
||||
|
||||
tfree(pCacheObj->name);
|
||||
memset(pCacheObj, 0, sizeof(SCacheObj));
|
||||
free(pCacheObj);
|
||||
}
|
||||
|
@ -613,27 +648,32 @@ void* taosCacheRefresh(void *handle) {
|
|||
|
||||
// reset the count value
|
||||
count = 0;
|
||||
size_t num = taosHashGetSize(pCacheObj->pHashTable);
|
||||
if (num == 0) {
|
||||
size_t elemInHash = taosHashGetSize(pCacheObj->pHashTable);
|
||||
if (elemInHash + pCacheObj->numOfElemsInTrash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t expiredTime = taosGetTimestampMs();
|
||||
pCacheObj->statistics.refreshCount++;
|
||||
|
||||
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable);
|
||||
// refresh data in hash table
|
||||
if (elemInHash > 0) {
|
||||
int64_t expiredTime = taosGetTimestampMs();
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
while (taosHashIterNext(pIter)) {
|
||||
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter);
|
||||
if (pNode->expiredTime <= expiredTime && T_REF_VAL_GET(pNode) <= 0) {
|
||||
taosCacheReleaseNode(pCacheObj, pNode);
|
||||
SHashMutableIterator *pIter = taosHashCreateIter(pCacheObj->pHashTable);
|
||||
|
||||
__cache_wr_lock(pCacheObj);
|
||||
while (taosHashIterNext(pIter)) {
|
||||
SCacheDataNode *pNode = *(SCacheDataNode **)taosHashIterGet(pIter);
|
||||
if ((pNode->addedTime + pNode->lifespan * pNode->extendFactor) <= expiredTime && T_REF_VAL_GET(pNode) <= 0) {
|
||||
taosCacheReleaseNode(pCacheObj, pNode);
|
||||
}
|
||||
}
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
taosHashDestroyIter(pIter);
|
||||
}
|
||||
|
||||
__cache_unlock(pCacheObj);
|
||||
|
||||
taosHashDestroyIter(pIter);
|
||||
taosTrashCanEmpty(pCacheObj, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#define RANDOM_FILE_FAIL_FACTOR 5
|
||||
|
||||
ssize_t taos_tread(int fd, void *buf, size_t count)
|
||||
{
|
||||
#ifdef TAOS_RANDOM_FILE_FAIL
|
||||
if (rand() % RANDOM_FILE_FAIL_FACTOR == 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return tread(fd, buf, count);
|
||||
}
|
||||
|
||||
ssize_t taos_twrite(int fd, void *buf, size_t count)
|
||||
{
|
||||
#ifdef TAOS_RANDOM_FILE_FAIL
|
||||
if (rand() % RANDOM_FILE_FAIL_FACTOR == 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return twrite(fd, buf, count);
|
||||
}
|
||||
|
||||
off_t taos_lseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
#ifdef TAOS_RANDOM_FILE_FAIL
|
||||
if (rand() % RANDOM_FILE_FAIL_FACTOR == 0) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return lseek(fd, offset, whence);
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
#include "tcoding.h"
|
||||
#include "tkvstore.h"
|
||||
#include "tulog.h"
|
||||
#include "tfile.h"
|
||||
|
||||
#define TD_KVSTORE_HEADER_SIZE 512
|
||||
#define TD_KVSTORE_MAJOR_VERSION 1
|
||||
|
@ -581,4 +582,4 @@ _err:
|
|||
taosHashDestroyIter(pIter);
|
||||
tfree(buf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ static void* realloc_detect_leak(void* ptr, size_t size, const char* file, uint3
|
|||
return malloc_detect_leak(size, file, line);
|
||||
}
|
||||
|
||||
SMemBlock* blk = ((char*)ptr) - sizeof(SMemBlock);
|
||||
SMemBlock* blk = (SMemBlock *)((char*)ptr) - sizeof(SMemBlock);
|
||||
if (blk->magic != MEMBLK_MAGIC) {
|
||||
if (fpAllocLog != NULL) {
|
||||
fprintf(fpAllocLog, "%s:%d: memory is allocated by default allocator.\n", file, line);
|
||||
|
|
|
@ -374,3 +374,34 @@ int32_t getTimestampInUsFromStr(char* token, int32_t tokenlen, int64_t* ts) {
|
|||
|
||||
return getTimestampInUsFromStrImpl(timestamp, token[tokenlen - 1], ts);
|
||||
}
|
||||
|
||||
// internal function, when program is paused in debugger,
|
||||
// one can call this function from debugger to print a
|
||||
// timestamp as human readable string, for example (gdb):
|
||||
// p fmtts(1593769722)
|
||||
// outputs:
|
||||
// 2020-07-03 17:48:42
|
||||
// and the parameter can also be a variable.
|
||||
const char* fmtts(int64_t ts) {
|
||||
static char buf[32];
|
||||
|
||||
time_t tt;
|
||||
if (ts > -62135625943 && ts < 32503651200) {
|
||||
tt = ts;
|
||||
} else if (ts > -62135625943000 && ts < 32503651200000) {
|
||||
tt = ts / 1000;
|
||||
} else {
|
||||
tt = ts / 1000000;
|
||||
}
|
||||
|
||||
struct tm* ptm = localtime(&tt);
|
||||
size_t pos = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ptm);
|
||||
|
||||
if (ts <= -62135625943000 || ts >= 32503651200000) {
|
||||
sprintf(buf + pos, ".%06d", (int)(ts % 1000000));
|
||||
} else if (ts <= -62135625943 || ts >= 32503651200) {
|
||||
sprintf(buf + pos, ".%03d", (int)(ts % 1000));
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
|
@ -801,6 +801,11 @@ int tmkdir(const char *path, mode_t mode) {
|
|||
}
|
||||
|
||||
void taosMvDir(char* destDir, char *srcDir) {
|
||||
if (0 == tsEnableVnodeBak) {
|
||||
uInfo("vnode backup not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
char shellCmd[1024+1] = {0};
|
||||
|
||||
//(void)snprintf(shellCmd, 1024, "cp -rf %s %s", srcDir, destDir);
|
||||
|
|
|
@ -19,12 +19,12 @@ int32_t tsMaxMeterConnections = 200;
|
|||
// test cache
|
||||
TEST(testCase, client_cache_test) {
|
||||
const int32_t REFRESH_TIME_IN_SEC = 2;
|
||||
SCacheObj* tscCacheHandle = taosCacheInit(REFRESH_TIME_IN_SEC);
|
||||
SCacheObj* tscCacheHandle = taosCacheInit(TSDB_DATA_TYPE_BINARY, REFRESH_TIME_IN_SEC, 0, NULL, "test");
|
||||
|
||||
const char* key1 = "test1";
|
||||
char data1[] = "test11";
|
||||
|
||||
char* cachedObj = (char*) taosCachePut(tscCacheHandle, key1, data1, strlen(data1)+1, 1);
|
||||
char* cachedObj = (char*) taosCachePut(tscCacheHandle, key1, strlen(key1), data1, strlen(data1)+1, 1);
|
||||
sleep(REFRESH_TIME_IN_SEC+1);
|
||||
|
||||
printf("obj is still valid: %s\n", cachedObj);
|
||||
|
@ -33,7 +33,7 @@ TEST(testCase, client_cache_test) {
|
|||
taosCacheRelease(tscCacheHandle, (void**) &cachedObj, false);
|
||||
|
||||
/* the object is cleared by cache clean operation */
|
||||
cachedObj = (char*) taosCachePut(tscCacheHandle, key1, data2, strlen(data2)+1, 20);
|
||||
cachedObj = (char*) taosCachePut(tscCacheHandle, key1, strlen(key1), data2, strlen(data2)+1, 20);
|
||||
printf("after updated: %s\n", cachedObj);
|
||||
|
||||
printf("start to remove data from cache\n");
|
||||
|
@ -43,32 +43,32 @@ TEST(testCase, client_cache_test) {
|
|||
const char* key3 = "test2";
|
||||
const char* data3 = "kkkkkkk";
|
||||
|
||||
char* cachedObj2 = (char*) taosCachePut(tscCacheHandle, key3, data3, strlen(data3) + 1, 1);
|
||||
char* cachedObj2 = (char*) taosCachePut(tscCacheHandle, key3, strlen(key3), data3, strlen(data3) + 1, 1);
|
||||
printf("%s\n", cachedObj2);
|
||||
|
||||
taosCacheRelease(tscCacheHandle, (void**) &cachedObj2, false);
|
||||
|
||||
sleep(3);
|
||||
char* d = (char*) taosCacheAcquireByName(tscCacheHandle, key3);
|
||||
char* d = (char*) taosCacheAcquireByKey(tscCacheHandle, key3, strlen(key3));
|
||||
// assert(d == NULL);
|
||||
|
||||
char key5[] = "test5";
|
||||
char data5[] = "data5kkkkk";
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, data5, strlen(data5) + 1, 20);
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, strlen(key5), data5, strlen(data5) + 1, 20);
|
||||
|
||||
const char* data6= "new Data after updated";
|
||||
taosCacheRelease(tscCacheHandle, (void**) &cachedObj2, false);
|
||||
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, data6, strlen(data6) + 1, 20);
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, strlen(key5), data6, strlen(data6) + 1, 20);
|
||||
printf("%s\n", cachedObj2);
|
||||
|
||||
taosCacheRelease(tscCacheHandle, (void**) &cachedObj2, true);
|
||||
|
||||
const char* data7 = "add call update procedure";
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, data7, strlen(data7) + 1, 20);
|
||||
cachedObj2 = (char*) taosCachePut(tscCacheHandle, key5, strlen(key5), data7, strlen(data7) + 1, 20);
|
||||
printf("%s\n=======================================\n\n", cachedObj2);
|
||||
|
||||
char* cc = (char*) taosCacheAcquireByName(tscCacheHandle, key5);
|
||||
char* cc = (char*) taosCacheAcquireByKey(tscCacheHandle, key5, strlen(key5));
|
||||
|
||||
taosCacheRelease(tscCacheHandle, (void**) &cachedObj2, true);
|
||||
taosCacheRelease(tscCacheHandle, (void**) &cc, false);
|
||||
|
@ -76,7 +76,7 @@ TEST(testCase, client_cache_test) {
|
|||
const char* data8 = "ttft";
|
||||
const char* key6 = "key6";
|
||||
|
||||
char* ft = (char*) taosCachePut(tscCacheHandle, key6, data8, strlen(data8), 20);
|
||||
char* ft = (char*) taosCachePut(tscCacheHandle, key6, strlen(key6), data8, strlen(data8), 20);
|
||||
taosCacheRelease(tscCacheHandle, (void**) &ft, false);
|
||||
|
||||
/**
|
||||
|
@ -85,7 +85,7 @@ TEST(testCase, client_cache_test) {
|
|||
uint64_t startTime = taosGetTimestampUs();
|
||||
printf("Cache Performance Test\nstart time:%" PRIu64 "\n", startTime);
|
||||
for(int32_t i=0; i<1000; ++i) {
|
||||
char* dd = (char*) taosCacheAcquireByName(tscCacheHandle, key6);
|
||||
char* dd = (char*) taosCacheAcquireByKey(tscCacheHandle, key6, strlen(key6));
|
||||
if (dd != NULL) {
|
||||
// printf("get the data\n");
|
||||
} else {
|
||||
|
@ -105,7 +105,7 @@ TEST(testCase, client_cache_test) {
|
|||
|
||||
TEST(testCase, cache_resize_test) {
|
||||
const int32_t REFRESH_TIME_IN_SEC = 2;
|
||||
auto* pCache = taosCacheInit(REFRESH_TIME_IN_SEC);
|
||||
auto* pCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, REFRESH_TIME_IN_SEC, false, NULL, "test");
|
||||
|
||||
char key[256] = {0};
|
||||
char data[1024] = "abcdefghijk";
|
||||
|
@ -116,7 +116,7 @@ TEST(testCase, cache_resize_test) {
|
|||
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
int32_t len = sprintf(key, "abc_%7d", i);
|
||||
taosCachePut(pCache, key, data, len, 3600);
|
||||
taosCachePut(pCache, key, strlen(key), data, len, 3600);
|
||||
}
|
||||
uint64_t endTime = taosGetTimestampUs();
|
||||
|
||||
|
@ -125,7 +125,7 @@ TEST(testCase, cache_resize_test) {
|
|||
startTime = taosGetTimestampUs();
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
int32_t len = sprintf(key, "abc_%7d", i);
|
||||
void* k = taosCacheAcquireByName(pCache, key);
|
||||
void* k = taosCacheAcquireByKey(pCache, key, len);
|
||||
assert(k != 0);
|
||||
}
|
||||
endTime = taosGetTimestampUs();
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct {
|
|||
STsdbCfg tsdbCfg;
|
||||
SSyncCfg syncCfg;
|
||||
SWalCfg walCfg;
|
||||
void *qMgmt;
|
||||
char *rootDir;
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
} SVnodeObj;
|
||||
|
|
|
@ -15,19 +15,22 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#include "tcache.h"
|
||||
#include "cJSON.h"
|
||||
#include "dnode.h"
|
||||
#include "hash.h"
|
||||
#include "taoserror.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tutil.h"
|
||||
#include "tglobal.h"
|
||||
#include "trpc.h"
|
||||
#include "tsdb.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimer.h"
|
||||
#include "cJSON.h"
|
||||
#include "tglobal.h"
|
||||
#include "dnode.h"
|
||||
#include "tutil.h"
|
||||
#include "vnode.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "query.h"
|
||||
|
||||
#define TSDB_VNODE_VERSION_CONTENT_LEN 31
|
||||
|
||||
|
@ -65,6 +68,12 @@ static void vnodeInit() {
|
|||
}
|
||||
}
|
||||
|
||||
void vnodeCleanupResources() {
|
||||
taosHashCleanup(tsDnodeVnodesHash);
|
||||
vnodeModuleInit = PTHREAD_ONCE_INIT;
|
||||
tsDnodeVnodesHash = NULL;
|
||||
}
|
||||
|
||||
int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
|
||||
int32_t code;
|
||||
pthread_once(&vnodeModuleInit, vnodeInit);
|
||||
|
@ -279,6 +288,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
|||
if (pVnode->role == TAOS_SYNC_ROLE_MASTER)
|
||||
cqStart(pVnode->cq);
|
||||
|
||||
pVnode->qMgmt = qOpenQueryMgmt(pVnode->vgId);
|
||||
pVnode->events = NULL;
|
||||
pVnode->status = TAOS_VN_STATUS_READY;
|
||||
vDebug("vgId:%d, vnode is opened in %s, pVnode:%p", pVnode->vgId, rootDir, pVnode);
|
||||
|
@ -289,7 +299,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
|||
}
|
||||
|
||||
int32_t vnodeStartStream(int32_t vnode) {
|
||||
SVnodeObj* pVnode = vnodeAccquireVnode(vnode);
|
||||
SVnodeObj* pVnode = vnodeAcquireVnode(vnode);
|
||||
if (pVnode != NULL) {
|
||||
tsdbStartStream(pVnode->tsdb);
|
||||
vnodeRelease(pVnode);
|
||||
|
@ -317,10 +327,13 @@ void vnodeRelease(void *pVnodeRaw) {
|
|||
assert(refCount >= 0);
|
||||
|
||||
if (refCount > 0) {
|
||||
vTrace("vgId:%d, release vnode, refCount:%d", vgId, refCount);
|
||||
vDebug("vgId:%d, release vnode, refCount:%d", vgId, refCount);
|
||||
return;
|
||||
}
|
||||
|
||||
qCleanupQueryMgmt(pVnode->qMgmt);
|
||||
pVnode->qMgmt = NULL;
|
||||
|
||||
if (pVnode->tsdb)
|
||||
tsdbCloseRepo(pVnode->tsdb, 1);
|
||||
pVnode->tsdb = NULL;
|
||||
|
@ -355,12 +368,6 @@ void vnodeRelease(void *pVnodeRaw) {
|
|||
|
||||
int32_t count = atomic_sub_fetch_32(&tsOpennedVnodes, 1);
|
||||
vDebug("vgId:%d, vnode is released, vnodes:%d", vgId, count);
|
||||
|
||||
if (count <= 0) {
|
||||
taosHashCleanup(tsDnodeVnodesHash);
|
||||
vnodeModuleInit = PTHREAD_ONCE_INIT;
|
||||
tsDnodeVnodesHash = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *vnodeGetVnode(int32_t vgId) {
|
||||
|
@ -376,22 +383,31 @@ void *vnodeGetVnode(int32_t vgId) {
|
|||
return *ppVnode;
|
||||
}
|
||||
|
||||
void *vnodeAccquireVnode(int32_t vgId) {
|
||||
void *vnodeAcquireVnode(int32_t vgId) {
|
||||
SVnodeObj *pVnode = vnodeGetVnode(vgId);
|
||||
if (pVnode == NULL) return pVnode;
|
||||
|
||||
atomic_add_fetch_32(&pVnode->refCount, 1);
|
||||
vTrace("vgId:%d, get vnode, refCount:%d", pVnode->vgId, pVnode->refCount);
|
||||
vDebug("vgId:%d, get vnode, refCount:%d", pVnode->vgId, pVnode->refCount);
|
||||
|
||||
return pVnode;
|
||||
}
|
||||
|
||||
void *vnodeAcquireRqueue(void *param) {
|
||||
SVnodeObj *pVnode = param;
|
||||
if (pVnode == NULL) return NULL;
|
||||
|
||||
atomic_add_fetch_32(&pVnode->refCount, 1);
|
||||
vDebug("vgId:%d, get vnode rqueue, refCount:%d", pVnode->vgId, pVnode->refCount);
|
||||
return ((SVnodeObj *)pVnode)->rqueue;
|
||||
}
|
||||
|
||||
void *vnodeGetRqueue(void *pVnode) {
|
||||
return ((SVnodeObj *)pVnode)->rqueue;
|
||||
}
|
||||
|
||||
void *vnodeGetWqueue(int32_t vgId) {
|
||||
SVnodeObj *pVnode = vnodeAccquireVnode(vgId);
|
||||
SVnodeObj *pVnode = vnodeAcquireVnode(vgId);
|
||||
if (pVnode == NULL) return NULL;
|
||||
return pVnode->wqueue;
|
||||
}
|
||||
|
@ -417,6 +433,28 @@ static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SDMStatusMsg *pStatus) {
|
|||
pLoad->replica = pVnode->syncCfg.replica;
|
||||
}
|
||||
|
||||
int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
|
||||
if (tsDnodeVnodesHash == NULL) return TSDB_CODE_SUCCESS;
|
||||
|
||||
SHashMutableIterator *pIter = taosHashCreateIter(tsDnodeVnodesHash);
|
||||
while (taosHashIterNext(pIter)) {
|
||||
SVnodeObj **pVnode = taosHashIterGet(pIter);
|
||||
if (pVnode == NULL) continue;
|
||||
if (*pVnode == NULL) continue;
|
||||
|
||||
(*numOfVnodes)++;
|
||||
if (*numOfVnodes >= TSDB_MAX_VNODES) {
|
||||
vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
|
||||
continue;
|
||||
} else {
|
||||
vnodeList[*numOfVnodes - 1] = (*pVnode)->vgId;
|
||||
}
|
||||
}
|
||||
|
||||
taosHashDestroyIter(pIter);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void vnodeBuildStatusMsg(void *param) {
|
||||
SDMStatusMsg *pStatus = param;
|
||||
SHashMutableIterator *pIter = taosHashCreateIter(tsDnodeVnodesHash);
|
||||
|
@ -435,7 +473,7 @@ void vnodeBuildStatusMsg(void *param) {
|
|||
void vnodeSetAccess(SDMVgroupAccess *pAccess, int32_t numOfVnodes) {
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
pAccess[i].vgId = htonl(pAccess[i].vgId);
|
||||
SVnodeObj *pVnode = vnodeAccquireVnode(pAccess[i].vgId);
|
||||
SVnodeObj *pVnode = vnodeAcquireVnode(pAccess[i].vgId);
|
||||
if (pVnode != NULL) {
|
||||
pVnode->accessState = pAccess[i].accessState;
|
||||
if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
|
||||
|
@ -459,6 +497,7 @@ static void vnodeCleanUp(SVnodeObj *pVnode) {
|
|||
vTrace("vgId:%d, vnode will cleanup, refCount:%d", pVnode->vgId, pVnode->refCount);
|
||||
|
||||
// release local resources only after cutting off outside connections
|
||||
qSetQueryMgmtClosed(pVnode->qMgmt);
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
||||
|
@ -848,12 +887,12 @@ static int32_t vnodeReadVersion(SVnodeObj *pVnode) {
|
|||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
cJSON *version = cJSON_GetObjectItem(root, "version");
|
||||
if (!version || version->type != cJSON_Number) {
|
||||
cJSON *ver = cJSON_GetObjectItem(root, "version");
|
||||
if (!ver || ver->type != cJSON_Number) {
|
||||
vError("vgId:%d, failed to read vnode version, version not found", pVnode->vgId);
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
pVnode->version = version->valueint;
|
||||
pVnode->version = ver->valueint;
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
vInfo("vgId:%d, read vnode version successfully, version:%" PRId64, pVnode->vgId, pVnode->version);
|
||||
|
|
|
@ -14,21 +14,23 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <dnode.h>
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
|
||||
#include "tglobal.h"
|
||||
#include "taoserror.h"
|
||||
#include "tqueue.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
#include "query.h"
|
||||
#include "trpc.h"
|
||||
#include "tsdb.h"
|
||||
#include "twal.h"
|
||||
#include "tdataformat.h"
|
||||
#include "vnode.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "query.h"
|
||||
|
||||
static int32_t (*vnodeProcessReadMsgFp[TSDB_MSG_TYPE_MAX])(SVnodeObj *pVnode, SReadMsg *pReadMsg);
|
||||
static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg);
|
||||
static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg);
|
||||
static int32_t vnodeNotifyCurrentQhandle(void* handle, void* qhandle, int32_t vgId);
|
||||
|
||||
void vnodeInitReadFp(void) {
|
||||
vnodeProcessReadMsgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessQueryMsg;
|
||||
|
@ -58,19 +60,6 @@ int32_t vnodeProcessRead(void *param, SReadMsg *pReadMsg) {
|
|||
return (*vnodeProcessReadMsgFp[msgType])(pVnode, pReadMsg);
|
||||
}
|
||||
|
||||
// notify connection(handle) that current qhandle is created, if current connection from
|
||||
// client is broken, the query needs to be killed immediately.
|
||||
static int32_t vnodeNotifyCurrentQhandle(void* handle, void* qhandle, int32_t vgId) {
|
||||
SRetrieveTableMsg* killQueryMsg = rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
killQueryMsg->qhandle = htobe64((uint64_t) qhandle);
|
||||
killQueryMsg->free = htons(1);
|
||||
killQueryMsg->header.vgId = htonl(vgId);
|
||||
killQueryMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg));
|
||||
|
||||
vDebug("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
||||
return rpcReportProgress(handle, (char*) killQueryMsg, sizeof(SRetrieveTableMsg));
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
||||
void * pCont = pReadMsg->pCont;
|
||||
int32_t contLen = pReadMsg->contLen;
|
||||
|
@ -85,59 +74,82 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
|||
killQueryMsg->free = htons(killQueryMsg->free);
|
||||
killQueryMsg->qhandle = htobe64(killQueryMsg->qhandle);
|
||||
|
||||
vWarn("QInfo:%p connection %p broken, kill query", (void*)killQueryMsg->qhandle, pReadMsg->rpcMsg.handle);
|
||||
void* handle = NULL;
|
||||
if ((void**) killQueryMsg->qhandle != NULL) {
|
||||
handle = *(void**) killQueryMsg->qhandle;
|
||||
}
|
||||
|
||||
vWarn("QInfo:%p connection %p broken, kill query", handle, pReadMsg->rpcMsg.handle);
|
||||
assert(pReadMsg->rpcMsg.contLen > 0 && killQueryMsg->free == 1);
|
||||
|
||||
// this message arrived here by means of the query message, so release the vnode is necessary
|
||||
qKillQuery((qinfo_t) killQueryMsg->qhandle, vnodeRelease, pVnode);
|
||||
vnodeRelease(pVnode);
|
||||
void** qhandle = qAcquireQInfo(pVnode->qMgmt, (void**) killQueryMsg->qhandle);
|
||||
if (qhandle == NULL || *qhandle == NULL) {
|
||||
vWarn("QInfo:%p invalid qhandle, no matched query handle, conn:%p", (void*) killQueryMsg->qhandle, pReadMsg->rpcMsg.handle);
|
||||
} else {
|
||||
assert(qhandle == (void**) killQueryMsg->qhandle);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &qhandle, true);
|
||||
}
|
||||
|
||||
return TSDB_CODE_TSC_QUERY_CANCELLED; // todo change the error code
|
||||
return TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
qinfo_t pQInfo = NULL;
|
||||
void** handle = NULL;
|
||||
|
||||
if (contLen != 0) {
|
||||
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, &pQInfo);
|
||||
code = qCreateQueryInfo(pVnode->tsdb, pVnode->vgId, pQueryTableMsg, pVnode, NULL, &pQInfo);
|
||||
|
||||
SQueryTableRsp *pRsp = (SQueryTableRsp *) rpcMallocCont(sizeof(SQueryTableRsp));
|
||||
pRsp->qhandle = htobe64((uint64_t) (pQInfo));
|
||||
pRsp->code = code;
|
||||
pRsp->code = code;
|
||||
pRsp->qhandle = 0;
|
||||
|
||||
pRet->len = sizeof(SQueryTableRsp);
|
||||
pRet->rsp = pRsp;
|
||||
int32_t vgId = pVnode->vgId;
|
||||
|
||||
// current connect is broken
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
if (vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, pQInfo, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
||||
vError("vgId:%d, QInfo:%p, dnode query discarded since link is broken, %p", pVnode->vgId, pQInfo,
|
||||
pReadMsg->rpcMsg.handle);
|
||||
pRsp->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||
// add lock here
|
||||
handle = qRegisterQInfo(pVnode->qMgmt, pQInfo);
|
||||
if (handle == NULL) { // failed to register qhandle
|
||||
pRsp->code = TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
|
||||
// NOTE: there two refcount, needs to kill twice, todo refactor
|
||||
qKillQuery(pQInfo, vnodeRelease, pVnode);
|
||||
qKillQuery(pQInfo, vnodeRelease, pVnode);
|
||||
|
||||
return pRsp->code;
|
||||
qKillQuery(pQInfo);
|
||||
qKillQuery(pQInfo);
|
||||
} else {
|
||||
assert(*handle == pQInfo);
|
||||
pRsp->qhandle = htobe64((uint64_t) (handle));
|
||||
}
|
||||
|
||||
vTrace("vgId:%d, QInfo:%p, dnode query msg disposed", pVnode->vgId, pQInfo);
|
||||
if (handle != NULL && vnodeNotifyCurrentQhandle(pReadMsg->rpcMsg.handle, handle, pVnode->vgId) != TSDB_CODE_SUCCESS) {
|
||||
vError("vgId:%d, QInfo:%p, query discarded since link is broken, %p", pVnode->vgId, pQInfo, pReadMsg->rpcMsg.handle);
|
||||
pRsp->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||
|
||||
// NOTE: there two refcount, needs to kill twice
|
||||
// query has not been put into qhandle pool, kill it directly.
|
||||
qKillQuery(pQInfo);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
||||
return pRsp->code;
|
||||
}
|
||||
} else {
|
||||
assert(pQInfo == NULL);
|
||||
vnodeRelease(pVnode);
|
||||
}
|
||||
|
||||
vDebug("vgId:%d, QInfo:%p, dnode query msg disposed", pVnode->vgId, pQInfo);
|
||||
vDebug("vgId:%d, QInfo:%p, dnode query msg disposed", vgId, pQInfo);
|
||||
} else {
|
||||
assert(pCont != NULL);
|
||||
pQInfo = pCont;
|
||||
pQInfo = *(void**)(pCont);
|
||||
handle = pCont;
|
||||
code = TSDB_CODE_VND_ACTION_IN_PROGRESS;
|
||||
|
||||
vDebug("vgId:%d, QInfo:%p, dnode query msg in progress", pVnode->vgId, pQInfo);
|
||||
}
|
||||
|
||||
if (pQInfo != NULL) {
|
||||
qTableQuery(pQInfo, vnodeRelease, pVnode); // do execute query
|
||||
qTableQuery(pQInfo); // do execute query
|
||||
assert(handle != NULL);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, false);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -148,46 +160,69 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
|
|||
SRspRet *pRet = &pReadMsg->rspRet;
|
||||
|
||||
SRetrieveTableMsg *pRetrieve = pCont;
|
||||
void *pQInfo = (void*) htobe64(pRetrieve->qhandle);
|
||||
void **pQInfo = (void*) htobe64(pRetrieve->qhandle);
|
||||
pRetrieve->free = htons(pRetrieve->free);
|
||||
|
||||
vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed", pVnode->vgId, *pQInfo);
|
||||
|
||||
memset(pRet, 0, sizeof(SRspRet));
|
||||
int32_t ret = 0;
|
||||
|
||||
void** handle = qAcquireQInfo(pVnode->qMgmt, pQInfo);
|
||||
if (handle == NULL || handle != pQInfo) {
|
||||
ret = TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
}
|
||||
|
||||
if (pRetrieve->free == 1) {
|
||||
vDebug("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pQInfo);
|
||||
int32_t ret = qKillQuery(pQInfo, vnodeRelease, pVnode);
|
||||
if (ret == TSDB_CODE_SUCCESS) {
|
||||
vDebug("vgId:%d, QInfo:%p, retrieve msg received to kill query and free qhandle", pVnode->vgId, pQInfo);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
||||
|
||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||
pRet->len = sizeof(SRetrieveTableRsp);
|
||||
|
||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||
SRetrieveTableRsp* pRsp = pRet->rsp;
|
||||
pRsp->numOfRows = 0;
|
||||
pRsp->completed = true;
|
||||
pRsp->useconds = 0;
|
||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||
pRet->len = sizeof(SRetrieveTableRsp);
|
||||
|
||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||
SRetrieveTableRsp* pRsp = pRet->rsp;
|
||||
pRsp->numOfRows = 0;
|
||||
pRsp->completed = true;
|
||||
pRsp->useconds = 0;
|
||||
} else { // todo handle error
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
vDebug("vgId:%d, QInfo:%p, retrieve msg is received", pVnode->vgId, pQInfo);
|
||||
|
||||
int32_t code = qRetrieveQueryResultInfo(pQInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
int32_t code = qRetrieveQueryResultInfo(*pQInfo);
|
||||
if (code != TSDB_CODE_SUCCESS || ret != TSDB_CODE_SUCCESS) {
|
||||
//TODO
|
||||
pRet->rsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp));
|
||||
memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp));
|
||||
|
||||
} else {
|
||||
// todo check code and handle error in build result set
|
||||
code = qDumpRetrieveResult(pQInfo, (SRetrieveTableRsp **)&pRet->rsp, &pRet->len);
|
||||
code = qDumpRetrieveResult(*pQInfo, (SRetrieveTableRsp **)&pRet->rsp, &pRet->len);
|
||||
|
||||
if (qHasMoreResultsToRetrieve(pQInfo)) {
|
||||
pRet->qhandle = pQInfo;
|
||||
code = TSDB_CODE_VND_ACTION_NEED_REPROCESSED;
|
||||
if (qHasMoreResultsToRetrieve(*handle)) {
|
||||
dnodePutItemIntoReadQueue(pVnode, handle);
|
||||
pRet->qhandle = handle;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
} else { // no further execution invoked, release the ref to vnode
|
||||
qDestroyQueryInfo(pQInfo, vnodeRelease, pVnode);
|
||||
qReleaseQInfo(pVnode->qMgmt, (void**) &handle, true);
|
||||
}
|
||||
}
|
||||
|
||||
vDebug("vgId:%d, QInfo:%p, retrieve msg is disposed", pVnode->vgId, pQInfo);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
// notify connection(handle) that current qhandle is created, if current connection from
|
||||
// client is broken, the query needs to be killed immediately.
|
||||
int32_t vnodeNotifyCurrentQhandle(void* handle, void* qhandle, int32_t vgId) {
|
||||
SRetrieveTableMsg* killQueryMsg = rpcMallocCont(sizeof(SRetrieveTableMsg));
|
||||
killQueryMsg->qhandle = htobe64((uint64_t) qhandle);
|
||||
killQueryMsg->free = htons(1);
|
||||
killQueryMsg->header.vgId = htonl(vgId);
|
||||
killQueryMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg));
|
||||
|
||||
vDebug("QInfo:%p register qhandle to connect:%p", qhandle, handle);
|
||||
return rpcReportProgress(handle, (char*) killQueryMsg, sizeof(SRetrieveTableMsg));
|
||||
}
|
|
@ -94,7 +94,7 @@
|
|||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>18.0</version>
|
||||
<version>24.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
|
|
@ -32,6 +32,7 @@ class TDTestCase:
|
|||
tdDnodes.stop(1)
|
||||
tdDnodes.deploy(1)
|
||||
tdDnodes.start(1)
|
||||
tdLog.sleep(5)
|
||||
|
||||
tdSql.execute('reset query cache')
|
||||
tdSql.execute('drop database if exists db')
|
||||
|
@ -61,6 +62,7 @@ class TDTestCase:
|
|||
tdDnodes.stop(1)
|
||||
tdLog.sleep(5)
|
||||
tdDnodes.start(1)
|
||||
tdLog.sleep(5)
|
||||
|
||||
tdLog.info("================= step5")
|
||||
tdLog.info("import 10 data totally repetitive")
|
||||
|
|
|
@ -22,7 +22,7 @@ class MetadataQuery:
|
|||
def initConnection(self):
|
||||
self.tables = 100000
|
||||
self.records = 10
|
||||
self.numOfTherads = 10
|
||||
self.numOfTherads = 20
|
||||
self.ts = 1537146000000
|
||||
self.host = "127.0.0.1"
|
||||
self.user = "root"
|
||||
|
@ -55,10 +55,10 @@ class MetadataQuery:
|
|||
|
||||
def createTablesAndInsertData(self, threadID):
|
||||
cursor = self.connectDB()
|
||||
cursor.execute("use test")
|
||||
base = threadID * self.tables
|
||||
cursor.execute("use test")
|
||||
|
||||
tablesPerThread = int (self.tables / self.numOfTherads)
|
||||
base = threadID * tablesPerThread
|
||||
for i in range(tablesPerThread):
|
||||
cursor.execute(
|
||||
'''create table t%d using meters tags(
|
||||
|
@ -75,12 +75,11 @@ class MetadataQuery:
|
|||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100))
|
||||
for j in range(self.records):
|
||||
cursor.execute(
|
||||
"insert into t%d values(%d, %d)" %
|
||||
(base + i + 1, self.ts + j, j))
|
||||
cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
cursor.execute(
|
||||
"insert into t%d values(%d, 1) (%d, 2) (%d, 3) (%d, 4) (%d, 5)" %
|
||||
(base + i + 1, self.ts + 1, self.ts + 2, self.ts + 3, self.ts + 4, self.ts + 5))
|
||||
cursor.close()
|
||||
|
||||
def queryData(self, query):
|
||||
cursor = self.connectDB()
|
||||
|
@ -108,12 +107,17 @@ if __name__ == '__main__':
|
|||
print(
|
||||
"================= Create %d tables and insert %d records into each table =================" %
|
||||
(t.tables, t.records))
|
||||
startTime = datetime.now()
|
||||
startTime = datetime.now()
|
||||
threads = []
|
||||
for i in range(t.numOfTherads):
|
||||
thread = threading.Thread(
|
||||
target=t.createTablesAndInsertData, args=(i,))
|
||||
thread.start()
|
||||
thread.join()
|
||||
threads.append(thread)
|
||||
|
||||
for th in threads:
|
||||
th.join()
|
||||
|
||||
endTime = datetime.now()
|
||||
diff = (endTime - startTime).seconds
|
||||
print(
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
###################################################################
|
||||
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is proprietary and confidential to TAOS Technologies.
|
||||
# No part of this file may be reproduced, stored, transmitted,
|
||||
# disclosed or used in any form or by any means other than as
|
||||
# expressly provided by the written permission from Jianhui Tao
|
||||
#
|
||||
###################################################################
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import taos
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime
|
||||
import numpy as np
|
||||
|
||||
class MyThread(threading.Thread):
|
||||
|
||||
def __init__(self, func, args=()):
|
||||
super(MyThread, self).__init__()
|
||||
self.func = func
|
||||
self.args = args
|
||||
|
||||
def run(self):
|
||||
self.result = self.func(*self.args)
|
||||
|
||||
def get_result(self):
|
||||
try:
|
||||
return self.result # 如果子线程不使用join方法,此处可能会报没有self.result的错误
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
class MetadataQuery:
|
||||
def initConnection(self):
|
||||
self.tables = 100
|
||||
self.records = 10
|
||||
self.numOfTherads =5
|
||||
self.ts = 1537146000000
|
||||
self.host = "127.0.0.1"
|
||||
self.user = "root"
|
||||
self.password = "taosdata"
|
||||
self.config = "/etc/taos"
|
||||
self.conn = taos.connect( self.host, self.user, self.password, self.config)
|
||||
def connectDB(self):
|
||||
return self.conn.cursor()
|
||||
|
||||
def createStable(self):
|
||||
print("================= Create stable meters =================")
|
||||
cursor = self.connectDB()
|
||||
cursor.execute("drop database if exists test")
|
||||
cursor.execute("create database test")
|
||||
cursor.execute("use test")
|
||||
cursor.execute('''create table if not exists meters (ts timestamp, speed int) tags(
|
||||
tgcol1 tinyint, tgcol2 smallint, tgcol3 int, tgcol4 bigint, tgcol5 float, tgcol6 double, tgcol7 bool, tgcol8 binary(20), tgcol9 nchar(20),
|
||||
tgcol10 tinyint, tgcol11 smallint, tgcol12 int, tgcol13 bigint, tgcol14 float, tgcol15 double, tgcol16 bool, tgcol17 binary(20), tgcol18 nchar(20),
|
||||
tgcol19 tinyint, tgcol20 smallint, tgcol21 int, tgcol22 bigint, tgcol23 float, tgcol24 double, tgcol25 bool, tgcol26 binary(20), tgcol27 nchar(20),
|
||||
tgcol28 tinyint, tgcol29 smallint, tgcol30 int, tgcol31 bigint, tgcol32 float, tgcol33 double, tgcol34 bool, tgcol35 binary(20), tgcol36 nchar(20),
|
||||
tgcol37 tinyint, tgcol38 smallint, tgcol39 int, tgcol40 bigint, tgcol41 float, tgcol42 double, tgcol43 bool, tgcol44 binary(20), tgcol45 nchar(20),
|
||||
tgcol46 tinyint, tgcol47 smallint, tgcol48 int, tgcol49 bigint, tgcol50 float, tgcol51 double, tgcol52 bool, tgcol53 binary(20), tgcol54 nchar(20))''')
|
||||
cursor.close()
|
||||
|
||||
def createTablesAndInsertData(self, threadID):
|
||||
cursor = self.connectDB()
|
||||
cursor.execute("use test")
|
||||
base = threadID * self.tables
|
||||
|
||||
tablesPerThread = int (self.tables / self.numOfTherads)
|
||||
for i in range(tablesPerThread):
|
||||
cursor.execute(
|
||||
'''create table t%d using meters tags(
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d',
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d',
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d',
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d',
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d',
|
||||
%d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d')''' %
|
||||
(base + i + 1,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100,
|
||||
(base + i) %100, (base + i) %10000, (base + i) %1000000, (base + i) %100000000, (base + i) %100 * 1.1, (base + i) %100 * 2.3, (base + i) %2, (base + i) %100, (base + i) %100))
|
||||
for j in range(self.records):
|
||||
cursor.execute(
|
||||
"insert into t%d values(%d, %d)" %
|
||||
(base + i + 1, self.ts + j, j))
|
||||
cursor.close()
|
||||
def queryWithTagId(self, threadId, tagId, queryNum):
|
||||
print("---------thread%d start-----------"%threadId)
|
||||
query = '''select tgcol1, tgcol2, tgcol3, tgcol4, tgcol5, tgcol6, tgcol7, tgcol8, tgcol9,
|
||||
tgcol10, tgcol11, tgcol12, tgcol13, tgcol14, tgcol15, tgcol16, tgcol17, tgcol18,
|
||||
tgcol19, tgcol20, tgcol21, tgcol22, tgcol23, tgcol24, tgcol25, tgcol26, tgcol27,
|
||||
tgcol28, tgcol29, tgcol30, tgcol31, tgcol32, tgcol33, tgcol34, tgcol35, tgcol36,
|
||||
tgcol37, tgcol38, tgcol39, tgcol40, tgcol41, tgcol42, tgcol43, tgcol44, tgcol45,
|
||||
tgcol46, tgcol47, tgcol48, tgcol49, tgcol50, tgcol51, tgcol52, tgcol53, tgcol54
|
||||
from meters where tgcol{id} > {condition}'''
|
||||
latancy = []
|
||||
cursor = self.connectDB()
|
||||
cursor.execute("use test")
|
||||
for i in range(queryNum):
|
||||
startTime = time.time()
|
||||
cursor.execute(query.format(id = tagId, condition = i))
|
||||
cursor.fetchall()
|
||||
latancy.append((time.time() - startTime))
|
||||
print("---------thread%d end-----------"%threadId)
|
||||
return latancy
|
||||
def queryData(self, query):
|
||||
cursor = self.connectDB()
|
||||
cursor.execute("use test")
|
||||
|
||||
print("================= query tag data =================")
|
||||
startTime = datetime.now()
|
||||
cursor.execute(query)
|
||||
cursor.fetchall()
|
||||
endTime = datetime.now()
|
||||
print(
|
||||
"Query time for the above query is %d seconds" %
|
||||
(endTime - startTime).seconds)
|
||||
|
||||
cursor.close()
|
||||
#self.conn.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
t = MetadataQuery()
|
||||
t.initConnection()
|
||||
|
||||
latancys = []
|
||||
threads = []
|
||||
tagId = 1
|
||||
queryNum = 1000
|
||||
for i in range(t.numOfTherads):
|
||||
thread = MyThread(t.queryWithTagId, args = (i, tagId, queryNum))
|
||||
threads.append(thread)
|
||||
thread.start()
|
||||
for i in range(t.numOfTherads):
|
||||
threads[i].join()
|
||||
latancys.extend(threads[i].get_result())
|
||||
print("Total query: %d"%(queryNum * t.numOfTherads))
|
||||
print("statistic(s): mean= %f, P50 = %f, P75 = %f, P95 = %f, P99 = %f"
|
||||
%(sum(latancys)/(queryNum * t.numOfTherads), np.percentile(latancys, 50), np.percentile(latancys, 75), np.percentile(latancys, 95), np.percentile(latancys, 99)))
|
||||
|
|
@ -137,6 +137,7 @@ python3 ./test.py -f query/filterFloatAndDouble.py
|
|||
python3 ./test.py -f query/filterOtherTypes.py
|
||||
python3 ./test.py -f query/queryError.py
|
||||
python3 ./test.py -f query/querySort.py
|
||||
python3 ./test.py -f query/queryJoin.py
|
||||
|
||||
#stream
|
||||
python3 ./test.py -f stream/stream1.py
|
||||
|
|
|
@ -81,7 +81,7 @@ if __name__ == "__main__":
|
|||
else:
|
||||
toBeKilled = "valgrind.bin"
|
||||
|
||||
killCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -HUP " % toBeKilled
|
||||
killCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs kill -HUP > /dev/null 2>&1" % toBeKilled
|
||||
|
||||
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
|
||||
processID = subprocess.check_output(psCmd, shell=True)
|
||||
|
@ -91,8 +91,17 @@ if __name__ == "__main__":
|
|||
time.sleep(1)
|
||||
processID = subprocess.check_output(psCmd, shell=True)
|
||||
|
||||
fuserCmd = "fuser -k -n tcp 6030"
|
||||
os.system(fuserCmd)
|
||||
for port in range(6030, 6041):
|
||||
usePortPID = "lsof -i tcp:%d | grep LISTEn | awk '{print $2}'" % port
|
||||
processID = subprocess.check_output(usePortPID, shell=True)
|
||||
|
||||
if processID:
|
||||
killCmd = "kill -9 %s" % processID
|
||||
os.system(killCmd)
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
tdLog.info('stop All dnodes')
|
||||
sys.exit(0)
|
||||
|
|
|
@ -251,11 +251,16 @@ class TDDnode:
|
|||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -INT %s" % processID
|
||||
killCmd = "kill -INT %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -INT" % (self.index))
|
||||
|
@ -272,11 +277,16 @@ class TDDnode:
|
|||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s" % processID
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
for port in range(6030, 6041):
|
||||
fuserCmd = "fuser -k -n tcp %d" % port
|
||||
os.system(fuserCmd)
|
||||
if self.valgrind:
|
||||
time.sleep(2)
|
||||
|
||||
self.running = 0
|
||||
tdLog.debug("dnode:%d is stopped by kill -KILL" % (self.index))
|
||||
|
@ -325,7 +335,7 @@ class TDDnodes:
|
|||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s" % processID
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
|
@ -334,7 +344,7 @@ class TDDnodes:
|
|||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s" % processID
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
|
@ -440,7 +450,7 @@ class TDDnodes:
|
|||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s" % processID
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
|
@ -449,7 +459,7 @@ class TDDnodes:
|
|||
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
|
||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||
while(processID):
|
||||
killCmd = "kill -KILL %s" % processID
|
||||
killCmd = "kill -KILL %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
|
|
|
@ -54,43 +54,43 @@ print =============== step2 - login
|
|||
|
||||
system_content curl 127.0.0.1:6020/grafana/
|
||||
print 1-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/grafana/xx
|
||||
print 2-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/grafana/login/xx/xx/
|
||||
print 3-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"mnode invalid user"}@ then
|
||||
if $system_content != @{"status":"error","code":849,"desc":"mnode invalid user"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/grafana/root/1/123/1/1/3
|
||||
print 4-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'show databases' 127.0.0.1:6020/grafana/login/1/root/1/
|
||||
print 5-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"mnode invalid user"}@ then
|
||||
if $system_content != @{"status":"error","code":849,"desc":"mnode invalid user"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cudGFvc2RhdGEuY29tIiwicGFzcyI6InRhb3NkYXRhIiwic3ViIjoicm9vdCJ9.xPv3b5odlR7YF8G_QWASjIRbMtA5v4ItToJ35fFgi' -d 'show databases' 127.0.0.1:6020/grafana/root/1/login
|
||||
print 6-> $system_content
|
||||
if $system_content != @{"status":"error","code":1010,"desc":"invalid type of Authorization"}@ then
|
||||
if $system_content != @{"status":"error","code":5010,"desc":"invalid type of Authorization"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cudGFvc2RhdGEuY29tIiwicGFzcyI6InRhb3NkYXRhIiwic3ViIjoicm9vdCJ9.xPv3b5odlR7YF8G_QWASjIRbMtA5v4ItToJ35fFgi' -d 'show databases' 127.0.0.1:6020/grafana/root/1/login
|
||||
print 7-> $system_content
|
||||
if $system_content != @{"status":"error","code":1010,"desc":"invalid type of Authorization"}@ then
|
||||
if $system_content != @{"status":"error","code":5010,"desc":"invalid type of Authorization"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ endi
|
|||
|
||||
system_content curl 127.0.0.1:6020/rest/login/u2/aabcd_1234
|
||||
print curl 127.0.0.1:6020/rest/login/u2/abcd_1234 -----> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -14,57 +14,57 @@ print =============== step1 - login
|
|||
|
||||
system_content curl 127.0.0.1:6020/rest/
|
||||
print 1-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/rest/xx
|
||||
print 2-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/rest/login
|
||||
print 3-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#4
|
||||
system_content curl 127.0.0.1:6020/rest/login/root
|
||||
print 4-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/rest/login/root/123
|
||||
print 5-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/rest/login/root/123/1/1/3
|
||||
print 6-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'show databases' 127.0.0.1:6020/rest/login/root/1
|
||||
print 7-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#8
|
||||
system_content curl -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cudGFvc2RhdGEuY29tIiwicGFzcyI6InRhb3NkYXRhIiwic3ViIjoicm9vdCJ9.xPv3b5odlR7YF8G_QWASjIRbMtA5v4ItToJ35fFgi' -d 'show databases' 127.0.0.1:6020/rest/login/root/1
|
||||
print 8-> $system_content
|
||||
if $system_content != @{"status":"error","code":1010,"desc":"invalid type of Authorization"}@ then
|
||||
if $system_content != @{"status":"error","code":5010,"desc":"invalid type of Authorization"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cudGFvc2RhdGEuY29tIiwicGFzcyI6InRhb3NkYXRhIiwic3ViIjoicm9vdCJ9.xPv3b5odlR7YF8G_QWASjIRbMtA5v4ItToJ35fFgi' -d 'show databases' 127.0.0.1:6020/rest/login/root/1
|
||||
print 9-> $system_content
|
||||
if $system_content != @{"status":"error","code":1010,"desc":"invalid type of Authorization"}@ then
|
||||
if $system_content != @{"status":"error","code":5010,"desc":"invalid type of Authorization"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -93,40 +93,40 @@ endi
|
|||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'create database d1' 127.0.0.1:6020/rest/sql
|
||||
print 13-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"mnode database aleady exist"}@ then
|
||||
if $system_content != @{"status":"error","code":897,"desc":"mnode database aleady exist"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#14
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d '' 127.0.0.1:6020/rest/sql
|
||||
print 14-> $system_content
|
||||
if $system_content != @{"status":"error","code":1012,"desc":"no sql input"}@ then
|
||||
if $system_content != @{"status":"error","code":5012,"desc":"no sql input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'use d1' 127.0.0.1:6020/rest/sql
|
||||
#print 15-> $system_content
|
||||
#if $system_content != @{"status":"error","code":1017,"desc":"no need to execute use db cmd"}@ then
|
||||
#if $system_content != @{"status":"error","code":5017,"desc":"no need to execute use db cmd"}@ then
|
||||
#if $system_content != @{"status":"succ","head":["affected_rows"],"data":[[1]],"rows":1}@ then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
#system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d ' use d1' 127.0.0.1:6020/rest/sql
|
||||
#print 16-> $system_content
|
||||
#if $system_content != @{"status":"error","code":1017,"desc":"no need to execute use db cmd"}@ then
|
||||
#if $system_content != @{"status":"error","code":5017,"desc":"no need to execute use db cmd"}@ then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d ' used1' 127.0.0.1:6020/rest/sql
|
||||
print 17-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"invalid SQL: invalid SQL: syntax error near 'used1'"}@ then
|
||||
if $system_content != @{"status":"error","code":512,"desc":"invalid SQL: invalid SQL: syntax error near 'used1'"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#18
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d ' show tables;' 127.0.0.1:6020/rest/sql
|
||||
print 18-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"mnode db not selected"}@ then
|
||||
if $system_content != @{"status":"error","code":896,"desc":"mnode db not selected"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -147,7 +147,7 @@ print =============== step3 - db
|
|||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d ' select * from d1.t1;' 127.0.0.1:6020/rest/sql
|
||||
print 21-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"mnode invalid table name"}@ then
|
||||
if $system_content != @{"status":"error","code":866,"desc":"mnode invalid table name"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -16,224 +16,224 @@ print =============== step1 - parse
|
|||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1022,"desc":"database name can not be null"}@ then
|
||||
if $system_content != @{"status":"error","code":5022,"desc":"database name can not be null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'select * from d1.table_admin' -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1022,"desc":"database name can not be null"}@ then
|
||||
if $system_content != @{"status":"error","code":5022,"desc":"database name can not be null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'select * from d1.table_admin' -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/d123456789012345678901234567890123456
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1023,"desc":"database name too long"}@ then
|
||||
if $system_content != @{"status":"error","code":5023,"desc":"database name too long"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[]' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1027,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5027,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1027,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5027,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{}]' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1027,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5027,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"metrics": []}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1025,"desc":"metrics size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5025,"desc":"metrics size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"metrics": [{}]}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1027,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5027,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"metrics": 12}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1025,"desc":"metrics size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5025,"desc":"metrics size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#system_content curl -u root:taosdata -d '{"metrics": [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
#print $system_content
|
||||
|
||||
#if $system_content != @{"status":"error","code":1026,"desc":"metrics size can not more than 50"}@ then
|
||||
#if $system_content != @{"status":"error","code":5026,"desc":"metrics size can not more than 50"}@ then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1027,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5027,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":111,"tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1028,"desc":"metric name type should be string"}@ then
|
||||
if $system_content != @{"status":"error","code":5028,"desc":"metric name type should be string"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1029,"desc":"metric name length is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5029,"desc":"metric name length is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234a1234567890123456789012345678901234","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1030,"desc":"metric name length too long"}@ then
|
||||
if $system_content != @{"status":"error","code":5030,"desc":"metric name length too long"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"}}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1031,"desc":"timestamp not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5031,"desc":"timestamp not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":""}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1032,"desc":"timestamp type should be integer"}@ then
|
||||
if $system_content != @{"status":"error","code":5032,"desc":"timestamp type should be integer"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":-1}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1033,"desc":"timestamp value smaller than 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5033,"desc":"timestamp value smaller than 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1034,"desc":"tags not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5034,"desc":"tags not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1035,"desc":"tags size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5035,"desc":"tags size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":"","timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1035,"desc":"tags size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5035,"desc":"tags size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor","host":"windows","instance":"1","objectname":"Processor","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata
|
||||
#print $system_content
|
||||
|
||||
#if $system_content != @{"status":"error","code":1036,"desc":"tags size too long"}@ then
|
||||
#if $system_content != @{"status":"error","code":5036,"desc":"tags size too long"}@ then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1035,"desc":"tags size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5035,"desc":"tags size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"":"windows"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1038,"desc":"tag name is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5038,"desc":"tag name is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host111111111111222222222222222222222":""},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
#print $system_content
|
||||
|
||||
#if $system_content != @{"status":"error","code":1039,"desc":"tag name length too long"}@ then
|
||||
#if $system_content != @{"status":"error","code":5039,"desc":"tag name length too long"}@ then
|
||||
# return -1
|
||||
#endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":true},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1040,"desc":"tag value type should be number or string"}@ then
|
||||
if $system_content != @{"status":"error","code":5040,"desc":"tag value type should be number or string"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":""},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1041,"desc":"tag value is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5041,"desc":"tag value is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"1022":"111"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"5022":"111"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1042,"desc":"table is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5042,"desc":"table is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222host111111111111222222222222222222222"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1043,"desc":"table name length too long"}@ then
|
||||
if $system_content != @{"status":"error","code":5043,"desc":"table name length too long"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1045,"desc":"fields size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5045,"desc":"fields size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"":0,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1048,"desc":"field name is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5048,"desc":"field name is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":"","Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1051,"desc":"field value is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5051,"desc":"field value is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{"fields":{"Percent_DPC_Time":true,"Percent_Idle_Time":95.59830474853516,"Percent_Interrupt_Time":0,"Percent_Privileged_Time":0,"Percent_Processor_Time":0,"Percent_User_Time":0},"name":"win_cpu","tags":{"host":"windows","instance":"1","objectname":"Processor"},"timestamp":1535784122}' 127.0.0.1:6020/telegraf/db/root/taosdata1
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1050,"desc":"field value type should be number or string"}@ then
|
||||
if $system_content != @{"status":"error","code":5050,"desc":"field value type should be number or string"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -365,3 +365,7 @@ cd ../../../debug; make
|
|||
./test.sh -f unique/arbitrator/sync_replica3_dropDb.sim
|
||||
./test.sh -f unique/arbitrator/sync_replica3_dropTable.sim
|
||||
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim
|
||||
|
|
|
@ -133,3 +133,7 @@ cd ../../../debug; make
|
|||
./test.sh -f unique/arbitrator/sync_replica3_dropDb.sim
|
||||
./test.sh -f unique/arbitrator/sync_replica3_dropTable.sim
|
||||
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeDir.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmMnodeVnodeDir_stopAll_starAll.sim
|
||||
./test.sh -f unique/migrate/mn2_vn2_repl2_rmVnodeDir.sim
|
||||
|
|
|
@ -124,7 +124,7 @@ run general/parser/slimit.sim
|
|||
run general/parser/fill.sim
|
||||
run general/parser/fill_stb.sim
|
||||
run general/parser/interp.sim
|
||||
# run general/parser/where.sim
|
||||
run general/parser/where.sim
|
||||
run general/parser/join.sim
|
||||
run general/parser/join_multivnode.sim
|
||||
run general/parser/select_with_tags.sim
|
||||
|
|
|
@ -113,7 +113,8 @@ echo "logDir $LOG_DIR" >> $TAOS_CFG
|
|||
echo "mDebugFlag 135" >> $TAOS_CFG
|
||||
echo "sdbDebugFlag 135" >> $TAOS_CFG
|
||||
echo "dDebugFlag 135" >> $TAOS_CFG
|
||||
echo "vDebugFlag 143" >> $TAOS_CFG
|
||||
echo "vDebugFlag 135" >> $TAOS_CFG
|
||||
echo "tsdbDebugFlag 135" >> $TAOS_CFG
|
||||
echo "cDebugFlag 135" >> $TAOS_CFG
|
||||
echo "jnidebugFlag 135" >> $TAOS_CFG
|
||||
echo "odbcdebugFlag 135" >> $TAOS_CFG
|
||||
|
@ -132,7 +133,7 @@ echo "monitorInterval 1" >> $TAOS_CFG
|
|||
echo "http 0" >> $TAOS_CFG
|
||||
echo "numOfThreadsPerCore 2.0" >> $TAOS_CFG
|
||||
echo "defaultPass taosdata" >> $TAOS_CFG
|
||||
echo "numOfLogLines 100000000" >> $TAOS_CFG
|
||||
echo "numOfLogLines 10000000" >> $TAOS_CFG
|
||||
echo "mnodeEqualVnodeNum 0" >> $TAOS_CFG
|
||||
echo "clog 2" >> $TAOS_CFG
|
||||
echo "statusInterval 1" >> $TAOS_CFG
|
||||
|
|
|
@ -33,49 +33,49 @@ print =============== step1 - login
|
|||
|
||||
system_content curl 127.0.0.1:6020/admin/
|
||||
print 1-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/admin/xx
|
||||
print 2-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/admin/login
|
||||
print 3-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/admin/login/root
|
||||
print 4-> $system_content
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/admin/login/root/123
|
||||
print 5-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl 127.0.0.1:6020/admin/login/root/123/1/1/3
|
||||
print 6-> $system_content
|
||||
if $system_content != @{"status":"error","code":1000,"desc":"auth failure"}@ then
|
||||
if $system_content != @{"status":"error","code":3,"desc":"auth failure"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.' -d 'show databases' 127.0.0.1:6020/admin/login/root/1
|
||||
print 7-> $system_content
|
||||
if $system_content != @{"status":"error","code":1010,"desc":"invalid type of Authorization"}@ then
|
||||
if $system_content != @{"status":"error","code":5010,"desc":"invalid type of Authorization"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cudGFvc2RhdGEuY29tIiwicGFzcyI6InRhb3NkYXRhIiwic3ViIjoicm9vdCJ9.xPv3b5odlR7YF8G_QWASjIRbMtA5v4ItToJ35fFgi' 127.0.0.1:6020/admin/login/root/1
|
||||
print 8-> $system_content
|
||||
if $system_content != @{"status":"error","code":1053,"desc":"parse http auth token error"}@ then
|
||||
if $system_content != @{"status":"error","code":5053,"desc":"parse http auth token error"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -105,7 +105,7 @@ endi
|
|||
system_content curl 127.0.0.1:6020/admin/logout
|
||||
print 11 -----> $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1011,"desc":"no auth info input"}@ then
|
||||
if $system_content != @{"status":"error","code":5011,"desc":"no auth info input"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -168,7 +168,7 @@ print =============== step7 - use dbs
|
|||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'use d1;' 127.0.0.1:6020/admin/all
|
||||
print 23-> $system_content
|
||||
if $system_content != @{"status":"error","code":1017,"desc":"no need to execute use db cmd"}@ then
|
||||
if $system_content != @{"status":"error","code":5017,"desc":"no need to execute use db cmd"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ system sh/stop_dnodes.sh
|
|||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/cfg.sh -n dnode1 -c http -v 1
|
||||
system sh/cfg.sh -n dnode1 -c wallevel -v 0
|
||||
system sh/cfg.sh -n dnode1 -c httpDebugFlag -v 135
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
||||
sleep 3000
|
||||
|
@ -14,92 +13,92 @@ print ============================ dnode1 start
|
|||
print =============== step1 - parse
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1057,"desc":"database name can not be null"}@ then
|
||||
if $system_content != @{"status":"error","code":5057,"desc":"database name can not be null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db123456789012345678901234567890db
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1058,"desc":"database name too long"}@ then
|
||||
if $system_content != @{"status":"error","code":5058,"desc":"database name too long"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1057,"desc":"database name can not be null"}@ then
|
||||
if $system_content != @{"status":"error","code":5057,"desc":"database name can not be null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put2
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1009,"desc":"http url parse error"}@ then
|
||||
if $system_content != @{"status":"error","code":5009,"desc":"http url parse error"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1060,"desc":"metrics size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5060,"desc":"metrics size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1059,"desc":"invalid opentsdb json fromat"}@ then
|
||||
if $system_content != @{"status":"error","code":5059,"desc":"invalid opentsdb json fromat"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '{}' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1060,"desc":"metrics size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5060,"desc":"metrics size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"error","code":1062,"desc":"metric name not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5062,"desc":"metric name not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": 1,"timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1063,"desc":"metric name type should be string"}@ then
|
||||
if $system_content != @{"status":"error","code":5063,"desc":"metric name type should be string"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1064,"desc":"metric name length is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5064,"desc":"metric name length is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "ab1234567890123456789012345678ab1234567890123456789012345678","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"ab1234567890123456789012345678ab1234567890123456789012345678","stable":"ab1234567890123456789012345678ab1234567890123456789012345678_d_bbb","table":"ab1234567890123456789012345678ab1234567890123456789012345678_d_bbb_lga_1_web01","timestamp":1346846400,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web01"},"status":"error","code":-2147482101,"desc":"tsdb timestamp is out of range"}}],"failed":1,"success":0,"affected_rows":0}@ then
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"ab1234567890123456789012345678ab1234567890123456789012345678","stable":"ab1234567890123456789012345678ab1234567890123456789012345678_d_bbb","table":"ab1234567890123456789012345678ab1234567890123456789012345678_d_bbb_lga_1_web01","timestamp":1346846400,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web01"},"status":"error","code":1547,"desc":"tsdb timestamp is out of range"}}],"failed":1,"success":0,"affected_rows":0}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1066,"desc":"timestamp not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5066,"desc":"timestamp not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": "2","value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1067,"desc":"timestamp type should be integer"}@ then
|
||||
if $system_content != @{"status":"error","code":5067,"desc":"timestamp type should be integer"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": -1,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1068,"desc":"timestamp value smaller than 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5068,"desc":"timestamp value smaller than 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1078,"desc":"value not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5078,"desc":"value not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -107,49 +106,49 @@ endi
|
|||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1069,"desc":"tags not find"}@ then
|
||||
if $system_content != @{"status":"error","code":5069,"desc":"tags not find"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1070,"desc":"tags size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5070,"desc":"tags size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": 0}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1070,"desc":"tags size is 0"}@ then
|
||||
if $system_content != @{"status":"error","code":5070,"desc":"tags size is 0"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web01","group1": "1","group1": "1","group1": "1","group1": "1","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbbbbbb","table":"sys_cpu_d_bbbbbbb_lga_1_1_1_1_1_web01","timestamp":1346846400,"value":18.000000,"tags":{"dc":"lga","group1":"1","group1":"1","group1":"1","group1":"1","group1":"1","host":"web01"},"status":"error","code":-2147482782,"desc":"failed to create table"}}],"failed":1,"success":0,"affected_rows":0}@ then
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbbbbbb","table":"sys_cpu_d_bbbbbbb_lga_1_1_1_1_1_web01","timestamp":1346846400,"value":18.000000,"tags":{"dc":"lga","group1":"1","group1":"1","group1":"1","group1":"1","group1":"1","host":"web01"},"status":"error","code":866,"desc":"failed to create table"}}],"failed":1,"success":0,"affected_rows":0}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"": "web01"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1073,"desc":"tag name is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5073,"desc":"tag name is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host01123456789001123456789001123456789001123456789001123456789001123456789": "01"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1074,"desc":"tag name length too long"}@ then
|
||||
if $system_content != @{"status":"error","code":5074,"desc":"tag name length too long"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": "web011234567890011234567890011234567890011234567890011234567890011234567890011234567890011234567890"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1077,"desc":"tag value can not more than 64"}@ then
|
||||
if $system_content != @{"status":"error","code":5077,"desc":"tag value can not more than 64"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846400,"value": 18,"tags": {"host": ""}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
print $system_content
|
||||
if $system_content != @{"status":"error","code":1076,"desc":"tag value is null"}@ then
|
||||
if $system_content != @{"status":"error","code":5076,"desc":"tag value is null"}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -175,11 +174,11 @@ if $system_content != @{"status":"succ","head":["ts","value"],"data":[["2012-09-
|
|||
endi
|
||||
|
||||
print =============== step3 - multi-query data
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846401000,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}},{"metric": "sys_cpu","timestamp": 1346846402000,"value": 18,"tags": {"host": "web02","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 1346846405000,"value": 18,"tags": {"host": "web01","group1": "1","dc": "lga"}},{"metric": "sys_cpu","timestamp": 1346846402000,"value": 18,"tags": {"host": "web02","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put
|
||||
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbb","table":"sys_cpu_d_bbb_lga_1_web01","timestamp":1346846401000,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web01"},"affected_rows":1,"status":"succ"}},{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbb","table":"sys_cpu_d_bbb_lga_1_web02","timestamp":1346846402000,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web02"},"affected_rows":1,"status":"succ"}}],"failed":0,"success":2,"affected_rows":2}@ then
|
||||
if $system_content != @{"errors":[{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbb","table":"sys_cpu_d_bbb_lga_1_web01","timestamp":1346846405000,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web01"},"affected_rows":1,"status":"succ"}},{"datapoint":{"metric":"sys_cpu","stable":"sys_cpu_d_bbb","table":"sys_cpu_d_bbb_lga_1_web02","timestamp":1346846402000,"value":18.000000,"tags":{"dc":"lga","group1":"1","host":"web02"},"affected_rows":1,"status":"succ"}}],"failed":0,"success":2,"affected_rows":2}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -187,7 +186,7 @@ system_content curl -u root:taosdata -d 'select * from db.sys_cpu_d_bbb_lga_1_w
|
|||
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"succ","head":["ts","value"],"data":[["2012-09-05 20:00:00.000",18.000000000],["2012-09-05 20:00:01.000",18.000000000]],"rows":2}@ then
|
||||
if $system_content != @{"status":"succ","head":["ts","value"],"data":[["2012-09-05 20:00:00.000",18.000000000],["2012-09-05 20:00:05.000",18.000000000]],"rows":2}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -200,7 +199,7 @@ if $system_content != @{"status":"succ","head":["count(*)"],"data":[[3]],"rows":
|
|||
endi
|
||||
|
||||
print =============== step4 - summary-put data
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_mem","timestamp": 1346846400000,"value": 8,"tags": {"host": "web01","group1": "1","dc": "lga"}},{"metric": "sys_mem","timestamp": 1346846401000,"value": 9,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put?details=false
|
||||
system_content curl -u root:taosdata -d '[{"metric": "sys_mem","timestamp": 1346846400000,"value": 8,"tags": {"host": "web01","group1": "1","dc": "lga"}},{"metric": "sys_mem","timestamp": 1346846405000,"value": 9,"tags": {"host": "web01","group1": "1","dc": "lga"}}]' 127.0.0.1:6020/opentsdb/db/put?details=false
|
||||
|
||||
print $system_content
|
||||
|
||||
|
@ -212,7 +211,7 @@ system_content curl -u root:taosdata -d 'select * from db.sys_mem_d_bbb_lga_1_w
|
|||
|
||||
print $system_content
|
||||
|
||||
if $system_content != @{"status":"succ","head":["ts","value"],"data":[["2012-09-05 20:00:00.000",8.000000000],["2012-09-05 20:00:01.000",9.000000000]],"rows":2}@ then
|
||||
if $system_content != @{"status":"succ","head":["ts","value"],"data":[["2012-09-05 20:00:00.000",8.000000000],["2012-09-05 20:00:05.000",9.000000000]],"rows":2}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -234,7 +233,7 @@ system_content curl -u root:taosdata -d '[{"metric": "sys_cpu","timestamp": 134
|
|||
|
||||
system_content curl -u root:taosdata -d 'select count(*) from db.sys_cpu_d_bbb' 127.0.0.1:6020/rest/sql/
|
||||
print $system_content
|
||||
if $system_content != @{"status":"succ","head":["count(*)"],"data":[[8]],"rows":1}@ then
|
||||
if $system_content != @{"status":"succ","head":["count(*)"],"data":[[7]],"rows":1}@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
# Test case describe: dnode1/dnode2 include mnode and vnode roles
|
||||
# step 1: start dnode1/dnode2, and added into cluster
|
||||
# step 2: create db(repl = 2), table, insert data,
|
||||
# step 4: stop dnode1, remove its mnode dir, and copy mnode dir of dnode2 to dnode1
|
||||
# step 5: restart dnode1, waiting sync end
|
||||
# step 6: stop dnode2, reset query cache, and query
|
||||
|
||||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/deploy.sh -n dnode2 -i 2
|
||||
#system sh/deploy.sh -n dnode3 -i 3
|
||||
#system sh/deploy.sh -n dnode4 -i 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
||||
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1
|
||||
#system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 2
|
||||
system sh/cfg.sh -n dnode2 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c walLevel -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c balanceInterval -v 10
|
||||
system sh/cfg.sh -n dnode2 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode3 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode4 -c balanceInterval -v 10
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfTotalVnodes -v 4
|
||||
system sh/cfg.sh -n dnode2 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c numOfTotalVnodes -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c alternativeRole -v 0
|
||||
system sh/cfg.sh -n dnode2 -c alternativeRole -v 0
|
||||
#system sh/cfg.sh -n dnode3 -c alternativeRole -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c alternativeRole -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4
|
||||
system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode5 -c maxtablesPerVnode -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c arbitrator -v $arbitrator
|
||||
system sh/cfg.sh -n dnode2 -c arbitrator -v $arbitrator
|
||||
#system sh/cfg.sh -n dnode3 -c arbitrator -v $arbitrator
|
||||
|
||||
print ============== step0: start tarbitrator
|
||||
system sh/exec_tarbitrator.sh -s start
|
||||
|
||||
print ============== step1: start dnode1/dnode2 and add into cluster
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
sleep 1000
|
||||
sql connect
|
||||
sleep 1000
|
||||
sql create dnode $hostname2
|
||||
sleep 1000
|
||||
|
||||
print ============== step2: create database with replica 2, and create table, insert data
|
||||
$totalTableNum = 10
|
||||
$sleepTimer = 3000
|
||||
|
||||
$db = db
|
||||
sql create database $db replica 2 cache 1
|
||||
sql use $db
|
||||
|
||||
# create table , insert data
|
||||
$stb = stb
|
||||
sql create table $stb (ts timestamp, c1 double) tags(t1 int)
|
||||
$rowNum = 1200
|
||||
$tblNum = $totalTableNum
|
||||
$totalRows = 0
|
||||
$tsStart = 1577808000000 # 2020-01-01 00:00:00.000
|
||||
|
||||
$i = 0
|
||||
while $i < $tblNum
|
||||
$tb = tb . $i
|
||||
sql create table $tb using $stb tags( $i )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$ts = $tsStart + $x
|
||||
sql insert into $tb values ( $ts + 0a , $x ) ( $ts + 1a , $x ) ( $ts + 2a , $x ) ( $ts + 3a , $x ) ( $ts + 4a , $x ) ( $ts + 5a , $x ) ( $ts + 6a , $x ) ( $ts + 7a , $x ) ( $ts + 8a , $x ) ( $ts + 9a , $x ) ( $ts + 10a , $x ) ( $ts + 11a , $x ) ( $ts + 12a , $x ) ( $ts + 13a , $x ) ( $ts + 14a , $x ) ( $ts + 15a , $x ) ( $ts + 16a , $x ) ( $ts + 17a , $x ) ( $ts + 18a , $x ) ( $ts + 19a , $x ) ( $ts + 20a , $x ) ( $ts + 21a , $x ) ( $ts + 22a , $x ) ( $ts + 23a , $x ) ( $ts + 24a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 35a , $x ) ( $ts + 36a , $x ) ( $ts + 37a , $x ) ( $ts + 38a , $x ) ( $ts + 39a , $x ) ( $ts + 40a , $x ) ( $ts + 41a , $x ) ( $ts + 42a , $x ) ( $ts + 43a , $x ) ( $ts + 44a , $x ) ( $ts + 45a , $x ) ( $ts + 46a , $x ) ( $ts + 47a , $x ) ( $ts + 48a , $x ) ( $ts + 49a , $x ) ( $ts + 50a , $x ) ( $ts + 51a , $x ) ( $ts + 52a , $x ) ( $ts + 53a , $x ) ( $ts + 54a , $x ) ( $ts + 55a , $x ) ( $ts + 56a , $x ) ( $ts + 57a , $x ) ( $ts + 58a , $x ) ( $ts + 59a , $x )
|
||||
$x = $x + 60
|
||||
endw
|
||||
$totalRows = $totalRows + $x
|
||||
print info: inserted $x rows into $tb and totalRows: $totalRows
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sql select count(*) from $stb
|
||||
print rows:$rows data00:$data00 totalRows:$totalRows
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
print ============== step3: insert old data(now-15d) and new data(now+15d), control data rows in order to save in cache, not falling disc
|
||||
sql insert into $tb values ( now - 20d , -20 )
|
||||
sql insert into $tb values ( now - 40d , -40 )
|
||||
$totalRows = $totalRows + 2
|
||||
|
||||
print ============== step4: stop dnode1
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#sql show vgroups
|
||||
#print show vgroups:
|
||||
#print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
#print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
#print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
|
||||
print ============== step5: remove the mnode dir of dnode1, then copy the monde dir of dnode2
|
||||
system_content rm -rf ../../../sim/dnode1/data/mnode
|
||||
system_content cp -rf ../../../sim/dnode2/data/mnode ../../../sim/dnode1/data/
|
||||
|
||||
print ============== step6: restart dnode1, waiting sync end
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 1000
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_ready:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 20 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes -x wait_dnode1_ready
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_vgroup_slave:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show vgroups
|
||||
if $rows != 3 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
print show vgroups:
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4
|
||||
$d2v2status = $data4_4
|
||||
$d2v3status = $data4_2
|
||||
$d2v4status = $data4_3
|
||||
|
||||
$d1v2status = $data7_4
|
||||
$d1v3status = $data7_2
|
||||
$d1v4status = $data7_3
|
||||
|
||||
if $d2v2status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v3status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v4status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
if $d1v2status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v3status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v4status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
print ============== step7: stop dnode2
|
||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode2_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
if $dnode2Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
|
||||
sql reset query cache
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
|
@ -0,0 +1,274 @@
|
|||
# Test case describe: dnode1/dnode2 include mnode and vnode roles
|
||||
# step 1: start dnode1/dnode2, and added into cluster
|
||||
# step 2: create db(repl = 2), table, insert data,
|
||||
# step 4: stop dnode1, remove its mnode and vnode dir, and copy mnode and vnode dir of dnode2 to dnode1
|
||||
# step 5: restart dnode1, waiting sync end
|
||||
# step 6: stop dnode2, reset query cache, and query
|
||||
|
||||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/deploy.sh -n dnode2 -i 2
|
||||
#system sh/deploy.sh -n dnode3 -i 3
|
||||
#system sh/deploy.sh -n dnode4 -i 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
||||
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1
|
||||
#system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 2
|
||||
system sh/cfg.sh -n dnode2 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c walLevel -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c balanceInterval -v 10
|
||||
system sh/cfg.sh -n dnode2 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode3 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode4 -c balanceInterval -v 10
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfTotalVnodes -v 4
|
||||
system sh/cfg.sh -n dnode2 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c numOfTotalVnodes -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c alternativeRole -v 0
|
||||
system sh/cfg.sh -n dnode2 -c alternativeRole -v 0
|
||||
#system sh/cfg.sh -n dnode3 -c alternativeRole -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c alternativeRole -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4
|
||||
system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode5 -c maxtablesPerVnode -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c arbitrator -v $arbitrator
|
||||
system sh/cfg.sh -n dnode2 -c arbitrator -v $arbitrator
|
||||
#system sh/cfg.sh -n dnode3 -c arbitrator -v $arbitrator
|
||||
|
||||
print ============== step0: start tarbitrator
|
||||
system sh/exec_tarbitrator.sh -s start
|
||||
|
||||
print ============== step1: start dnode1/dnode2 and add into cluster
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
sleep 1000
|
||||
sql connect
|
||||
sleep 1000
|
||||
sql create dnode $hostname2
|
||||
sleep 1000
|
||||
|
||||
print ============== step2: create database with replica 2, and create table, insert data
|
||||
$totalTableNum = 10
|
||||
$sleepTimer = 3000
|
||||
|
||||
$db = db
|
||||
sql create database $db replica 2 cache 1
|
||||
sql use $db
|
||||
|
||||
# create table , insert data
|
||||
$stb = stb
|
||||
sql create table $stb (ts timestamp, c1 double) tags(t1 int)
|
||||
$rowNum = 1200
|
||||
$tblNum = $totalTableNum
|
||||
$totalRows = 0
|
||||
$tsStart = 1577808000000 # 2020-01-01 00:00:00.000
|
||||
|
||||
$i = 0
|
||||
while $i < $tblNum
|
||||
$tb = tb . $i
|
||||
sql create table $tb using $stb tags( $i )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$ts = $tsStart + $x
|
||||
sql insert into $tb values ( $ts + 0a , $x ) ( $ts + 1a , $x ) ( $ts + 2a , $x ) ( $ts + 3a , $x ) ( $ts + 4a , $x ) ( $ts + 5a , $x ) ( $ts + 6a , $x ) ( $ts + 7a , $x ) ( $ts + 8a , $x ) ( $ts + 9a , $x ) ( $ts + 10a , $x ) ( $ts + 11a , $x ) ( $ts + 12a , $x ) ( $ts + 13a , $x ) ( $ts + 14a , $x ) ( $ts + 15a , $x ) ( $ts + 16a , $x ) ( $ts + 17a , $x ) ( $ts + 18a , $x ) ( $ts + 19a , $x ) ( $ts + 20a , $x ) ( $ts + 21a , $x ) ( $ts + 22a , $x ) ( $ts + 23a , $x ) ( $ts + 24a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 35a , $x ) ( $ts + 36a , $x ) ( $ts + 37a , $x ) ( $ts + 38a , $x ) ( $ts + 39a , $x ) ( $ts + 40a , $x ) ( $ts + 41a , $x ) ( $ts + 42a , $x ) ( $ts + 43a , $x ) ( $ts + 44a , $x ) ( $ts + 45a , $x ) ( $ts + 46a , $x ) ( $ts + 47a , $x ) ( $ts + 48a , $x ) ( $ts + 49a , $x ) ( $ts + 50a , $x ) ( $ts + 51a , $x ) ( $ts + 52a , $x ) ( $ts + 53a , $x ) ( $ts + 54a , $x ) ( $ts + 55a , $x ) ( $ts + 56a , $x ) ( $ts + 57a , $x ) ( $ts + 58a , $x ) ( $ts + 59a , $x )
|
||||
$x = $x + 60
|
||||
endw
|
||||
$totalRows = $totalRows + $x
|
||||
print info: inserted $x rows into $tb and totalRows: $totalRows
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sql select count(*) from $stb
|
||||
print rows:$rows data00:$data00 totalRows:$totalRows
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
print ============== step3: insert old data(now-15d) and new data(now+15d), control data rows in order to save in cache, not falling disc
|
||||
sql insert into $tb values ( now - 20d , -20 )
|
||||
sql insert into $tb values ( now - 40d , -40 )
|
||||
$totalRows = $totalRows + 2
|
||||
|
||||
print ============== step4: stop dnode1
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#sql show vgroups
|
||||
#print show vgroups:
|
||||
#print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
#print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
#print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
|
||||
print ============== step5: remove the mnode dir of dnode1, then copy the monde dir of dnode2
|
||||
system_content rm -rf ../../../sim/dnode1/data/vnode
|
||||
system_content rm -rf ../../../sim/dnode1/data/mnode
|
||||
system_content cp -rf ../../../sim/dnode2/data/vnode ../../../sim/dnode1/data/
|
||||
system_content cp -rf ../../../sim/dnode2/data/mnode ../../../sim/dnode1/data/
|
||||
|
||||
print ============== step6: restart dnode1, waiting sync end
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 1000
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_ready:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 20 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes -x wait_dnode1_ready
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_vgroup_slave:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show vgroups
|
||||
if $rows != 3 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
print show vgroups:
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4
|
||||
$d2v2status = $data4_4
|
||||
$d2v3status = $data4_2
|
||||
$d2v4status = $data4_3
|
||||
|
||||
$d1v2status = $data7_4
|
||||
$d1v3status = $data7_2
|
||||
$d1v4status = $data7_3
|
||||
|
||||
if $d2v2status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v3status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v4status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
if $d1v2status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v3status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v4status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
print ============== step7: stop dnode2
|
||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode2_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
if $dnode2Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
|
||||
sql reset query cache
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
|
@ -0,0 +1,210 @@
|
|||
# Test case describe: dnode1/dnode2 include mnode and vnode roles
|
||||
# step 1: start dnode1/dnode2, and added into cluster
|
||||
# step 2: create db(repl = 2), table, insert data,
|
||||
# step 4: stop dnode1, remove its mnode and vnode dir, and copy mnode and vnode dir of dnode2 to dnode1
|
||||
# step 5: restart dnode1, waiting sync end
|
||||
# step 6: stop dnode2, reset query cache, and query
|
||||
|
||||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/deploy.sh -n dnode2 -i 2
|
||||
#system sh/deploy.sh -n dnode3 -i 3
|
||||
#system sh/deploy.sh -n dnode4 -i 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
||||
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1
|
||||
#system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 2
|
||||
system sh/cfg.sh -n dnode2 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c walLevel -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c balanceInterval -v 10
|
||||
system sh/cfg.sh -n dnode2 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode3 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode4 -c balanceInterval -v 10
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfTotalVnodes -v 4
|
||||
system sh/cfg.sh -n dnode2 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c numOfTotalVnodes -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c alternativeRole -v 0
|
||||
system sh/cfg.sh -n dnode2 -c alternativeRole -v 0
|
||||
#system sh/cfg.sh -n dnode3 -c alternativeRole -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c alternativeRole -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4
|
||||
system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode5 -c maxtablesPerVnode -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c arbitrator -v $arbitrator
|
||||
system sh/cfg.sh -n dnode2 -c arbitrator -v $arbitrator
|
||||
#system sh/cfg.sh -n dnode3 -c arbitrator -v $arbitrator
|
||||
|
||||
print ============== step0: start tarbitrator
|
||||
system sh/exec_tarbitrator.sh -s start
|
||||
|
||||
print ============== step1: start dnode1/dnode2 and add into cluster
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
sleep 1000
|
||||
sql connect
|
||||
sleep 1000
|
||||
sql create dnode $hostname2
|
||||
sleep 1000
|
||||
|
||||
print ============== step2: create database with replica 2, and create table, insert data
|
||||
$totalTableNum = 10
|
||||
$sleepTimer = 3000
|
||||
|
||||
$db = db
|
||||
sql create database $db replica 2 cache 1
|
||||
sql use $db
|
||||
|
||||
# create table , insert data
|
||||
$stb = stb
|
||||
sql create table $stb (ts timestamp, c1 double) tags(t1 int)
|
||||
$rowNum = 1200
|
||||
$tblNum = $totalTableNum
|
||||
$totalRows = 0
|
||||
$tsStart = 1577808000000 # 2020-01-01 00:00:00.000
|
||||
|
||||
$i = 0
|
||||
while $i < $tblNum
|
||||
$tb = tb . $i
|
||||
sql create table $tb using $stb tags( $i )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$ts = $tsStart + $x
|
||||
sql insert into $tb values ( $ts + 0a , $x ) ( $ts + 1a , $x ) ( $ts + 2a , $x ) ( $ts + 3a , $x ) ( $ts + 4a , $x ) ( $ts + 5a , $x ) ( $ts + 6a , $x ) ( $ts + 7a , $x ) ( $ts + 8a , $x ) ( $ts + 9a , $x ) ( $ts + 10a , $x ) ( $ts + 11a , $x ) ( $ts + 12a , $x ) ( $ts + 13a , $x ) ( $ts + 14a , $x ) ( $ts + 15a , $x ) ( $ts + 16a , $x ) ( $ts + 17a , $x ) ( $ts + 18a , $x ) ( $ts + 19a , $x ) ( $ts + 20a , $x ) ( $ts + 21a , $x ) ( $ts + 22a , $x ) ( $ts + 23a , $x ) ( $ts + 24a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 35a , $x ) ( $ts + 36a , $x ) ( $ts + 37a , $x ) ( $ts + 38a , $x ) ( $ts + 39a , $x ) ( $ts + 40a , $x ) ( $ts + 41a , $x ) ( $ts + 42a , $x ) ( $ts + 43a , $x ) ( $ts + 44a , $x ) ( $ts + 45a , $x ) ( $ts + 46a , $x ) ( $ts + 47a , $x ) ( $ts + 48a , $x ) ( $ts + 49a , $x ) ( $ts + 50a , $x ) ( $ts + 51a , $x ) ( $ts + 52a , $x ) ( $ts + 53a , $x ) ( $ts + 54a , $x ) ( $ts + 55a , $x ) ( $ts + 56a , $x ) ( $ts + 57a , $x ) ( $ts + 58a , $x ) ( $ts + 59a , $x )
|
||||
$x = $x + 60
|
||||
endw
|
||||
$totalRows = $totalRows + $x
|
||||
print info: inserted $x rows into $tb and totalRows: $totalRows
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sql select count(*) from $stb
|
||||
print rows:$rows data00:$data00 totalRows:$totalRows
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
print ============== step3: insert old data(now-15d) and new data(now+15d), control data rows in order to save in cache, not falling disc
|
||||
sql insert into $tb values ( now - 20d , -20 )
|
||||
sql insert into $tb values ( now - 40d , -40 )
|
||||
$totalRows = $totalRows + 2
|
||||
|
||||
print ============== step4: stop dnode1
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||
|
||||
print ============== step5: remove the mnode dir of dnode1, then copy the monde dir of dnode2
|
||||
system_content rm -rf ../../../sim/dnode1/data/vnode
|
||||
system_content rm -rf ../../../sim/dnode1/data/mnode
|
||||
system_content cp -rf ../../../sim/dnode2/data/vnode ../../../sim/dnode1/data/
|
||||
system_content cp -rf ../../../sim/dnode2/data/mnode ../../../sim/dnode1/data/
|
||||
|
||||
print ============== step6: restart dnode1/dnode2
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
sleep 1000
|
||||
sql connect
|
||||
sql use $db
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_ready:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 20 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes -x wait_dnode1_ready
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_vgroup_slave:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show vgroups
|
||||
if $rows != 3 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
print show vgroups:
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4
|
||||
$d2v2status = $data4_4
|
||||
$d2v3status = $data4_2
|
||||
$d2v4status = $data4_3
|
||||
|
||||
$d1v2status = $data7_4
|
||||
$d1v3status = $data7_2
|
||||
$d1v4status = $data7_3
|
||||
|
||||
if $d2v2status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v3status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v4status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
if $d1v2status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v3status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v4status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
sql reset query cache
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
|
@ -0,0 +1,272 @@
|
|||
# Test case describe: dnode1/dnode2 include mnode and vnode roles
|
||||
# step 1: start dnode1/dnode2, and added into cluster
|
||||
# step 2: create db(repl = 2), table, insert data,
|
||||
# step 4: stop dnode1, remove its vnode dir, and copy vnode dir of dnode2 to dnode1
|
||||
# step 5: restart dnode1, waiting sync end
|
||||
# step 6: stop dnode2, reset query cache, and query
|
||||
|
||||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/deploy.sh -n dnode2 -i 2
|
||||
#system sh/deploy.sh -n dnode3 -i 3
|
||||
#system sh/deploy.sh -n dnode4 -i 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2
|
||||
system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1
|
||||
#system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 2
|
||||
system sh/cfg.sh -n dnode2 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode3 -c walLevel -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c walLevel -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c balanceInterval -v 10
|
||||
system sh/cfg.sh -n dnode2 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode3 -c balanceInterval -v 10
|
||||
#system sh/cfg.sh -n dnode4 -c balanceInterval -v 10
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c numOfTotalVnodes -v 4
|
||||
system sh/cfg.sh -n dnode2 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c numOfTotalVnodes -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c numOfTotalVnodes -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c alternativeRole -v 0
|
||||
system sh/cfg.sh -n dnode2 -c alternativeRole -v 0
|
||||
#system sh/cfg.sh -n dnode3 -c alternativeRole -v 2
|
||||
#system sh/cfg.sh -n dnode4 -c alternativeRole -v 2
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4
|
||||
system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 4
|
||||
#system sh/cfg.sh -n dnode5 -c maxtablesPerVnode -v 4
|
||||
|
||||
system sh/cfg.sh -n dnode1 -c arbitrator -v $arbitrator
|
||||
system sh/cfg.sh -n dnode2 -c arbitrator -v $arbitrator
|
||||
#system sh/cfg.sh -n dnode3 -c arbitrator -v $arbitrator
|
||||
|
||||
print ============== step0: start tarbitrator
|
||||
system sh/exec_tarbitrator.sh -s start
|
||||
|
||||
print ============== step1: start dnode1/dnode2 and add into cluster
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
system sh/exec.sh -n dnode2 -s start
|
||||
sleep 1000
|
||||
sql connect
|
||||
sleep 1000
|
||||
sql create dnode $hostname2
|
||||
sleep 1000
|
||||
|
||||
print ============== step2: create database with replica 2, and create table, insert data
|
||||
$totalTableNum = 10
|
||||
$sleepTimer = 3000
|
||||
|
||||
$db = db
|
||||
sql create database $db replica 2 cache 1
|
||||
sql use $db
|
||||
|
||||
# create table , insert data
|
||||
$stb = stb
|
||||
sql create table $stb (ts timestamp, c1 double) tags(t1 int)
|
||||
$rowNum = 1200
|
||||
$tblNum = $totalTableNum
|
||||
$totalRows = 0
|
||||
$tsStart = 1577808000000 # 2020-01-01 00:00:00.000
|
||||
|
||||
$i = 0
|
||||
while $i < $tblNum
|
||||
$tb = tb . $i
|
||||
sql create table $tb using $stb tags( $i )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$ts = $tsStart + $x
|
||||
sql insert into $tb values ( $ts + 0a , $x ) ( $ts + 1a , $x ) ( $ts + 2a , $x ) ( $ts + 3a , $x ) ( $ts + 4a , $x ) ( $ts + 5a , $x ) ( $ts + 6a , $x ) ( $ts + 7a , $x ) ( $ts + 8a , $x ) ( $ts + 9a , $x ) ( $ts + 10a , $x ) ( $ts + 11a , $x ) ( $ts + 12a , $x ) ( $ts + 13a , $x ) ( $ts + 14a , $x ) ( $ts + 15a , $x ) ( $ts + 16a , $x ) ( $ts + 17a , $x ) ( $ts + 18a , $x ) ( $ts + 19a , $x ) ( $ts + 20a , $x ) ( $ts + 21a , $x ) ( $ts + 22a , $x ) ( $ts + 23a , $x ) ( $ts + 24a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 25a , $x ) ( $ts + 26a , $x ) ( $ts + 27a , $x ) ( $ts + 28a , $x ) ( $ts + 29a , $x ) ( $ts + 30a , $x ) ( $ts + 31a , $x ) ( $ts + 32a , $x ) ( $ts + 33a , $x ) ( $ts + 34a , $x ) ( $ts + 35a , $x ) ( $ts + 36a , $x ) ( $ts + 37a , $x ) ( $ts + 38a , $x ) ( $ts + 39a , $x ) ( $ts + 40a , $x ) ( $ts + 41a , $x ) ( $ts + 42a , $x ) ( $ts + 43a , $x ) ( $ts + 44a , $x ) ( $ts + 45a , $x ) ( $ts + 46a , $x ) ( $ts + 47a , $x ) ( $ts + 48a , $x ) ( $ts + 49a , $x ) ( $ts + 50a , $x ) ( $ts + 51a , $x ) ( $ts + 52a , $x ) ( $ts + 53a , $x ) ( $ts + 54a , $x ) ( $ts + 55a , $x ) ( $ts + 56a , $x ) ( $ts + 57a , $x ) ( $ts + 58a , $x ) ( $ts + 59a , $x )
|
||||
$x = $x + 60
|
||||
endw
|
||||
$totalRows = $totalRows + $x
|
||||
print info: inserted $x rows into $tb and totalRows: $totalRows
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
sql select count(*) from $stb
|
||||
print rows:$rows data00:$data00 totalRows:$totalRows
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
print ============== step3: insert old data(now-15d) and new data(now+15d), control data rows in order to save in cache, not falling disc
|
||||
sql insert into $tb values ( now - 20d , -20 )
|
||||
sql insert into $tb values ( now - 40d , -40 )
|
||||
$totalRows = $totalRows + 2
|
||||
|
||||
print ============== step4: stop dnode1
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_offline
|
||||
endi
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
||||
|
||||
#sql show vgroups
|
||||
#print show vgroups:
|
||||
#print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
#print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
#print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
|
||||
print ============== step5: remove the mnode dir of dnode1, then copy the monde dir of dnode2
|
||||
system_content rm -rf ../../../sim/dnode1/data/vnode
|
||||
system_content cp -rf ../../../sim/dnode2/data/vnode ../../../sim/dnode1/data/
|
||||
|
||||
print ============== step6: restart dnode1, waiting sync end
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 1000
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_ready:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 20 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes -x wait_dnode1_ready
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
if $dnode2Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode1_ready
|
||||
endi
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode1_vgroup_slave:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show vgroups
|
||||
if $rows != 3 then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
print show vgroups:
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1 $data5_1 $data6_1 $data7_1 $data8_1 $data9_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2 $data5_2 $data6_2 $data7_2 $data8_2 $data9_2
|
||||
print $data0_3 $data1_3 $data2_3 $data3_3 $data4_3 $data5_3 $data6_3 $data7_3 $data8_3 $data9_3
|
||||
print $data0_4 $data1_4 $data2_4 $data3_4 $data4_4 $data5_4 $data6_4 $data7_4 $data8_4 $data9_4
|
||||
$d2v2status = $data4_4
|
||||
$d2v3status = $data4_2
|
||||
$d2v4status = $data4_3
|
||||
|
||||
$d1v2status = $data7_4
|
||||
$d1v3status = $data7_2
|
||||
$d1v4status = $data7_3
|
||||
|
||||
if $d2v2status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v3status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d2v4status != master then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
if $d1v2status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v3status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
if $d1v4status != slave then
|
||||
sleep 2000
|
||||
goto wait_dnode1_vgroup_slave
|
||||
endi
|
||||
|
||||
print ============== step7: stop dnode2
|
||||
system sh/exec.sh -n dnode2 -s stop -x SIGINT
|
||||
|
||||
$loopCnt = 0
|
||||
wait_dnode2_offline:
|
||||
$loopCnt = $loopCnt + 1
|
||||
if $loopCnt == 10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql show dnodes
|
||||
if $rows != 2 then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
print $data0_1 $data1_1 $data2_1 $data3_1 $data4_1
|
||||
print $data0_2 $data1_2 $data2_2 $data3_2 $data4_2
|
||||
$dnode1Status = $data4_1
|
||||
$dnode2Status = $data4_2
|
||||
|
||||
if $dnode1Status != ready then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
if $dnode2Status != offline then
|
||||
sleep 2000
|
||||
goto wait_dnode2_offline
|
||||
endi
|
||||
|
||||
sql reset query cache
|
||||
|
||||
# check using select
|
||||
sql select count(*) from $stb
|
||||
print data00 $data00
|
||||
if $data00 != $totalRows then
|
||||
return -1
|
||||
endi
|
|
@ -0,0 +1,3 @@
|
|||
stress
|
||||
stress.exe
|
||||
cases.json
|
|
@ -0,0 +1,80 @@
|
|||
# STRESS
|
||||
|
||||
Stress test tool for TDengine. It run a set of test cases randomly and show statistics.
|
||||
|
||||
## COMMAND LINE
|
||||
|
||||
``` bash
|
||||
$ ./stress [-h=<localhost>] [-P=<0>] [-d=<test>] [-u=<root>] [-p=<taosdata>] [-c=<4>] [-f=<true>] [-l=<logPath>] [path_or_sql]
|
||||
```
|
||||
|
||||
* **-h**: host name or IP address of TDengine server (default: localhost).
|
||||
* **-P**: port number of TDengine server (default: 0).
|
||||
* **-u**: user name (default: root).
|
||||
* **-p**: password (default: taosdata).
|
||||
* **-c**: concurrency, number of concurrent goroutines for query (default: 4).
|
||||
* **-f**: fetch data or not (default: true).
|
||||
* **-l**: log file path (default: no log).
|
||||
* **path_or_sql**: a SQL statement or path of a JSON file which contains the test cases (default: cases.json).
|
||||
|
||||
## TEST CASE FILE
|
||||
|
||||
```json
|
||||
[{
|
||||
"weight": 1,
|
||||
"sql": "select * from meters where ts>=now+%dm and ts<=now-%dm and c1=%v and c2=%d and c3='%s' and tbname='%s'",
|
||||
"args": [{
|
||||
"type": "range",
|
||||
"min": 30,
|
||||
"max": 60
|
||||
}, {
|
||||
"type": "bool"
|
||||
}, {
|
||||
"type": "int",
|
||||
"min": -10,
|
||||
"max": 20
|
||||
}, {
|
||||
"type": "string",
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
}, {
|
||||
"type": "list",
|
||||
"list": [
|
||||
"table1",
|
||||
"table2",
|
||||
"table3",
|
||||
"table4"
|
||||
]
|
||||
}]
|
||||
}]
|
||||
```
|
||||
|
||||
The test case file is a standard JSON file which contains an array of test cases. For test cases, field `sql` is mandatory, and it can optionally include a `weight` field and an `args` field which is an array of arguments.
|
||||
|
||||
`sql` is a SQL statement, it can include zero or more arguments (placeholders).
|
||||
|
||||
`weight` defines the possibility of the case being selected, the greater value the higher possibility. It must be an non-negative integer and the default value is zero, but, if all cases have a zero weight, all the weights are regarded as 1.
|
||||
|
||||
Placeholders of `sql` are replaced by arguments in `args` at runtime. There are 5 types of arguments currently:
|
||||
|
||||
* **bool**: generate a `boolean` value randomly.
|
||||
* **int**: generate an `integer` between [`min`, `max`] randomly, the default value of `min` is 0 and `max` is 100.
|
||||
* **range**: generate two `integer`s between [`min`, `max`] randomly, the first is less than the second, the default value of `min` is 0 and `max` is 100.
|
||||
* **string**: generate a `string` with length between [`min`, `max`] randomly, the default value of `min` is 0 and `max` is 100.
|
||||
* **list**: select an item from `list` randomly.
|
||||
|
||||
## OUTPUT
|
||||
|
||||
```
|
||||
00:00:08 | TOTAL REQ | TOTAL TIME(us) | TOTAL AVG(us) | REQUEST | TIME(us) | AVERAGE(us) |
|
||||
TOTAL | 3027 | 26183890 | 8650.11 | 287 | 3060935 | 10665.28 |
|
||||
SUCCESS | 3027 | 26183890 | 8650.11 | 287 | 3060935 | 10665.28 |
|
||||
FAIL | 0 | 0 | 0.00 | 0 | 0 | 0.00 |
|
||||
```
|
||||
|
||||
* **Col 2**: total number of request since test start.
|
||||
* **Col 3**: total time of all request since test start.
|
||||
* **Col 4**: average time of all request since test start.
|
||||
* **Col 5**: number of request in last second.
|
||||
* **Col 6**: time of all request in last second.
|
||||
* **Col 7**: average time of all request in last second.
|
|
@ -0,0 +1,7 @@
|
|||
module github.com/taosdata/stress
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/taosdata/driver-go v0.0.0-20200606095205-b786bac1857f
|
||||
)
|
|
@ -0,0 +1,406 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
_ "github.com/taosdata/driver-go/taosSql"
|
||||
)
|
||||
|
||||
type argument struct {
|
||||
Type string `json:"type"`
|
||||
Min int `json:"min"`
|
||||
Max int `json:"max"`
|
||||
List []interface{} `json:"list, omitempty"`
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
isQuery bool `json:"-"`
|
||||
numArgs int `json:"-"`
|
||||
Weight int `json:"weight"`
|
||||
SQL string `json:"sql"`
|
||||
Args []argument `json:"args"`
|
||||
}
|
||||
|
||||
func (arg *argument) check() (int, error) {
|
||||
if arg.Type == "list" {
|
||||
if len(arg.List) == 0 {
|
||||
return 0, errors.New("list cannot be empty")
|
||||
}
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
if arg.Max < arg.Min {
|
||||
return 0, errors.New("invalid min/max value")
|
||||
}
|
||||
|
||||
if arg.Type == "string" {
|
||||
if arg.Min < 0 {
|
||||
return 0, errors.New("negative string length")
|
||||
}
|
||||
}
|
||||
|
||||
if arg.Type == "int" && arg.Min == 0 && arg.Max == 0 {
|
||||
arg.Max = arg.Min + 100
|
||||
}
|
||||
|
||||
if arg.Type == "range" {
|
||||
return 2, nil
|
||||
}
|
||||
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
func (arg *argument) generate(args []interface{}) []interface{} {
|
||||
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
switch arg.Type {
|
||||
case "bool":
|
||||
if rand.Intn(2) == 1 {
|
||||
args = append(args, true)
|
||||
} else {
|
||||
args = append(args, false)
|
||||
}
|
||||
|
||||
case "int":
|
||||
v := rand.Intn(arg.Max-arg.Min+1) + arg.Min
|
||||
args = append(args, v)
|
||||
|
||||
case "range":
|
||||
v := rand.Intn(arg.Max-arg.Min) + arg.Min
|
||||
args = append(args, v)
|
||||
v = rand.Intn(arg.Max-v+1) + v
|
||||
args = append(args, v)
|
||||
|
||||
case "string":
|
||||
l := rand.Intn(arg.Max-arg.Min+1) + arg.Min
|
||||
sb := strings.Builder{}
|
||||
for i := 0; i < l; i++ {
|
||||
sb.WriteByte(chars[rand.Intn(len(chars))])
|
||||
}
|
||||
args = append(args, sb.String())
|
||||
|
||||
case "list":
|
||||
v := arg.List[rand.Intn(len(arg.List))]
|
||||
args = append(args, v)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func (tc *testCase) buildSql() string {
|
||||
args := make([]interface{}, 0, tc.numArgs)
|
||||
for i := 0; i < len(tc.Args); i++ {
|
||||
args = tc.Args[i].generate(args)
|
||||
}
|
||||
return fmt.Sprintf(tc.SQL, args...)
|
||||
}
|
||||
|
||||
type statitics struct {
|
||||
succeeded int64
|
||||
failed int64
|
||||
succeededDuration int64
|
||||
failedDuration int64
|
||||
}
|
||||
|
||||
var (
|
||||
host string
|
||||
port uint
|
||||
database string
|
||||
user string
|
||||
password string
|
||||
fetch bool
|
||||
|
||||
chLog chan string
|
||||
wgLog sync.WaitGroup
|
||||
startAt time.Time
|
||||
shouldStop int64
|
||||
wgTest sync.WaitGroup
|
||||
stat statitics
|
||||
totalWeight int
|
||||
cases []testCase
|
||||
)
|
||||
|
||||
func loadTestCaseFromFile(file *os.File) error {
|
||||
if e := json.NewDecoder(file).Decode(&cases); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
if len(cases) == 0 {
|
||||
return fmt.Errorf("no test case loaded.")
|
||||
}
|
||||
|
||||
for i := 0; i < len(cases); i++ {
|
||||
c := &cases[i]
|
||||
c.SQL = strings.TrimSpace(c.SQL)
|
||||
c.isQuery = strings.ToLower(c.SQL[:6]) == "select"
|
||||
if c.Weight < 0 {
|
||||
return fmt.Errorf("test %d: negative weight", i)
|
||||
}
|
||||
totalWeight += c.Weight
|
||||
|
||||
for j := 0; j < len(c.Args); j++ {
|
||||
arg := &c.Args[j]
|
||||
arg.Type = strings.ToLower(arg.Type)
|
||||
n, e := arg.check()
|
||||
if e != nil {
|
||||
return fmt.Errorf("test case %d argument %d: %s", i, j, e.Error())
|
||||
}
|
||||
c.numArgs += n
|
||||
}
|
||||
}
|
||||
|
||||
if totalWeight == 0 {
|
||||
for i := 0; i < len(cases); i++ {
|
||||
cases[i].Weight = 1
|
||||
}
|
||||
totalWeight = len(cases)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadTestCase(pathOrSQL string) error {
|
||||
if f, e := os.Open(pathOrSQL); e == nil {
|
||||
defer f.Close()
|
||||
return loadTestCaseFromFile(f)
|
||||
}
|
||||
|
||||
pathOrSQL = strings.TrimSpace(pathOrSQL)
|
||||
if strings.ToLower(pathOrSQL[:6]) != "select" {
|
||||
return fmt.Errorf("'%s' is not a valid file or SQL statement", pathOrSQL)
|
||||
}
|
||||
|
||||
cases = append(cases, testCase{
|
||||
isQuery: true,
|
||||
Weight: 1,
|
||||
numArgs: 0,
|
||||
SQL: pathOrSQL,
|
||||
})
|
||||
totalWeight = 1
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func selectTestCase() *testCase {
|
||||
sum, target := 0, rand.Intn(totalWeight)
|
||||
var c *testCase
|
||||
for i := 0; i < len(cases); i++ {
|
||||
c = &cases[i]
|
||||
sum += c.Weight
|
||||
if sum > target {
|
||||
break
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func runTest() {
|
||||
defer wgTest.Done()
|
||||
db, e := sql.Open("taosSql", fmt.Sprintf("%s:%s@tcp(%s:%v)/%s", user, password, host, port, database))
|
||||
if e != nil {
|
||||
fmt.Printf("failed to connect to database: %s\n", e.Error())
|
||||
return
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
for atomic.LoadInt64(&shouldStop) == 0 {
|
||||
c := selectTestCase()
|
||||
str := c.buildSql()
|
||||
|
||||
start := time.Now()
|
||||
if c.isQuery {
|
||||
var rows *sql.Rows
|
||||
if rows, e = db.Query(str); rows != nil {
|
||||
if fetch {
|
||||
for rows.Next() {
|
||||
}
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
} else {
|
||||
_, e = db.Exec(str)
|
||||
}
|
||||
duration := time.Now().Sub(start).Microseconds()
|
||||
|
||||
if e != nil {
|
||||
if chLog != nil {
|
||||
chLog <- str + ": " + e.Error()
|
||||
}
|
||||
atomic.AddInt64(&stat.failed, 1)
|
||||
atomic.AddInt64(&stat.failedDuration, duration)
|
||||
} else {
|
||||
atomic.AddInt64(&stat.succeeded, 1)
|
||||
atomic.AddInt64(&stat.succeededDuration, duration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getStatPrinter() func(tm time.Time) {
|
||||
var last statitics
|
||||
lastPrintAt := startAt
|
||||
|
||||
return func(tm time.Time) {
|
||||
var current statitics
|
||||
|
||||
current.succeeded = atomic.LoadInt64(&stat.succeeded)
|
||||
current.failed = atomic.LoadInt64(&stat.failed)
|
||||
current.succeededDuration = atomic.LoadInt64(&stat.succeededDuration)
|
||||
current.failedDuration = atomic.LoadInt64(&stat.failedDuration)
|
||||
|
||||
seconds := int64(tm.Sub(startAt).Seconds())
|
||||
format := "\033[47;30m %02v:%02v:%02v | TOTAL REQ | TOTAL TIME(us) | TOTAL AVG(us) | REQUEST | TIME(us) | AVERAGE(us) |\033[0m\n"
|
||||
fmt.Printf(format, seconds/3600, seconds%3600/60, seconds%60)
|
||||
|
||||
tr := current.succeeded + current.failed
|
||||
td := current.succeededDuration + current.failedDuration
|
||||
r := tr - last.succeeded - last.failed
|
||||
d := td - last.succeededDuration - last.failedDuration
|
||||
ta, a := 0.0, 0.0
|
||||
if tr > 0 {
|
||||
ta = float64(td) / float64(tr)
|
||||
}
|
||||
if r > 0 {
|
||||
a = float64(d) / float64(r)
|
||||
}
|
||||
format = " TOTAL | %9v | %14v | %13.2f | %7v | %10v | % 13.2f |\n"
|
||||
fmt.Printf(format, tr, td, ta, r, d, a)
|
||||
|
||||
tr = current.succeeded
|
||||
td = current.succeededDuration
|
||||
r = tr - last.succeeded
|
||||
d = td - last.succeededDuration
|
||||
ta, a = 0.0, 0.0
|
||||
if tr > 0 {
|
||||
ta = float64(td) / float64(tr)
|
||||
}
|
||||
if r > 0 {
|
||||
a = float64(d) / float64(r)
|
||||
}
|
||||
format = " SUCCESS | \033[32m%9v\033[0m | \033[32m%14v\033[0m | \033[32m%13.2f\033[0m | \033[32m%7v\033[0m | \033[32m%10v\033[0m | \033[32m%13.2f\033[0m |\n"
|
||||
fmt.Printf(format, tr, td, ta, r, d, a)
|
||||
|
||||
tr = current.failed
|
||||
td = current.failedDuration
|
||||
r = tr - last.failed
|
||||
d = td - last.failedDuration
|
||||
ta, a = 0.0, 0.0
|
||||
if tr > 0 {
|
||||
ta = float64(td) / float64(tr)
|
||||
}
|
||||
if r > 0 {
|
||||
a = float64(d) / float64(r)
|
||||
}
|
||||
format = " FAIL | \033[31m%9v\033[0m | \033[31m%14v\033[0m | \033[31m%13.2f\033[0m | \033[31m%7v\033[0m | \033[31m%10v\033[0m | \033[31m%13.2f\033[0m |\n"
|
||||
fmt.Printf(format, tr, td, ta, r, d, a)
|
||||
|
||||
last = current
|
||||
lastPrintAt = tm
|
||||
}
|
||||
}
|
||||
|
||||
func startLogger(path string) error {
|
||||
if len(path) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
f, e := os.Create(path)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
chLog = make(chan string, 100)
|
||||
wgLog.Add(1)
|
||||
go func() {
|
||||
for s := range chLog {
|
||||
if f != nil {
|
||||
f.WriteString(s)
|
||||
f.WriteString("\n")
|
||||
}
|
||||
}
|
||||
f.Close()
|
||||
wgLog.Done()
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var concurrency uint
|
||||
var logPath string
|
||||
flag.StringVar(&host, "h", "localhost", "host name or IP address of TDengine server")
|
||||
flag.UintVar(&port, "P", 0, "port (default 0)")
|
||||
flag.StringVar(&database, "d", "test", "database name")
|
||||
flag.StringVar(&user, "u", "root", "user name")
|
||||
flag.StringVar(&password, "p", "taosdata", "password")
|
||||
flag.BoolVar(&fetch, "f", true, "fetch result or not")
|
||||
flag.UintVar(&concurrency, "c", 4, "concurrency, number of goroutines for query")
|
||||
flag.StringVar(&logPath, "l", "", "path of log file (default: no log)")
|
||||
flag.Parse()
|
||||
|
||||
if e := startLogger(logPath); e != nil {
|
||||
fmt.Println("failed to open log file:", e.Error())
|
||||
return
|
||||
}
|
||||
|
||||
pathOrSQL := flag.Arg(0)
|
||||
if len(pathOrSQL) == 0 {
|
||||
pathOrSQL = "cases.json"
|
||||
}
|
||||
if e := loadTestCase(pathOrSQL); e != nil {
|
||||
fmt.Println("failed to load test cases:", e.Error())
|
||||
return
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
fmt.Printf("\nSERVER: %s DATABASE: %s CONCURRENCY: %d FETCH DATA: %v\n\n", host, database, concurrency, fetch)
|
||||
|
||||
startAt = time.Now()
|
||||
printStat := getStatPrinter()
|
||||
printStat(startAt)
|
||||
|
||||
for i := uint(0); i < concurrency; i++ {
|
||||
wgTest.Add(1)
|
||||
go runTest()
|
||||
}
|
||||
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt)
|
||||
ticker := time.NewTicker(time.Second)
|
||||
|
||||
fmt.Println("Ctrl + C to exit....\033[1A")
|
||||
|
||||
LOOP:
|
||||
for {
|
||||
select {
|
||||
case <-interrupt:
|
||||
break LOOP
|
||||
case tm := <-ticker.C:
|
||||
fmt.Print("\033[4A")
|
||||
printStat(tm)
|
||||
}
|
||||
}
|
||||
|
||||
atomic.StoreInt64(&shouldStop, 1)
|
||||
fmt.Print("\033[100D'Ctrl + C' received, Waiting started query to stop...")
|
||||
wgTest.Wait()
|
||||
|
||||
if chLog != nil {
|
||||
close(chLog)
|
||||
wgLog.Wait()
|
||||
}
|
||||
fmt.Print("\033[4A\033[100D")
|
||||
printStat(time.Now())
|
||||
fmt.Println()
|
||||
}
|
Loading…
Reference in New Issue