Merge branch 'develop' into test/testcase
This commit is contained in:
commit
2c97971ef8
|
@ -95,6 +95,7 @@ TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修
|
|||
- logKeepDays:日志文件的最长保存时间。大于0时,日志文件会被重命名为taosdlog.xxx,其中xxx为日志文件最后修改的时间戳,单位为秒。默认值:0天。
|
||||
- maxSQLLength:单条SQL语句允许最长限制。默认值:65380字节。
|
||||
- telemetryReporting: 是否允许 TDengine 采集和上报基本使用信息,0表示不允许,1表示允许。 默认值:1。
|
||||
- stream: 是否启用连续查询(流计算功能),0表示不允许,1表示允许。 默认值:1。
|
||||
|
||||
**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030都6042共13个端口,而且必须TCP和UDP都打开。
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
获取最近一次API调用失败的原因,返回值为错误代码。
|
||||
|
||||
|
||||
**注意**:对于单个数据库连接,在同一时刻只能有一个线程使用该连接调用API,否则会有未定义的行为出现并可能导致客户端crash。客户端应用可以通过建立多个连接进行多线程的数据写入或查询处理。
|
||||
**注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
|
||||
|
||||
|
||||
### 异步查询API
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
# httpDebugFlag 131
|
||||
|
||||
# debug flag for monitor
|
||||
# monitorDebugFlag 131
|
||||
# monDebugFlag 131
|
||||
|
||||
# debug flag for query
|
||||
# qDebugflag 131
|
||||
|
@ -251,7 +251,7 @@
|
|||
# cqDebugFlag 131
|
||||
|
||||
# enable/disable recording the SQL in taos client
|
||||
# tscEnableRecordSql 0
|
||||
# enableRecordSql 0
|
||||
|
||||
# generate core file when service crash
|
||||
# enableCoreFile 1
|
||||
|
@ -261,3 +261,9 @@
|
|||
|
||||
# enable/disable telemetry reporting
|
||||
# telemetryReporting 1
|
||||
|
||||
# enable/disable stream (continuous query)
|
||||
# stream 1
|
||||
|
||||
# only 50% CPU resources will be used in query processing
|
||||
# halfCoresForQuery 0
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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_BALANCE_INT_H
|
||||
#define TDENGINE_BALANCE_INT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mnodeInt.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeDnode.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t size;
|
||||
int32_t maxSize;
|
||||
SDnodeObj **list;
|
||||
} SBnDnodes;
|
||||
|
||||
typedef struct {
|
||||
void * timer;
|
||||
bool stop;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
pthread_t thread;
|
||||
} SBnThread;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
} SBnMgmt;
|
||||
|
||||
int32_t bnInit();
|
||||
void bnCleanUp();
|
||||
bool bnStart();
|
||||
void bnCheckStatus();
|
||||
void bnCheckModules();
|
||||
|
||||
extern SBnDnodes tsBnDnodes;
|
||||
extern void *tsMnodeTmr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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_BALANCE_SCORE_H
|
||||
#define TDENGINE_BALANCE_SCORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "bnInt.h"
|
||||
|
||||
void bnInitDnodes();
|
||||
void bnCleanupDnodes();
|
||||
void bnAccquireDnodes();
|
||||
void bnReleaseDnodes();
|
||||
float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extraVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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_BALANCE_THREAD_H
|
||||
#define TDENGINE_BALANCE_THREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "bnInt.h"
|
||||
|
||||
int32_t bnInitThread();
|
||||
void bnCleanupThread();
|
||||
void bnNotify();
|
||||
void bnStartTimer(int64_t mseconds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -15,17 +15,12 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tutil.h"
|
||||
#include "tbalance.h"
|
||||
#include "tsync.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
#include "tdataformat.h"
|
||||
#include "dnode.h"
|
||||
#include "mnode.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeInt.h"
|
||||
#include "mnodeDnode.h"
|
||||
#include "bnInt.h"
|
||||
#include "bnScore.h"
|
||||
#include "bnThread.h"
|
||||
#include "mnodeDb.h"
|
||||
#include "mnodeMnode.h"
|
||||
#include "mnodeSdb.h"
|
||||
|
@ -33,36 +28,18 @@
|
|||
#include "mnodeUser.h"
|
||||
#include "mnodeVgroup.h"
|
||||
|
||||
/*
|
||||
* once sdb work as mater, then tsAccessSquence reset to zero
|
||||
* increase tsAccessSquence every balance interval
|
||||
*/
|
||||
extern void * tsMnodeTmr;
|
||||
static void * tsBalanceTimer = NULL;
|
||||
static int32_t tsBalanceDnodeListSize = 0;
|
||||
static SDnodeObj ** tsBalanceDnodeList = NULL;
|
||||
static int32_t tsBalanceDnodeListMallocSize = 16;
|
||||
static pthread_mutex_t tsBalanceMutex;
|
||||
static SBnMgmt tsBnMgmt;;
|
||||
static void bnMonitorDnodeModule();
|
||||
|
||||
static void balanceStartTimer(int64_t mseconds);
|
||||
static void balanceInitDnodeList();
|
||||
static void balanceCleanupDnodeList();
|
||||
static void balanceAccquireDnodeList();
|
||||
static void balanceReleaseDnodeList();
|
||||
static void balanceMonitorDnodeModule();
|
||||
static float balanceTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extraVnode);
|
||||
static int32_t balanceGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t balanceRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
static void balanceLock() {
|
||||
pthread_mutex_lock(&tsBalanceMutex);
|
||||
static void bnLock() {
|
||||
pthread_mutex_lock(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
static void balanceUnLock() {
|
||||
pthread_mutex_unlock(&tsBalanceMutex);
|
||||
static void bnUnLock() {
|
||||
pthread_mutex_unlock(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
static bool balanceCheckFree(SDnodeObj *pDnode) {
|
||||
static bool bnCheckFree(SDnodeObj *pDnode) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mError("dnode:%d, status:%s not available", pDnode->dnodeId, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
return false;
|
||||
|
@ -86,7 +63,7 @@ static bool balanceCheckFree(SDnodeObj *pDnode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void balanceDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
||||
static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
||||
mDebug("vgId:%d, dnode:%d is dropping", pVgroup->vgId, pVnodeGid->dnodeId);
|
||||
|
||||
SDnodeObj *pDnode = mnodeGetDnode(pVnodeGid->dnodeId);
|
||||
|
@ -111,27 +88,26 @@ static void balanceDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
|||
mnodeUpdateVgroup(pVgroup);
|
||||
}
|
||||
|
||||
static void balanceSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
static void bnSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
// SVnodeGid tmp = *pVnodeGid1;
|
||||
// *pVnodeGid1 = *pVnodeGid2;
|
||||
// *pVnodeGid2 = tmp;
|
||||
}
|
||||
|
||||
int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||
int32_t bnAllocVnodes(SVgObj *pVgroup) {
|
||||
static int32_t randIndex = 0;
|
||||
int32_t dnode = 0;
|
||||
int32_t vnodes = 0;
|
||||
|
||||
balanceLock();
|
||||
|
||||
balanceAccquireDnodeList();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
mDebug("db:%s, try alloc %d vnodes to vgroup, dnodes total:%d, avail:%d", pVgroup->dbName, pVgroup->numOfVnodes,
|
||||
mnodeGetDnodesNum(), tsBalanceDnodeListSize);
|
||||
mnodeGetDnodesNum(), tsBnDnodes.size);
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
for (; dnode < tsBalanceDnodeListSize; ++dnode) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[dnode];
|
||||
if (balanceCheckFree(pDnode)) {
|
||||
for (; dnode < tsBnDnodes.size; ++dnode) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[dnode];
|
||||
if (bnCheckFree(pDnode)) {
|
||||
SVnodeGid *pVnodeGid = pVgroup->vnodeGid + i;
|
||||
pVnodeGid->dnodeId = pDnode->dnodeId;
|
||||
pVnodeGid->pDnode = pDnode;
|
||||
|
@ -148,8 +124,8 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
|||
}
|
||||
|
||||
if (vnodes != pVgroup->numOfVnodes) {
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
mDebug("db:%s, need vnodes:%d, but alloc:%d", pVgroup->dbName, pVgroup->numOfVnodes, vnodes);
|
||||
|
||||
|
@ -179,33 +155,33 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
|||
if (pVgroup->numOfVnodes == 1) {
|
||||
} else if (pVgroup->numOfVnodes == 2) {
|
||||
if (randIndex++ % 2 == 0) {
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid, pVgroup->vnodeGid + 1);
|
||||
}
|
||||
} else {
|
||||
int32_t randVal = randIndex++ % 6;
|
||||
if (randVal == 1) { // 1, 0, 2
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
} else if (randVal == 2) { // 1, 2, 0
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
} else if (randVal == 3) { // 2, 1, 0
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
} else if (randVal == 4) { // 2, 0, 1
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
}
|
||||
if (randVal == 5) { // 0, 2, 1
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
} else {
|
||||
} // 0, 1, 2
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool balanceCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
||||
static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
||||
if (pVgroup->lbTime + 5 * tsStatusInterval > tsAccessSquence) {
|
||||
return false;
|
||||
}
|
||||
|
@ -232,7 +208,7 @@ static bool balanceCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
|||
* desc: remove one vnode from vgroup
|
||||
* all vnodes in vgroup should in ready state, except the balancing one
|
||||
**/
|
||||
static int32_t balanceRemoveVnode(SVgObj *pVgroup) {
|
||||
static int32_t bnRemoveVnode(SVgObj *pVgroup) {
|
||||
if (pVgroup->numOfVnodes <= 1) return -1;
|
||||
|
||||
SVnodeGid *pRmVnode = NULL;
|
||||
|
@ -274,17 +250,17 @@ static int32_t balanceRemoveVnode(SVgObj *pVgroup) {
|
|||
pSelVnode = pRmVnode;
|
||||
}
|
||||
|
||||
if (!balanceCheckVgroupReady(pVgroup, pSelVnode)) {
|
||||
if (!bnCheckVgroupReady(pVgroup, pSelVnode)) {
|
||||
mDebug("vgId:%d, is not ready", pVgroup->vgId);
|
||||
return -1;
|
||||
} else {
|
||||
mDebug("vgId:%d, is ready, discard dnode:%d", pVgroup->vgId, pSelVnode->dnodeId);
|
||||
balanceDiscardVnode(pVgroup, pSelVnode);
|
||||
bnDiscardVnode(pVgroup, pSelVnode);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static bool balanceCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
||||
static bool bnCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SVnodeGid *pGid = &pVgroup->vnodeGid[i];
|
||||
if (pGid->dnodeId == 0) break;
|
||||
|
@ -299,13 +275,13 @@ static bool balanceCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
|||
/**
|
||||
* desc: add vnode to vgroup, find a new one if dest dnode is null
|
||||
**/
|
||||
static int32_t balanceAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDestDnode) {
|
||||
static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDestDnode) {
|
||||
if (pDestDnode == NULL) {
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode == pSrcDnode) continue;
|
||||
if (balanceCheckDnodeInVgroup(pDnode, pVgroup)) continue;
|
||||
if (!balanceCheckFree(pDnode)) continue;
|
||||
if (bnCheckDnodeInVgroup(pDnode, pVgroup)) continue;
|
||||
if (!bnCheckFree(pDnode)) continue;
|
||||
|
||||
pDestDnode = pDnode;
|
||||
mDebug("vgId:%d, add vnode to dnode:%d", pVgroup->vgId, pDnode->dnodeId);
|
||||
|
@ -333,25 +309,25 @@ static int32_t balanceAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool balanceMonitorBalance() {
|
||||
if (tsBalanceDnodeListSize < 2) return false;
|
||||
static bool bnMonitorBalance() {
|
||||
if (tsBnDnodes.size < 2) return false;
|
||||
|
||||
for (int32_t src = tsBalanceDnodeListSize - 1; src >= 0; --src) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[src];
|
||||
mDebug("%d-dnode:%d, state:%s, score:%.1f, numOfCores:%d, openVnodes:%d", tsBalanceDnodeListSize - src - 1,
|
||||
for (int32_t src = tsBnDnodes.size - 1; src >= 0; --src) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[src];
|
||||
mDebug("%d-dnode:%d, state:%s, score:%.1f, numOfCores:%d, openVnodes:%d", tsBnDnodes.size - src - 1,
|
||||
pDnode->dnodeId, mnodeGetDnodeStatusStr(pDnode->status), pDnode->score, pDnode->numOfCores,
|
||||
pDnode->openVnodes);
|
||||
}
|
||||
|
||||
float scoresDiff = tsBalanceDnodeList[tsBalanceDnodeListSize - 1]->score - tsBalanceDnodeList[0]->score;
|
||||
float scoresDiff = tsBnDnodes.list[tsBnDnodes.size - 1]->score - tsBnDnodes.list[0]->score;
|
||||
if (scoresDiff < 0.01) {
|
||||
mDebug("all dnodes:%d is already balanced, scoresDiff:%f", tsBalanceDnodeListSize, scoresDiff);
|
||||
mDebug("all dnodes:%d is already balanced, scoresDiff:%f", tsBnDnodes.size, scoresDiff);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t src = tsBalanceDnodeListSize - 1; src > 0; --src) {
|
||||
SDnodeObj *pSrcDnode = tsBalanceDnodeList[src];
|
||||
float srcScore = balanceTryCalcDnodeScore(pSrcDnode, -1);
|
||||
for (int32_t src = tsBnDnodes.size - 1; src > 0; --src) {
|
||||
SDnodeObj *pSrcDnode = tsBnDnodes.list[src];
|
||||
float srcScore = bnTryCalcDnodeScore(pSrcDnode, -1);
|
||||
if (tsEnableBalance == 0 && pSrcDnode->status != TAOS_DN_STATUS_DROPPING) {
|
||||
continue;
|
||||
}
|
||||
|
@ -362,19 +338,19 @@ static bool balanceMonitorBalance() {
|
|||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
if (balanceCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
if (bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
for (int32_t dest = 0; dest < src; dest++) {
|
||||
SDnodeObj *pDestDnode = tsBalanceDnodeList[dest];
|
||||
if (balanceCheckDnodeInVgroup(pDestDnode, pVgroup)) continue;
|
||||
SDnodeObj *pDestDnode = tsBnDnodes.list[dest];
|
||||
if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) continue;
|
||||
|
||||
float destScore = balanceTryCalcDnodeScore(pDestDnode, 1);
|
||||
float destScore = bnTryCalcDnodeScore(pDestDnode, 1);
|
||||
if (srcScore + 0.0001 < destScore) continue;
|
||||
if (!balanceCheckFree(pDestDnode)) continue;
|
||||
if (!bnCheckFree(pDestDnode)) continue;
|
||||
|
||||
mDebug("vgId:%d, balance from dnode:%d to dnode:%d, srcScore:%.1f:%.1f, destScore:%.1f:%.1f",
|
||||
pVgroup->vgId, pSrcDnode->dnodeId, pDestDnode->dnodeId, pSrcDnode->score,
|
||||
srcScore, pDestDnode->score, destScore);
|
||||
balanceAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
bnAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
mnodeCancelGetNextVgroup(pIter);
|
||||
return true;
|
||||
|
@ -392,7 +368,7 @@ static bool balanceMonitorBalance() {
|
|||
// 1. reset balanceAccessSquence to zero
|
||||
// 2. reset state of dnodes to offline
|
||||
// 3. reset lastAccess of dnodes to zero
|
||||
void balanceReset() {
|
||||
void bnReset() {
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
while (1) {
|
||||
|
@ -413,7 +389,7 @@ void balanceReset() {
|
|||
tsAccessSquence = 0;
|
||||
}
|
||||
|
||||
static int32_t balanceMonitorVgroups() {
|
||||
static int32_t bnMonitorVgroups() {
|
||||
void * pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
bool hasUpdatingVgroup = false;
|
||||
|
@ -429,11 +405,11 @@ static int32_t balanceMonitorVgroups() {
|
|||
if (vgReplica > dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try remove one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
code = balanceRemoveVnode(pVgroup);
|
||||
code = bnRemoveVnode(pVgroup);
|
||||
} else if (vgReplica < dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try add one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
code = balanceAddVnode(pVgroup, NULL, NULL);
|
||||
code = bnAddVnode(pVgroup, NULL, NULL);
|
||||
}
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
|
@ -446,7 +422,7 @@ static int32_t balanceMonitorVgroups() {
|
|||
return hasUpdatingVgroup;
|
||||
}
|
||||
|
||||
static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
||||
static bool bnMonitorDnodeDropping(SDnodeObj *pDnode) {
|
||||
mDebug("dnode:%d, in dropping state", pDnode->dnodeId);
|
||||
|
||||
void * pIter = NULL;
|
||||
|
@ -456,7 +432,7 @@ static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
|||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
hasThisDnode = balanceCheckDnodeInVgroup(pDnode, pVgroup);
|
||||
hasThisDnode = bnCheckDnodeInVgroup(pDnode, pVgroup);
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
|
||||
if (hasThisDnode) {
|
||||
|
@ -474,7 +450,7 @@ static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool balanceMontiorDropping() {
|
||||
static bool bnMontiorDropping() {
|
||||
void *pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
||||
|
@ -499,7 +475,7 @@ static bool balanceMontiorDropping() {
|
|||
}
|
||||
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING) {
|
||||
bool ret = balanceMonitorDnodeDropping(pDnode);
|
||||
bool ret = bnMonitorDnodeDropping(pDnode);
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
return ret;
|
||||
|
@ -509,33 +485,31 @@ static bool balanceMontiorDropping() {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool balanceStart() {
|
||||
bool bnStart() {
|
||||
if (!sdbIsMaster()) return false;
|
||||
|
||||
balanceLock();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
balanceAccquireDnodeList();
|
||||
bnMonitorDnodeModule();
|
||||
|
||||
balanceMonitorDnodeModule();
|
||||
|
||||
bool updateSoon = balanceMontiorDropping();
|
||||
bool updateSoon = bnMontiorDropping();
|
||||
|
||||
if (!updateSoon) {
|
||||
updateSoon = balanceMonitorVgroups();
|
||||
updateSoon = bnMonitorVgroups();
|
||||
}
|
||||
|
||||
if (!updateSoon) {
|
||||
updateSoon = balanceMonitorBalance();
|
||||
updateSoon = bnMonitorBalance();
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
return updateSoon;
|
||||
}
|
||||
|
||||
static void balanceSetVgroupOffline(SDnodeObj* pDnode) {
|
||||
static void bnSetVgroupOffline(SDnodeObj* pDnode) {
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SVgObj *pVgroup;
|
||||
|
@ -551,7 +525,7 @@ static void balanceSetVgroupOffline(SDnodeObj* pDnode) {
|
|||
}
|
||||
}
|
||||
|
||||
static void balanceCheckDnodeAccess() {
|
||||
void bnCheckStatus() {
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
||||
|
@ -564,84 +538,39 @@ static void balanceCheckDnodeAccess() {
|
|||
pDnode->offlineReason = TAOS_DN_OFF_STATUS_MSG_TIMEOUT;
|
||||
mInfo("dnode:%d, set to offline state, access seq:%d last seq:%d laststat:%d", pDnode->dnodeId, tsAccessSquence,
|
||||
pDnode->lastAccess, pDnode->status);
|
||||
balanceSetVgroupOffline(pDnode);
|
||||
bnSetVgroupOffline(pDnode);
|
||||
}
|
||||
}
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
}
|
||||
|
||||
static void balanceProcessBalanceTimer(void *handle, void *tmrId) {
|
||||
if (!sdbIsMaster()) return;
|
||||
|
||||
tsBalanceTimer = NULL;
|
||||
tsAccessSquence ++;
|
||||
|
||||
balanceCheckDnodeAccess();
|
||||
bool updateSoon = false;
|
||||
|
||||
if (handle == NULL) {
|
||||
if (tsAccessSquence % tsBalanceInterval == 0) {
|
||||
mDebug("balance function is scheduled by timer");
|
||||
updateSoon = balanceStart();
|
||||
}
|
||||
} else {
|
||||
int64_t mseconds = (int64_t)handle;
|
||||
mDebug("balance function is scheduled by event for %" PRId64 " mseconds arrived", mseconds);
|
||||
updateSoon = balanceStart();
|
||||
}
|
||||
|
||||
if (updateSoon) {
|
||||
balanceStartTimer(1000);
|
||||
} else {
|
||||
taosTmrReset(balanceProcessBalanceTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBalanceTimer);
|
||||
}
|
||||
}
|
||||
|
||||
static void balanceStartTimer(int64_t mseconds) {
|
||||
taosTmrReset(balanceProcessBalanceTimer, mseconds, (void *)mseconds, tsMnodeTmr, &tsBalanceTimer);
|
||||
}
|
||||
|
||||
void balanceSyncNotify() {
|
||||
void bnCheckModules() {
|
||||
if (sdbIsMaster()) {
|
||||
balanceLock();
|
||||
balanceAccquireDnodeList();
|
||||
balanceMonitorDnodeModule();
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
bnMonitorDnodeModule();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
}
|
||||
}
|
||||
|
||||
void balanceAsyncNotify() {
|
||||
balanceStartTimer(500);
|
||||
}
|
||||
|
||||
int32_t balanceInit() {
|
||||
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_SCORES, balanceGetScoresMeta);
|
||||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_SCORES, balanceRetrieveScores);
|
||||
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_SCORES, mnodeCancelGetNextDnode);
|
||||
|
||||
pthread_mutex_init(&tsBalanceMutex, NULL);
|
||||
balanceInitDnodeList();
|
||||
balanceStartTimer(2000);
|
||||
mDebug("balance start fp:%p initialized", balanceProcessBalanceTimer);
|
||||
|
||||
balanceReset();
|
||||
int32_t bnInit() {
|
||||
pthread_mutex_init(&tsBnMgmt.mutex, NULL);
|
||||
bnInitDnodes();
|
||||
bnInitThread();
|
||||
bnReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void balanceCleanUp() {
|
||||
if (tsBalanceTimer != NULL) {
|
||||
taosTmrStopA(&tsBalanceTimer);
|
||||
pthread_mutex_destroy(&tsBalanceMutex);
|
||||
tsBalanceTimer = NULL;
|
||||
mDebug("stop balance timer");
|
||||
}
|
||||
balanceCleanupDnodeList();
|
||||
void bnCleanUp() {
|
||||
bnCleanupThread();
|
||||
bnCleanupDnodes();
|
||||
pthread_mutex_destroy(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
||||
int32_t bnDropDnode(SDnodeObj *pDnode) {
|
||||
int32_t totalFreeVnodes = 0;
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pTempDnode = NULL;
|
||||
|
@ -650,7 +579,7 @@ int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
|||
pIter = mnodeGetNextDnode(pIter, &pTempDnode);
|
||||
if (pTempDnode == NULL) break;
|
||||
|
||||
if (pTempDnode != pDnode && balanceCheckFree(pTempDnode)) {
|
||||
if (pTempDnode != pDnode && bnCheckFree(pTempDnode)) {
|
||||
totalFreeVnodes += (TSDB_MAX_VNODES - pTempDnode->openVnodes);
|
||||
}
|
||||
|
||||
|
@ -665,298 +594,17 @@ int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
|||
pDnode->status = TAOS_DN_STATUS_DROPPING;
|
||||
mnodeUpdateDnode(pDnode);
|
||||
|
||||
balanceStartTimer(1100);
|
||||
bnStartTimer(1100);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcCpuScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->cpuAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->cpuAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcMemoryScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->memoryAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->memoryAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcDiskScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->diskAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->diskAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcBandwidthScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->bandwidthUsage < 30)
|
||||
return 0;
|
||||
else if (pDnode->bandwidthUsage < 80)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static float balanceCalcModuleScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
if (pDnode->isMgmt) {
|
||||
return (float)tsMnodeEqualVnodeNum / pDnode->numOfCores;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float balanceCalcVnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) return 100000000;
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
return (float)(pDnode->openVnodes + extra) / pDnode->numOfCores;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc singe score, such as cpu/memory/disk/bandwitdh/vnode
|
||||
* 1. get the score config
|
||||
* 2. if the value is out of range, use border data
|
||||
* 3. otherwise use interpolation method
|
||||
**/
|
||||
void balanceCalcDnodeScore(SDnodeObj *pDnode) {
|
||||
pDnode->score = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode) + balanceCalcModuleScore(pDnode) +
|
||||
balanceCalcVnodeScore(pDnode, 0) + pDnode->customScore;
|
||||
}
|
||||
|
||||
float balanceTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
int32_t systemScore = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode);
|
||||
float moduleScore = balanceCalcModuleScore(pDnode);
|
||||
float vnodeScore = balanceCalcVnodeScore(pDnode, extra);
|
||||
|
||||
float score = systemScore + moduleScore + vnodeScore + pDnode->customScore;
|
||||
return score;
|
||||
}
|
||||
|
||||
static void balanceInitDnodeList() {
|
||||
tsBalanceDnodeList = calloc(tsBalanceDnodeListMallocSize, sizeof(SDnodeObj *));
|
||||
}
|
||||
|
||||
static void balanceCleanupDnodeList() {
|
||||
if (tsBalanceDnodeList != NULL) {
|
||||
free(tsBalanceDnodeList);
|
||||
tsBalanceDnodeList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void balanceCheckDnodeListSize(int32_t dnodesNum) {
|
||||
if (tsBalanceDnodeListMallocSize <= dnodesNum) {
|
||||
tsBalanceDnodeListMallocSize = dnodesNum * 2;
|
||||
tsBalanceDnodeList = realloc(tsBalanceDnodeList, tsBalanceDnodeListMallocSize * sizeof(SDnodeObj *));
|
||||
}
|
||||
}
|
||||
|
||||
void balanceAccquireDnodeList() {
|
||||
int32_t dnodesNum = mnodeGetDnodesNum();
|
||||
balanceCheckDnodeListSize(dnodesNum);
|
||||
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
int32_t dnodeIndex = 0;
|
||||
|
||||
while (1) {
|
||||
if (dnodeIndex >= dnodesNum) {
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
break;
|
||||
}
|
||||
|
||||
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
balanceCalcDnodeScore(pDnode);
|
||||
|
||||
int32_t orderIndex = dnodeIndex;
|
||||
for (; orderIndex > 0; --orderIndex) {
|
||||
if (pDnode->score > tsBalanceDnodeList[orderIndex - 1]->score) {
|
||||
break;
|
||||
}
|
||||
tsBalanceDnodeList[orderIndex] = tsBalanceDnodeList[orderIndex - 1];
|
||||
}
|
||||
tsBalanceDnodeList[orderIndex] = pDnode;
|
||||
dnodeIndex++;
|
||||
}
|
||||
|
||||
tsBalanceDnodeListSize = dnodeIndex;
|
||||
}
|
||||
|
||||
void balanceReleaseDnodeList() {
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
if (pDnode != NULL) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t balanceGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||
if (pUser == NULL) return 0;
|
||||
|
||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
||||
mnodeDecUserRef(pUser);
|
||||
return TSDB_CODE_MND_NO_RIGHTS;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->schema;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "id");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "system scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "custom scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "module scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "vnode scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "total scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "open vnodes");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "cpu cores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 18 + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "balance state");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mnodeGetDnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pIter = NULL;
|
||||
|
||||
mnodeDecUserRef(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t balanceRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
int32_t cols = 0;
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = mnodeGetNextDnode(pShow->pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
int32_t systemScore = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode);
|
||||
float moduleScore = balanceCalcModuleScore(pDnode);
|
||||
float vnodeScore = balanceCalcVnodeScore(pDnode, 0);
|
||||
|
||||
cols = 0;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pDnode->dnodeId;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = systemScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = pDnode->customScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)moduleScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)vnodeScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)(vnodeScore + moduleScore + pDnode->customScore + systemScore);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->openVnodes;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->numOfCores;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void balanceMonitorDnodeModule() {
|
||||
static void bnMonitorDnodeModule() {
|
||||
int32_t numOfMnodes = mnodeGetMnodesNum();
|
||||
if (numOfMnodes >= tsNumOfMnodes) return;
|
||||
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
if (pDnode->isMgmt || pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
|
@ -980,7 +628,7 @@ static void balanceMonitorDnodeModule() {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t balanceAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnodeId) {
|
||||
int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnodeId) {
|
||||
if (!sdbIsMaster()) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for self not master", pSrcDnode->dnodeId, vnodeId, dnodeId);
|
||||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
|
@ -1004,29 +652,29 @@ int32_t balanceAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t
|
|||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
balanceLock();
|
||||
balanceAccquireDnodeList();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (!balanceCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
if (!bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup not in dnode:%d", pSrcDnode->dnodeId, vnodeId,
|
||||
dnodeId, pSrcDnode->dnodeId);
|
||||
code = TSDB_CODE_MND_VGROUP_NOT_IN_DNODE;
|
||||
} else if (balanceCheckDnodeInVgroup(pDestDnode, pVgroup)) {
|
||||
} else if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup already in dnode:%d", pSrcDnode->dnodeId, vnodeId,
|
||||
dnodeId, dnodeId);
|
||||
code = TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE;
|
||||
} else if (!balanceCheckFree(pDestDnode)) {
|
||||
} else if (!bnCheckFree(pDestDnode)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for dnode:%d not free", pSrcDnode->dnodeId, vnodeId, dnodeId,
|
||||
dnodeId);
|
||||
code = TSDB_CODE_MND_DNODE_NOT_FREE;
|
||||
} else {
|
||||
code = balanceAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
code = bnAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
mInfo("dnode:%d, alter vgId:%d to dnode:%d, result:%s", pSrcDnode->dnodeId, vnodeId, dnodeId, tstrerror(code));
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
mnodeDecDnodeRef(pDestDnode);
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnodeShow.h"
|
||||
#include "mnodeUser.h"
|
||||
#include "bnScore.h"
|
||||
|
||||
SBnDnodes tsBnDnodes;
|
||||
|
||||
static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
static int32_t bnCalcCpuScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->cpuAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->cpuAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcMemoryScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->memoryAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->memoryAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcDiskScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->diskAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->diskAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcBandScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->bandwidthUsage < 30)
|
||||
return 0;
|
||||
else if (pDnode->bandwidthUsage < 80)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static float bnCalcModuleScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
if (pDnode->isMgmt) {
|
||||
return (float)tsMnodeEqualVnodeNum / pDnode->numOfCores;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float bnCalcVnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) return 100000000;
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
return (float)(pDnode->openVnodes + extra) / pDnode->numOfCores;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc singe score, such as cpu/memory/disk/bandwitdh/vnode
|
||||
* 1. get the score config
|
||||
* 2. if the value is out of range, use border data
|
||||
* 3. otherwise use interpolation method
|
||||
**/
|
||||
static void bnCalcDnodeScore(SDnodeObj *pDnode) {
|
||||
pDnode->score = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) +
|
||||
bnCalcBandScore(pDnode) + bnCalcModuleScore(pDnode) + bnCalcVnodeScore(pDnode, 0) +
|
||||
pDnode->customScore;
|
||||
}
|
||||
|
||||
float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) +
|
||||
bnCalcBandScore(pDnode);
|
||||
float moduleScore = bnCalcModuleScore(pDnode);
|
||||
float vnodeScore = bnCalcVnodeScore(pDnode, extra);
|
||||
|
||||
float score = systemScore + moduleScore + vnodeScore + pDnode->customScore;
|
||||
return score;
|
||||
}
|
||||
|
||||
void bnInitDnodes() {
|
||||
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_SCORES, bnGetScoresMeta);
|
||||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_SCORES, bnRetrieveScores);
|
||||
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_SCORES, mnodeCancelGetNextDnode);
|
||||
|
||||
memset(&tsBnDnodes, 0, sizeof(SBnDnodes));
|
||||
tsBnDnodes.maxSize = 16;
|
||||
tsBnDnodes.list = calloc(tsBnDnodes.maxSize, sizeof(SDnodeObj *));
|
||||
}
|
||||
|
||||
void bnCleanupDnodes() {
|
||||
if (tsBnDnodes.list != NULL) {
|
||||
free(tsBnDnodes.list);
|
||||
tsBnDnodes.list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void bnCheckDnodesSize(int32_t dnodesNum) {
|
||||
if (tsBnDnodes.maxSize <= dnodesNum) {
|
||||
tsBnDnodes.maxSize = dnodesNum * 2;
|
||||
tsBnDnodes.list = realloc(tsBnDnodes.list, tsBnDnodes.maxSize * sizeof(SDnodeObj *));
|
||||
}
|
||||
}
|
||||
|
||||
void bnAccquireDnodes() {
|
||||
int32_t dnodesNum = mnodeGetDnodesNum();
|
||||
bnCheckDnodesSize(dnodesNum);
|
||||
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
int32_t dnodeIndex = 0;
|
||||
|
||||
while (1) {
|
||||
if (dnodeIndex >= dnodesNum) {
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
break;
|
||||
}
|
||||
|
||||
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
bnCalcDnodeScore(pDnode);
|
||||
|
||||
int32_t orderIndex = dnodeIndex;
|
||||
for (; orderIndex > 0; --orderIndex) {
|
||||
if (pDnode->score > tsBnDnodes.list[orderIndex - 1]->score) {
|
||||
break;
|
||||
}
|
||||
tsBnDnodes.list[orderIndex] = tsBnDnodes.list[orderIndex - 1];
|
||||
}
|
||||
tsBnDnodes.list[orderIndex] = pDnode;
|
||||
dnodeIndex++;
|
||||
}
|
||||
|
||||
tsBnDnodes.size = dnodeIndex;
|
||||
}
|
||||
|
||||
void bnReleaseDnodes() {
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode != NULL) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||
if (pUser == NULL) return 0;
|
||||
|
||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
||||
mnodeDecUserRef(pUser);
|
||||
return TSDB_CODE_MND_NO_RIGHTS;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->schema;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "id");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "system scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "custom scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "module scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "vnode scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "total scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "open vnodes");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "cpu cores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 18 + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "balance state");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mnodeGetDnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pIter = NULL;
|
||||
|
||||
mnodeDecUserRef(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
int32_t cols = 0;
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = mnodeGetNextDnode(pShow->pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) + bnCalcBandScore(pDnode);
|
||||
float moduleScore = bnCalcModuleScore(pDnode);
|
||||
float vnodeScore = bnCalcVnodeScore(pDnode, 0);
|
||||
|
||||
cols = 0;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pDnode->dnodeId;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = systemScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = pDnode->customScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)moduleScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)vnodeScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)(vnodeScore + moduleScore + pDnode->customScore + systemScore);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->openVnodes;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->numOfCores;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnodeSdb.h"
|
||||
#include "bnThread.h"
|
||||
|
||||
static SBnThread tsBnThread;
|
||||
|
||||
static void *bnThreadFunc(void *arg) {
|
||||
while (1) {
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
if (tsBnThread.stop) {
|
||||
pthread_mutex_unlock(&tsBnThread.mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_cond_wait(&tsBnThread.cond, &tsBnThread.mutex);
|
||||
bool updateSoon = bnStart();
|
||||
bnStartTimer(updateSoon ? 1000 : -1);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
}
|
||||
|
||||
mDebug("balance thread is stopped");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t bnInitThread() {
|
||||
memset(&tsBnThread, 0, sizeof(SBnThread));
|
||||
tsBnThread.stop = false;
|
||||
pthread_mutex_init(&tsBnThread.mutex, NULL);
|
||||
pthread_cond_init(&tsBnThread.cond, NULL);
|
||||
|
||||
pthread_attr_t thattr;
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||
int32_t ret = pthread_create(&tsBnThread.thread, &thattr, bnThreadFunc, NULL);
|
||||
pthread_attr_destroy(&thattr);
|
||||
|
||||
if (ret != 0) {
|
||||
mError("failed to create balance thread since %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bnStartTimer(2000);
|
||||
mDebug("balance thread is created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bnCleanupThread() {
|
||||
mDebug("balance thread will be cleanup");
|
||||
|
||||
if (tsBnThread.timer != NULL) {
|
||||
taosTmrStopA(&tsBnThread.timer);
|
||||
tsBnThread.timer = NULL;
|
||||
mDebug("stop balance timer");
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
tsBnThread.stop = true;
|
||||
pthread_cond_signal(&tsBnThread.cond);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
pthread_join(tsBnThread.thread, NULL);
|
||||
|
||||
pthread_cond_destroy(&tsBnThread.cond);
|
||||
pthread_mutex_destroy(&tsBnThread.mutex);
|
||||
}
|
||||
|
||||
static void bnPostSignal() {
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
pthread_cond_signal(&tsBnThread.cond);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
}
|
||||
|
||||
/*
|
||||
* once sdb work as mater, then tsAccessSquence reset to zero
|
||||
* increase tsAccessSquence every balance interval
|
||||
*/
|
||||
|
||||
static void bnProcessTimer(void *handle, void *tmrId) {
|
||||
if (!sdbIsMaster()) return;
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
tsBnThread.timer = NULL;
|
||||
tsAccessSquence++;
|
||||
|
||||
bnCheckStatus();
|
||||
bnStartTimer(-1);
|
||||
|
||||
if (handle == NULL) {
|
||||
if (tsAccessSquence % tsBalanceInterval == 0) {
|
||||
mDebug("balance function is scheduled by timer");
|
||||
bnPostSignal();
|
||||
}
|
||||
} else {
|
||||
int64_t mseconds = (int64_t)handle;
|
||||
mDebug("balance function is scheduled by event for %" PRId64 " mseconds arrived", mseconds);
|
||||
bnPostSignal();
|
||||
}
|
||||
}
|
||||
|
||||
void bnStartTimer(int64_t mseconds) {
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
bool updateSoon = (mseconds != -1);
|
||||
if (updateSoon) {
|
||||
taosTmrReset(bnProcessTimer, mseconds, (void *)mseconds, tsMnodeTmr, &tsBnThread.timer);
|
||||
} else {
|
||||
taosTmrReset(bnProcessTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBnThread.timer);
|
||||
}
|
||||
}
|
||||
|
||||
void bnNotify() {
|
||||
bnStartTimer(500);
|
||||
}
|
|
@ -250,7 +250,10 @@ typedef struct SQueryInfo {
|
|||
int64_t * fillVal; // default value for fill
|
||||
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
||||
int64_t clauseLimit; // limit for current sub clause
|
||||
|
||||
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
|
||||
int64_t tableLimit; // table limit in case of super table projection query + global order + limit
|
||||
|
||||
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
||||
int16_t resColumnId; // result column id
|
||||
} SQueryInfo;
|
||||
|
|
|
@ -426,8 +426,7 @@ static void count_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
}
|
||||
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
|
||||
*((int64_t *)pCtx->aOutputBuf) += 1;
|
||||
*((int64_t *)pCtx->aOutputBuf) += pCtx->size;
|
||||
|
||||
// do not need it actually
|
||||
SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
|
||||
|
@ -3632,114 +3631,119 @@ static bool twa_function_setup(SQLFunctionCtx *pCtx) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) {
|
||||
static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t tsIndex, int32_t index, int32_t size) {
|
||||
int32_t notNullElems = 0;
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
int32_t i = index;
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
assert(pCtx->start.key < primaryKey[index] && pInfo->lastKey == INT64_MIN);
|
||||
assert((pCtx->start.key < primaryKey[tsIndex + i] && pCtx->order == TSDB_ORDER_ASC) ||
|
||||
(pCtx->start.key > primaryKey[tsIndex + i] && pCtx->order == TSDB_ORDER_DESC));
|
||||
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, 0));
|
||||
assert(pInfo->lastKey == INT64_MIN);
|
||||
|
||||
pInfo->lastKey = primaryKey[tsIndex + i];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->start.val) / 2) * (pInfo->lastKey - pCtx->start.key);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
i += step;
|
||||
} else if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, 0));
|
||||
pInfo->lastKey = primaryKey[tsIndex + i];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pInfo->lastKey;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
i += step;
|
||||
}
|
||||
|
||||
// calculate the value of
|
||||
switch(pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = (double) val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i] - pInfo->lastKey);
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3764,16 +3768,13 @@ static void twa_function(SQLFunctionCtx *pCtx) {
|
|||
STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
// skip null value
|
||||
int32_t i = 0;
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||
int32_t i = (pCtx->order == TSDB_ORDER_ASC)? 0:(pCtx->size - 1);
|
||||
while (pCtx->hasNull && i < pCtx->size && isNull((char *)data + pCtx->inputBytes * i, pCtx->inputType)) {
|
||||
i++;
|
||||
i += step;
|
||||
}
|
||||
|
||||
if (i >= pCtx->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t notNullElems = twa_function_impl(pCtx, pCtx->startOffset, pCtx->size);
|
||||
int32_t notNullElems = twa_function_impl(pCtx, pCtx->startOffset, i, pCtx->size);
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (notNullElems > 0) {
|
||||
|
@ -3791,11 +3792,136 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t notNullElems = twa_function_impl(pCtx, index, 1);
|
||||
int32_t notNullElems = 0;
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
int32_t i = pCtx->startOffset;
|
||||
int32_t size = pCtx->size;
|
||||
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
assert(pInfo->lastKey == INT64_MIN);
|
||||
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->start.val) / 2) * (pInfo->lastKey - pCtx->start.key);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
} else if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pInfo->lastKey;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// calculate the value of
|
||||
switch(pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = (double) val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
// the last interpolated time window value
|
||||
if (pCtx->end.key != INT64_MIN) {
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->end.val) / 2) * (pCtx->end.key - pInfo->lastKey);
|
||||
pInfo->lastValue = pCtx->end.val;
|
||||
pInfo->lastKey = pCtx->end.key;
|
||||
}
|
||||
|
||||
pInfo->win.ekey = pInfo->lastKey;
|
||||
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (notNullElems > 0) {
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
if (pCtx->stableQuery) {
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -721,10 +721,16 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
|
||||
// final result depends on the fields number
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
SSchema *p1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
SSchema p1 = {0};
|
||||
if (pExpr->colInfo.colIndex != TSDB_TBNAME_COLUMN_INDEX) {
|
||||
p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
} else {
|
||||
p1 = tGetTableNameColumnSchema();
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t type = -1;
|
||||
|
@ -743,7 +749,8 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
functionId = TSDB_FUNC_LAST;
|
||||
}
|
||||
|
||||
getResultDataInfo(p1->type, p1->bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
pSchema[i].type = (uint8_t)type;
|
||||
|
|
|
@ -630,11 +630,17 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||
static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||
pBlocks->tid = pTableMeta->id.tid;
|
||||
pBlocks->uid = pTableMeta->id.uid;
|
||||
pBlocks->sversion = pTableMeta->sversion;
|
||||
|
||||
if (pBlocks->numOfRows + numOfRows >= INT16_MAX) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
} else {
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// data block is disordered, sort it in ascending order
|
||||
|
@ -722,7 +728,11 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableList, char **st
|
|||
}
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(dataBuf->pData);
|
||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", *str);
|
||||
return code;
|
||||
}
|
||||
|
||||
dataBuf->vgId = pTableMeta->vgroupInfo.vgId;
|
||||
dataBuf->numOfTables = 1;
|
||||
|
@ -1384,7 +1394,10 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData);
|
||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", NULL);
|
||||
}
|
||||
|
||||
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
|
|
@ -39,6 +39,7 @@ void tscInitConnCb(void *param, TAOS_RES *result, int code) {
|
|||
tscSlowQueryConnInitialized = true;
|
||||
tscSaveSlowQueryFp(sql, NULL);
|
||||
}
|
||||
taos_free_result(result);
|
||||
}
|
||||
|
||||
void tscAddIntoSqlList(SSqlObj *pSql) {
|
||||
|
@ -69,6 +70,7 @@ void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) {
|
|||
} else {
|
||||
tscDebug("success to save slow query, code:%d", code);
|
||||
}
|
||||
taos_free_result(result);
|
||||
}
|
||||
|
||||
void tscSaveSlowQueryFp(void *handle, void *tmrId) {
|
||||
|
|
|
@ -5103,7 +5103,7 @@ int32_t validateDNodeConfig(tDCLSQL* pOptions) {
|
|||
const int tokenDebugFlagEnd = 20;
|
||||
const SDNodeDynConfOption cfgOptions[] = {
|
||||
{"resetLog", 8}, {"resetQueryCache", 15}, {"balance", 7}, {"monitor", 7},
|
||||
{"debugFlag", 9}, {"monitorDebugFlag", 16}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
|
||||
{"debugFlag", 9}, {"monDebugFlag", 12}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
|
||||
{"cDebugFlag", 10}, {"httpDebugFlag", 13}, {"qDebugflag", 10}, {"sdbDebugFlag", 12},
|
||||
{"uDebugFlag", 10}, {"tsdbDebugFlag", 13}, {"sDebugflag", 10}, {"rpcDebugFlag", 12},
|
||||
{"dDebugFlag", 10}, {"mqttDebugFlag", 13}, {"wDebugFlag", 10}, {"tmrDebugFlag", 12},
|
||||
|
@ -5308,14 +5308,17 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
|||
// keep original limitation value in globalLimit
|
||||
pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
|
||||
pQueryInfo->prjOffset = pQueryInfo->limit.offset;
|
||||
pQueryInfo->tableLimit = -1;
|
||||
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
/*
|
||||
* the limitation/offset value should be removed during retrieve data from virtual node,
|
||||
* since the global order are done in client side, so the limitation should also
|
||||
* be done at the client side.
|
||||
* the offset value should be removed during retrieve data from virtual node, since the
|
||||
* global order are done in client side, so the offset is applied at the client side
|
||||
* However, note that the maximum allowed number of result for each table should be less
|
||||
* than or equal to the value of limit.
|
||||
*/
|
||||
if (pQueryInfo->limit.limit > 0) {
|
||||
pQueryInfo->tableLimit = pQueryInfo->limit.limit + pQueryInfo->limit.offset;
|
||||
pQueryInfo->limit.limit = -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -684,6 +684,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||
pQueryMsg->tableLimit = htobe64(pQueryInfo->tableLimit);
|
||||
|
||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||
|
@ -2058,6 +2059,10 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
|||
if (pConnect->epSet.numOfEps > 0) {
|
||||
tscEpSetHtons(&pConnect->epSet);
|
||||
tscUpdateMgmtEpSet(&pConnect->epSet);
|
||||
|
||||
for (int i = 0; i < pConnect->epSet.numOfEps; ++i) {
|
||||
tscDebug("%p epSet.fqdn[%d]: %s, pObj:%p", pSql, i, pConnect->epSet.fqdn[i], pObj);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(pObj->sversion, pConnect->serverVersion);
|
||||
|
|
|
@ -157,7 +157,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
code = tsParseSql(pSql, false);
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
tsem_wait(&pSub->sem);
|
||||
code = pSql->res.code;
|
||||
|
@ -168,7 +168,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
line = __LINE__;
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
goto fail;
|
||||
|
@ -401,10 +401,12 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
|||
tscLoadSubscriptionProgress(pSub);
|
||||
}
|
||||
|
||||
if (pSub->pSql->cmd.command == TSDB_SQL_SELECT) {
|
||||
if (!tscUpdateSubscription(pObj, pSub)) {
|
||||
taos_unsubscribe(pSub, 1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pSub->interval = interval;
|
||||
if (fp != NULL) {
|
||||
|
@ -417,10 +419,80 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
|||
return pSub;
|
||||
}
|
||||
|
||||
SSqlObj* recreateSqlObj(SSub* pSub) {
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSql->signature = pSql;
|
||||
pSql->pTscObj = pSub->taos;
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
if (tsem_init(&pSql->rspSem, 0, 0) == -1) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSql->param = pSub;
|
||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||
pSql->fp = asyncCallback;
|
||||
pSql->fetchFp = asyncCallback;
|
||||
pSql->sqlstr = strdup(pSub->pSql->sqlstr);
|
||||
if (pSql->sqlstr == NULL) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRes->qhandle = 0;
|
||||
pRes->numOfRows = 1;
|
||||
|
||||
int code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
tsem_wait(&pSub->sem);
|
||||
code = pSql->res.code;
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pSql;
|
||||
}
|
||||
|
||||
TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||
SSub *pSub = (SSub *)tsub;
|
||||
if (pSub == NULL) return NULL;
|
||||
|
||||
if (pSub->pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
SSqlObj* pSql = recreateSqlObj(pSub);
|
||||
if (pSql == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (pSub->pSql->self != 0) {
|
||||
taosReleaseRef(tscObjRef, pSub->pSql->self);
|
||||
} else {
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
}
|
||||
pSub->pSql = pSql;
|
||||
pSql->pSubscription = pSub;
|
||||
}
|
||||
|
||||
tscSaveSubscriptionProgress(pSub);
|
||||
|
||||
SSqlObj *pSql = pSub->pSql;
|
||||
|
@ -512,10 +584,13 @@ void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
|||
}
|
||||
|
||||
if (pSub->pSql != NULL) {
|
||||
taos_free_result(pSub->pSql);
|
||||
if (pSub->pSql->self != 0) {
|
||||
taosReleaseRef(tscObjRef, pSub->pSql->self);
|
||||
} else {
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
}
|
||||
}
|
||||
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
taosArrayDestroy(pSub->progress);
|
||||
tsem_destroy(&pSub->sem);
|
||||
memset(pSub, 0, sizeof(*pSub));
|
||||
|
|
|
@ -144,7 +144,7 @@ void taos_init_imp(void) {
|
|||
int64_t refreshTime = 10; // 10 seconds by default
|
||||
if (tscMetaCache == NULL) {
|
||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
||||
tscObjRef = taosOpenRef(4096, tscFreeRegisteredSqlObj);
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
}
|
||||
|
||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||
|
|
|
@ -56,6 +56,7 @@ extern char tsTempDir[];
|
|||
|
||||
//query buffer management
|
||||
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing
|
||||
extern int32_t tsHalfCoresForQuery; // only 50% will be used in query processing
|
||||
|
||||
// client
|
||||
extern int32_t tsTableMetaKeepTimer;
|
||||
|
@ -125,6 +126,9 @@ extern char tsMonitorDbName[];
|
|||
extern char tsInternalPass[];
|
||||
extern int32_t tsMonitorInterval;
|
||||
|
||||
// stream
|
||||
extern int32_t tsEnableStream;
|
||||
|
||||
// internal
|
||||
extern int32_t tsPrintAuth;
|
||||
extern int32_t tscEmbedded;
|
||||
|
@ -176,7 +180,7 @@ extern int32_t tmrDebugFlag;
|
|||
extern int32_t sdbDebugFlag;
|
||||
extern int32_t httpDebugFlag;
|
||||
extern int32_t mqttDebugFlag;
|
||||
extern int32_t monitorDebugFlag;
|
||||
extern int32_t monDebugFlag;
|
||||
extern int32_t uDebugFlag;
|
||||
extern int32_t rpcDebugFlag;
|
||||
extern int32_t odbcDebugFlag;
|
||||
|
|
|
@ -107,6 +107,9 @@ int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
|
|||
// positive value (in MB)
|
||||
int32_t tsQueryBufferSize = -1;
|
||||
|
||||
// only 50% cpu will be used in query processing in dnode
|
||||
int32_t tsHalfCoresForQuery = 0;
|
||||
|
||||
// db parameters
|
||||
int32_t tsCacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||
int32_t tsBlocksPerVnode = TSDB_DEFAULT_TOTAL_BLOCKS;
|
||||
|
@ -161,6 +164,9 @@ char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log";
|
|||
char tsInternalPass[] = "secretkey";
|
||||
int32_t tsMonitorInterval = 30; // seconds
|
||||
|
||||
// stream
|
||||
int32_t tsEnableStream = 1;
|
||||
|
||||
// internal
|
||||
int32_t tsPrintAuth = 0;
|
||||
int32_t tscEmbedded = 0;
|
||||
|
@ -206,7 +212,7 @@ int32_t jniDebugFlag = 131;
|
|||
int32_t odbcDebugFlag = 131;
|
||||
int32_t httpDebugFlag = 131;
|
||||
int32_t mqttDebugFlag = 131;
|
||||
int32_t monitorDebugFlag = 131;
|
||||
int32_t monDebugFlag = 131;
|
||||
int32_t qDebugFlag = 131;
|
||||
int32_t rpcDebugFlag = 131;
|
||||
int32_t uDebugFlag = 131;
|
||||
|
@ -216,9 +222,9 @@ int32_t wDebugFlag = 135;
|
|||
int32_t tsdbDebugFlag = 131;
|
||||
int32_t cqDebugFlag = 135;
|
||||
|
||||
int32_t (*monitorStartSystemFp)() = NULL;
|
||||
void (*monitorStopSystemFp)() = NULL;
|
||||
void (*monitorExecuteSQLFp)(char *sql) = NULL;
|
||||
int32_t (*monStartSystemFp)() = NULL;
|
||||
void (*monStopSystemFp)() = NULL;
|
||||
void (*monExecuteSQLFp)(char *sql) = NULL;
|
||||
|
||||
char *qtypeStr[] = {"rpc", "fwd", "wal", "cq", "query"};
|
||||
|
||||
|
@ -235,7 +241,7 @@ void taosSetAllDebugFlag() {
|
|||
odbcDebugFlag = debugFlag;
|
||||
httpDebugFlag = debugFlag;
|
||||
mqttDebugFlag = debugFlag;
|
||||
monitorDebugFlag = debugFlag;
|
||||
monDebugFlag = debugFlag;
|
||||
qDebugFlag = debugFlag;
|
||||
rpcDebugFlag = debugFlag;
|
||||
uDebugFlag = debugFlag;
|
||||
|
@ -276,15 +282,15 @@ bool taosCfgDynamicOptions(char *msg) {
|
|||
|
||||
if (strncasecmp(cfg->option, "monitor", olen) == 0) {
|
||||
if (1 == vint) {
|
||||
if (monitorStartSystemFp) {
|
||||
(*monitorStartSystemFp)();
|
||||
if (monStartSystemFp) {
|
||||
(*monStartSystemFp)();
|
||||
uInfo("monitor is enabled");
|
||||
} else {
|
||||
uError("monitor can't be updated, for monitor not initialized");
|
||||
}
|
||||
} else {
|
||||
if (monitorStopSystemFp) {
|
||||
(*monitorStopSystemFp)();
|
||||
if (monStopSystemFp) {
|
||||
(*monStopSystemFp)();
|
||||
uInfo("monitor is disabled");
|
||||
} else {
|
||||
uError("monitor can't be updated, for monitor not initialized");
|
||||
|
@ -307,8 +313,8 @@ bool taosCfgDynamicOptions(char *msg) {
|
|||
}
|
||||
|
||||
if (strncasecmp(option, "resetQueryCache", 15) == 0) {
|
||||
if (monitorExecuteSQLFp) {
|
||||
(*monitorExecuteSQLFp)("resetQueryCache");
|
||||
if (monExecuteSQLFp) {
|
||||
(*monExecuteSQLFp)("resetQueryCache");
|
||||
uInfo("resetquerycache is executed");
|
||||
} else {
|
||||
uError("resetquerycache can't be executed, for monitor not started");
|
||||
|
@ -881,6 +887,16 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_BYTE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "halfCoresForQuery";
|
||||
cfg.ptr = &tsHalfCoresForQuery;
|
||||
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);
|
||||
|
||||
// locale & charset
|
||||
cfg.option = "timezone";
|
||||
cfg.ptr = tsTimezone;
|
||||
|
@ -1015,6 +1031,16 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "stream";
|
||||
cfg.ptr = &tsEnableStream;
|
||||
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 = "httpEnableRecordSql";
|
||||
cfg.ptr = &tsHttpEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
|
@ -1227,8 +1253,8 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "monitorDebugFlag";
|
||||
cfg.ptr = &monitorDebugFlag;
|
||||
cfg.option = "monDebugFlag";
|
||||
cfg.ptr = &monDebugFlag;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG;
|
||||
cfg.minValue = 0;
|
||||
|
@ -1277,7 +1303,7 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "tscEnableRecordSql";
|
||||
cfg.option = "enableRecordSql";
|
||||
cfg.ptr = &tsTscEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
|
|
|
@ -69,6 +69,9 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row);
|
|||
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj);
|
||||
|
||||
void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
||||
if (tsEnableStream == 0) {
|
||||
return NULL;
|
||||
}
|
||||
SCqContext *pContext = calloc(sizeof(SCqContext), 1);
|
||||
if (pContext == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
|
@ -99,6 +102,9 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
|||
}
|
||||
|
||||
void cqClose(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
if (handle == NULL) return;
|
||||
|
||||
|
@ -129,6 +135,9 @@ void cqClose(void *handle) {
|
|||
}
|
||||
|
||||
void cqStart(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
if (pContext->dbConn || pContext->master) return;
|
||||
|
||||
|
@ -147,6 +156,9 @@ void cqStart(void *handle) {
|
|||
}
|
||||
|
||||
void cqStop(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
cInfo("vgId:%d, stop all CQs", pContext->vgId);
|
||||
if (pContext->dbConn == NULL || pContext->master == 0) return;
|
||||
|
@ -174,6 +186,9 @@ void cqStop(void *handle) {
|
|||
}
|
||||
|
||||
void *cqCreate(void *handle, uint64_t uid, int32_t tid, char *sqlStr, STSchema *pSchema) {
|
||||
if (tsEnableStream == 0) {
|
||||
return NULL;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
|
||||
SCqObj *pObj = calloc(sizeof(SCqObj), 1);
|
||||
|
@ -203,6 +218,9 @@ void *cqCreate(void *handle, uint64_t uid, int32_t tid, char *sqlStr, STSchema *
|
|||
}
|
||||
|
||||
void cqDrop(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqObj *pObj = handle;
|
||||
SCqContext *pContext = pObj->pContext;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "tqueue.h"
|
||||
#include "tsync.h"
|
||||
#include "ttimer.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tglobal.h"
|
||||
#include "dnode.h"
|
||||
#include "vnode.h"
|
||||
|
|
|
@ -78,10 +78,10 @@ static void dnodeAllocModules() {
|
|||
|
||||
tsModule[TSDB_MOD_MONITOR].enable = (tsEnableMonitorModule == 1);
|
||||
tsModule[TSDB_MOD_MONITOR].name = "monitor";
|
||||
tsModule[TSDB_MOD_MONITOR].initFp = monitorInitSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].cleanUpFp = monitorCleanUpSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].startFp = monitorStartSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].stopFp = monitorStopSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].initFp = monInitSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].cleanUpFp = monCleanupSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].startFp = monStartSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].stopFp = monStopSystem;
|
||||
if (tsEnableMonitorModule) {
|
||||
dnodeSetModuleStatus(TSDB_MOD_MONITOR);
|
||||
}
|
||||
|
|
|
@ -182,6 +182,8 @@ void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg) {
|
|||
void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
|
||||
SRpcEpSet epSet = {0};
|
||||
dnodeGetEpSetForPeer(&epSet);
|
||||
|
||||
assert(tsClientRpc != 0);
|
||||
rpcSendRecv(tsClientRpc, &epSet, rpcMsg, rpcRsp);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,13 +47,13 @@ typedef struct {
|
|||
int8_t accessState;
|
||||
} SAcctMonitorObj;
|
||||
|
||||
int32_t monitorInitSystem();
|
||||
int32_t monitorStartSystem();
|
||||
void monitorStopSystem();
|
||||
void monitorCleanUpSystem();
|
||||
void monitorSaveAcctLog(SAcctMonitorObj *pMonObj);
|
||||
void monitorSaveLog(int32_t level, const char *const format, ...);
|
||||
void monitorExecuteSQL(char *sql);
|
||||
int32_t monInitSystem();
|
||||
int32_t monStartSystem();
|
||||
void monStopSystem();
|
||||
void monCleanupSystem();
|
||||
void monSaveAcctLog(SAcctMonitorObj *pMonObj);
|
||||
void monSaveLog(int32_t level, const char *const format, ...);
|
||||
void monExecuteSQL(char *sql);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -476,6 +476,8 @@ typedef struct {
|
|||
int16_t numOfGroupCols; // num of group by columns
|
||||
int16_t orderByIdx;
|
||||
int16_t orderType; // used in group by xx order by xxx
|
||||
int64_t tableLimit; // limit the number of rows for each table, used in order by + limit in stable projection query.
|
||||
int16_t prjOrder; // global order in super table projection query.
|
||||
int64_t limit;
|
||||
int64_t offset;
|
||||
uint32_t queryType; // denote another query process
|
||||
|
|
|
@ -23,14 +23,14 @@ extern "C" {
|
|||
struct SVgObj;
|
||||
struct SDnodeObj;
|
||||
|
||||
int32_t balanceInit();
|
||||
void balanceCleanUp();
|
||||
void balanceAsyncNotify();
|
||||
void balanceSyncNotify();
|
||||
void balanceReset();
|
||||
int32_t balanceAllocVnodes(struct SVgObj *pVgroup);
|
||||
int32_t balanceAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId);
|
||||
int32_t balanceDropDnode(struct SDnodeObj *pDnode);
|
||||
int32_t bnInit();
|
||||
void bnCleanUp();
|
||||
void bnNotify();
|
||||
void bnCheckModules();
|
||||
void bnReset();
|
||||
int32_t bnAllocVnodes(struct SVgObj *pVgroup);
|
||||
int32_t bnAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId);
|
||||
int32_t bnDropDnode(struct SDnodeObj *pDnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -41,9 +41,9 @@ extern int32_t sdbDebugFlag;
|
|||
#define sdbDebug(...) { if (sdbDebugFlag & DEBUG_DEBUG) { taosPrintLog("SDB ", sdbDebugFlag, __VA_ARGS__); }}
|
||||
#define sdbTrace(...) { if (sdbDebugFlag & DEBUG_TRACE) { taosPrintLog("SDB ", sdbDebugFlag, __VA_ARGS__); }}
|
||||
|
||||
#define mLError(...) { monitorSaveLog(2, __VA_ARGS__); mError(__VA_ARGS__) }
|
||||
#define mLWarn(...) { monitorSaveLog(1, __VA_ARGS__); mWarn(__VA_ARGS__) }
|
||||
#define mLInfo(...) { monitorSaveLog(0, __VA_ARGS__); mInfo(__VA_ARGS__) }
|
||||
#define mLError(...) { monSaveLog(2, __VA_ARGS__); mError(__VA_ARGS__) }
|
||||
#define mLWarn(...) { monSaveLog(1, __VA_ARGS__); mWarn(__VA_ARGS__) }
|
||||
#define mLInfo(...) { monSaveLog(0, __VA_ARGS__); mInfo(__VA_ARGS__) }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "tgrant.h"
|
||||
#include "tglobal.h"
|
||||
#include "tname.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tdataformat.h"
|
||||
#include "mnode.h"
|
||||
#include "mnodeDef.h"
|
||||
|
@ -250,7 +250,7 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) {
|
|||
}
|
||||
|
||||
if (pCfg->daysToKeep2 < TSDB_MIN_KEEP || pCfg->daysToKeep2 > pCfg->daysToKeep) {
|
||||
mError("invalid db option daysToKeep2:%d valid range: [%d, %d]", pCfg->daysToKeep, TSDB_MIN_KEEP, pCfg->daysToKeep);
|
||||
mError("invalid db option daysToKeep2:%d valid range: [%d, %d]", pCfg->daysToKeep2, TSDB_MIN_KEEP, pCfg->daysToKeep);
|
||||
return TSDB_CODE_MND_INVALID_DB_OPTION_KEEP;
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1004,7 @@ static int32_t mnodeAlterDbCb(SMnodeMsg *pMsg, int32_t code) {
|
|||
mDebug("db:%s, all vgroups is altered", pDb->name);
|
||||
mLInfo("db:%s, is alterd by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
|
||||
|
||||
balanceAsyncNotify();
|
||||
bnNotify();
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tgrant.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tglobal.h"
|
||||
#include "tconfig.h"
|
||||
#include "tutil.h"
|
||||
#include "tsocket.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tsync.h"
|
||||
#include "tdataformat.h"
|
||||
#include "mnode.h"
|
||||
|
@ -115,7 +115,7 @@ static int32_t mnodeDnodeActionDelete(SSdbRow *pRow) {
|
|||
mnodeDropAllDnodeVgroups(pDnode);
|
||||
#endif
|
||||
mnodeDropMnodeLocal(pDnode->dnodeId);
|
||||
balanceAsyncNotify();
|
||||
bnNotify();
|
||||
mnodeUpdateDnodeEps();
|
||||
|
||||
mDebug("dnode:%d, all vgroups is dropped from sdb", pDnode->dnodeId);
|
||||
|
@ -347,7 +347,7 @@ static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg) {
|
|||
return TSDB_CODE_MND_INVALID_DNODE_CFG_OPTION;
|
||||
}
|
||||
|
||||
int32_t code = balanceAlterDnode(pDnode, vnodeId, dnodeId);
|
||||
int32_t code = bnAlterDnode(pDnode, vnodeId, dnodeId);
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
return code;
|
||||
} else {
|
||||
|
@ -591,8 +591,8 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
|||
mInfo("dnode:%d, from offline to online", pDnode->dnodeId);
|
||||
pDnode->status = TAOS_DN_STATUS_READY;
|
||||
pDnode->offlineReason = TAOS_DN_OFF_ONLINE;
|
||||
balanceSyncNotify();
|
||||
balanceAsyncNotify();
|
||||
bnCheckModules();
|
||||
bnNotify();
|
||||
}
|
||||
|
||||
if (openVnodes != pDnode->openVnodes) {
|
||||
|
@ -708,7 +708,7 @@ static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
|
|||
#ifndef _SYNC
|
||||
int32_t code = mnodeDropDnode(pDnode, pMsg);
|
||||
#else
|
||||
int32_t code = balanceDropDnode(pDnode);
|
||||
int32_t code = bnDropDnode(pDnode);
|
||||
#endif
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
return code;
|
||||
|
@ -1182,12 +1182,12 @@ static char* mnodeGetDnodeAlternativeRoleStr(int32_t alternativeRole) {
|
|||
|
||||
#ifndef _SYNC
|
||||
|
||||
int32_t balanceInit() { return TSDB_CODE_SUCCESS; }
|
||||
void balanceCleanUp() {}
|
||||
void balanceAsyncNotify() {}
|
||||
void balanceSyncNotify() {}
|
||||
void balanceReset() {}
|
||||
int32_t balanceAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId) { return TSDB_CODE_SYN_NOT_ENABLED; }
|
||||
int32_t bnInit() { return TSDB_CODE_SUCCESS; }
|
||||
void bnCleanUp() {}
|
||||
void bnNotify() {}
|
||||
void bnCheckModules() {}
|
||||
void bnReset() {}
|
||||
int32_t bnAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId) { return TSDB_CODE_SYN_NOT_ENABLED; }
|
||||
|
||||
char* syncRole[] = {
|
||||
"offline",
|
||||
|
@ -1197,7 +1197,7 @@ char* syncRole[] = {
|
|||
"master"
|
||||
};
|
||||
|
||||
int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||
int32_t bnAllocVnodes(SVgObj *pVgroup) {
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
SDnodeObj *pSelDnode = NULL;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tsched.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tgrant.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
|
@ -58,7 +58,7 @@ static const SMnodeComponent tsMnodeComponents[] = {
|
|||
{"tables", mnodeInitTables, mnodeCleanupTables},
|
||||
{"mnodes", mnodeInitMnodes, mnodeCleanupMnodes},
|
||||
{"sdb", sdbInit, sdbCleanUp},
|
||||
{"balance", balanceInit, balanceCleanUp},
|
||||
{"balance", bnInit, bnCleanUp},
|
||||
{"grant", grantInit, grantCleanUp},
|
||||
{"show", mnodeInitShow, mnodeCleanUpShow}
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "tglobal.h"
|
||||
#include "trpc.h"
|
||||
#include "tsync.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tutil.h"
|
||||
#include "tsocket.h"
|
||||
#include "tdataformat.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "tsystem.h"
|
||||
#include "tutil.h"
|
||||
#include "tgrant.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnode.h"
|
||||
#include "dnode.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tsched.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tgrant.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "hash.h"
|
||||
#include "tutil.h"
|
||||
#include "tref.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tqueue.h"
|
||||
#include "twal.h"
|
||||
#include "tsync.h"
|
||||
|
@ -244,7 +244,7 @@ static void sdbNotifyRole(int32_t vgId, int8_t role) {
|
|||
sdbInfo("vgId:1, mnode role changed from %s to %s", syncRole[tsSdbMgmt.role], syncRole[role]);
|
||||
|
||||
if (role == TAOS_SYNC_ROLE_MASTER && tsSdbMgmt.role != TAOS_SYNC_ROLE_MASTER) {
|
||||
balanceReset();
|
||||
bnReset();
|
||||
}
|
||||
tsSdbMgmt.role = role;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "tsocket.h"
|
||||
#include "tidpool.h"
|
||||
#include "tsync.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tglobal.h"
|
||||
#include "tdataformat.h"
|
||||
#include "dnode.h"
|
||||
|
@ -563,7 +563,7 @@ int32_t mnodeCreateVgroup(SMnodeMsg *pMsg) {
|
|||
pVgroup->numOfVnodes = pDb->cfg.replications;
|
||||
pVgroup->createdTime = taosGetTimestampMs();
|
||||
pVgroup->accessState = TSDB_VN_ALL_ACCCESS;
|
||||
int32_t code = balanceAllocVnodes(pVgroup);
|
||||
int32_t code = bnAllocVnodes(pVgroup);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
mError("db:%s, no enough dnode to alloc %d vnodes to vgroup, reason:%s", pDb->name, pVgroup->numOfVnodes,
|
||||
tstrerror(code));
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tsched.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tgrant.h"
|
||||
#include "tglobal.h"
|
||||
#include "trpc.h"
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
#include "monitor.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define mnFatal(...) { if (monitorDebugFlag & DEBUG_FATAL) { taosPrintLog("MON FATAL ", 255, __VA_ARGS__); }}
|
||||
#define mnError(...) { if (monitorDebugFlag & DEBUG_ERROR) { taosPrintLog("MON ERROR ", 255, __VA_ARGS__); }}
|
||||
#define mnWarn(...) { if (monitorDebugFlag & DEBUG_WARN) { taosPrintLog("MON WARN ", 255, __VA_ARGS__); }}
|
||||
#define mnInfo(...) { if (monitorDebugFlag & DEBUG_INFO) { taosPrintLog("MON ", 255, __VA_ARGS__); }}
|
||||
#define mnDebug(...) { if (monitorDebugFlag & DEBUG_DEBUG) { taosPrintLog("MON ", monitorDebugFlag, __VA_ARGS__); }}
|
||||
#define mnTrace(...) { if (monitorDebugFlag & DEBUG_TRACE) { taosPrintLog("MON ", monitorDebugFlag, __VA_ARGS__); }}
|
||||
#define monFatal(...) { if (monDebugFlag & DEBUG_FATAL) { taosPrintLog("MON FATAL ", 255, __VA_ARGS__); }}
|
||||
#define monError(...) { if (monDebugFlag & DEBUG_ERROR) { taosPrintLog("MON ERROR ", 255, __VA_ARGS__); }}
|
||||
#define monWarn(...) { if (monDebugFlag & DEBUG_WARN) { taosPrintLog("MON WARN ", 255, __VA_ARGS__); }}
|
||||
#define monInfo(...) { if (monDebugFlag & DEBUG_INFO) { taosPrintLog("MON ", 255, __VA_ARGS__); }}
|
||||
#define monDebug(...) { if (monDebugFlag & DEBUG_DEBUG) { taosPrintLog("MON ", monDebugFlag, __VA_ARGS__); }}
|
||||
#define monTrace(...) { if (monDebugFlag & DEBUG_TRACE) { taosPrintLog("MON ", monDebugFlag, __VA_ARGS__); }}
|
||||
|
||||
#define SQL_LENGTH 1030
|
||||
#define LOG_LEN_STR 100
|
||||
|
@ -48,12 +48,12 @@ typedef enum {
|
|||
MON_CMD_CREATE_TB_ACCT_ROOT,
|
||||
MON_CMD_CREATE_TB_SLOWQUERY,
|
||||
MON_CMD_MAX
|
||||
} EMonitorCommand;
|
||||
} EMonCmd;
|
||||
|
||||
typedef enum {
|
||||
MON_STATE_NOT_INIT,
|
||||
MON_STATE_INITED
|
||||
} EMonitorState;
|
||||
} EMonState;
|
||||
|
||||
typedef struct {
|
||||
pthread_t thread;
|
||||
|
@ -64,17 +64,17 @@ typedef struct {
|
|||
int8_t start; // enable/disable by mnode
|
||||
int8_t quiting; // taosd is quiting
|
||||
char sql[SQL_LENGTH + 1];
|
||||
} SMonitorConn;
|
||||
} SMonConn;
|
||||
|
||||
static SMonitorConn tsMonitor = {0};
|
||||
static void monitorSaveSystemInfo();
|
||||
static void *monitorThreadFunc(void *param);
|
||||
static void monitorBuildMonitorSql(char *sql, int32_t cmd);
|
||||
extern int32_t (*monitorStartSystemFp)();
|
||||
extern void (*monitorStopSystemFp)();
|
||||
extern void (*monitorExecuteSQLFp)(char *sql);
|
||||
static SMonConn tsMonitor = {0};
|
||||
static void monSaveSystemInfo();
|
||||
static void *monThreadFunc(void *param);
|
||||
static void monBuildMonitorSql(char *sql, int32_t cmd);
|
||||
extern int32_t (*monStartSystemFp)();
|
||||
extern void (*monStopSystemFp)();
|
||||
extern void (*monExecuteSQLFp)(char *sql);
|
||||
|
||||
int32_t monitorInitSystem() {
|
||||
int32_t monInitSystem() {
|
||||
if (tsMonitor.ep[0] == 0) {
|
||||
strcpy(tsMonitor.ep, tsLocalEp);
|
||||
}
|
||||
|
@ -90,29 +90,29 @@ int32_t monitorInitSystem() {
|
|||
pthread_attr_init(&thAttr);
|
||||
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
if (pthread_create(&tsMonitor.thread, &thAttr, monitorThreadFunc, NULL)) {
|
||||
mnError("failed to create thread to for monitor module, reason:%s", strerror(errno));
|
||||
if (pthread_create(&tsMonitor.thread, &thAttr, monThreadFunc, NULL)) {
|
||||
monError("failed to create thread to for monitor module, reason:%s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&thAttr);
|
||||
mnDebug("monitor thread is launched");
|
||||
monDebug("monitor thread is launched");
|
||||
|
||||
monitorStartSystemFp = monitorStartSystem;
|
||||
monitorStopSystemFp = monitorStopSystem;
|
||||
monStartSystemFp = monStartSystem;
|
||||
monStopSystemFp = monStopSystem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t monitorStartSystem() {
|
||||
int32_t monStartSystem() {
|
||||
taos_init();
|
||||
tsMonitor.start = 1;
|
||||
monitorExecuteSQLFp = monitorExecuteSQL;
|
||||
mnInfo("monitor module start");
|
||||
monExecuteSQLFp = monExecuteSQL;
|
||||
monInfo("monitor module start");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *monitorThreadFunc(void *param) {
|
||||
mnDebug("starting to initialize monitor module ...");
|
||||
static void *monThreadFunc(void *param) {
|
||||
monDebug("starting to initialize monitor module ...");
|
||||
|
||||
while (1) {
|
||||
static int32_t accessTimes = 0;
|
||||
|
@ -121,7 +121,7 @@ static void *monitorThreadFunc(void *param) {
|
|||
|
||||
if (tsMonitor.quiting) {
|
||||
tsMonitor.state = MON_STATE_NOT_INIT;
|
||||
mnInfo("monitor thread will quit, for taosd is quiting");
|
||||
monInfo("monitor thread will quit, for taosd is quiting");
|
||||
break;
|
||||
} else {
|
||||
taosGetDisk();
|
||||
|
@ -132,7 +132,7 @@ static void *monitorThreadFunc(void *param) {
|
|||
}
|
||||
|
||||
if (dnodeGetDnodeId() <= 0) {
|
||||
mnDebug("dnode not initialized, waiting for 3000 ms to start monitor module");
|
||||
monDebug("dnode not initialized, waiting for 3000 ms to start monitor module");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -140,10 +140,10 @@ static void *monitorThreadFunc(void *param) {
|
|||
tsMonitor.state = MON_STATE_NOT_INIT;
|
||||
tsMonitor.conn = taos_connect(NULL, "monitor", tsInternalPass, "", 0);
|
||||
if (tsMonitor.conn == NULL) {
|
||||
mnError("failed to connect to database, reason:%s", tstrerror(terrno));
|
||||
monError("failed to connect to database, reason:%s", tstrerror(terrno));
|
||||
continue;
|
||||
} else {
|
||||
mnDebug("connect to database success");
|
||||
monDebug("connect to database success");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,16 +151,16 @@ static void *monitorThreadFunc(void *param) {
|
|||
int code = 0;
|
||||
|
||||
for (; tsMonitor.cmdIndex < MON_CMD_MAX; ++tsMonitor.cmdIndex) {
|
||||
monitorBuildMonitorSql(tsMonitor.sql, tsMonitor.cmdIndex);
|
||||
monBuildMonitorSql(tsMonitor.sql, tsMonitor.cmdIndex);
|
||||
void *res = taos_query(tsMonitor.conn, tsMonitor.sql);
|
||||
code = taos_errno(res);
|
||||
taos_free_result(res);
|
||||
|
||||
if (code != 0) {
|
||||
mnError("failed to exec sql:%s, reason:%s", tsMonitor.sql, tstrerror(code));
|
||||
monError("failed to exec sql:%s, reason:%s", tsMonitor.sql, tstrerror(code));
|
||||
break;
|
||||
} else {
|
||||
mnDebug("successfully to exec sql:%s", tsMonitor.sql);
|
||||
monDebug("successfully to exec sql:%s", tsMonitor.sql);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,16 +171,16 @@ static void *monitorThreadFunc(void *param) {
|
|||
|
||||
if (tsMonitor.state == MON_STATE_INITED) {
|
||||
if (accessTimes % tsMonitorInterval == 0) {
|
||||
monitorSaveSystemInfo();
|
||||
monSaveSystemInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mnInfo("monitor thread is stopped");
|
||||
monInfo("monitor thread is stopped");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void monitorBuildMonitorSql(char *sql, int32_t cmd) {
|
||||
static void monBuildMonitorSql(char *sql, int32_t cmd) {
|
||||
memset(sql, 0, SQL_LENGTH);
|
||||
|
||||
if (cmd == MON_CMD_CREATE_DB) {
|
||||
|
@ -236,47 +236,47 @@ static void monitorBuildMonitorSql(char *sql, int32_t cmd) {
|
|||
sql[SQL_LENGTH] = 0;
|
||||
}
|
||||
|
||||
void monitorStopSystem() {
|
||||
void monStopSystem() {
|
||||
tsMonitor.start = 0;
|
||||
tsMonitor.state = MON_STATE_NOT_INIT;
|
||||
monitorExecuteSQLFp = NULL;
|
||||
mnInfo("monitor module stopped");
|
||||
monExecuteSQLFp = NULL;
|
||||
monInfo("monitor module stopped");
|
||||
}
|
||||
|
||||
void monitorCleanUpSystem() {
|
||||
void monCleanupSystem() {
|
||||
tsMonitor.quiting = 1;
|
||||
monitorStopSystem();
|
||||
monStopSystem();
|
||||
pthread_join(tsMonitor.thread, NULL);
|
||||
if (tsMonitor.conn != NULL) {
|
||||
taos_close(tsMonitor.conn);
|
||||
tsMonitor.conn = NULL;
|
||||
}
|
||||
mnInfo("monitor module is cleaned up");
|
||||
monInfo("monitor module is cleaned up");
|
||||
}
|
||||
|
||||
// unit is MB
|
||||
static int32_t monitorBuildMemorySql(char *sql) {
|
||||
static int32_t monBuildMemorySql(char *sql) {
|
||||
float sysMemoryUsedMB = 0;
|
||||
bool suc = taosGetSysMemory(&sysMemoryUsedMB);
|
||||
if (!suc) {
|
||||
mnDebug("failed to get sys memory info");
|
||||
monDebug("failed to get sys memory info");
|
||||
}
|
||||
|
||||
float procMemoryUsedMB = 0;
|
||||
suc = taosGetProcMemory(&procMemoryUsedMB);
|
||||
if (!suc) {
|
||||
mnDebug("failed to get proc memory info");
|
||||
monDebug("failed to get proc memory info");
|
||||
}
|
||||
|
||||
return sprintf(sql, ", %f, %f, %d", procMemoryUsedMB, sysMemoryUsedMB, tsTotalMemoryMB);
|
||||
}
|
||||
|
||||
// unit is %
|
||||
static int32_t monitorBuildCpuSql(char *sql) {
|
||||
static int32_t monBuildCpuSql(char *sql) {
|
||||
float sysCpuUsage = 0, procCpuUsage = 0;
|
||||
bool suc = taosGetCpuUsage(&sysCpuUsage, &procCpuUsage);
|
||||
if (!suc) {
|
||||
mnDebug("failed to get cpu usage");
|
||||
monDebug("failed to get cpu usage");
|
||||
}
|
||||
|
||||
if (sysCpuUsage <= procCpuUsage) {
|
||||
|
@ -287,72 +287,72 @@ static int32_t monitorBuildCpuSql(char *sql) {
|
|||
}
|
||||
|
||||
// unit is GB
|
||||
static int32_t monitorBuildDiskSql(char *sql) {
|
||||
static int32_t monBuildDiskSql(char *sql) {
|
||||
return sprintf(sql, ", %f, %d", (tsTotalDataDirGB - tsAvailDataDirGB), (int32_t)tsTotalDataDirGB);
|
||||
}
|
||||
|
||||
// unit is Kb
|
||||
static int32_t monitorBuildBandSql(char *sql) {
|
||||
static int32_t monBuildBandSql(char *sql) {
|
||||
float bandSpeedKb = 0;
|
||||
bool suc = taosGetBandSpeed(&bandSpeedKb);
|
||||
if (!suc) {
|
||||
mnDebug("failed to get bandwidth speed");
|
||||
monDebug("failed to get bandwidth speed");
|
||||
}
|
||||
|
||||
return sprintf(sql, ", %f", bandSpeedKb);
|
||||
}
|
||||
|
||||
static int32_t monitorBuildReqSql(char *sql) {
|
||||
static int32_t monBuildReqSql(char *sql) {
|
||||
SStatisInfo info = dnodeGetStatisInfo();
|
||||
return sprintf(sql, ", %d, %d, %d)", info.httpReqNum, info.queryReqNum, info.submitReqNum);
|
||||
}
|
||||
|
||||
static int32_t monitorBuildIoSql(char *sql) {
|
||||
static int32_t monBuildIoSql(char *sql) {
|
||||
float readKB = 0, writeKB = 0;
|
||||
bool suc = taosGetProcIO(&readKB, &writeKB);
|
||||
if (!suc) {
|
||||
mnDebug("failed to get io info");
|
||||
monDebug("failed to get io info");
|
||||
}
|
||||
|
||||
return sprintf(sql, ", %f, %f", readKB, writeKB);
|
||||
}
|
||||
|
||||
static void monitorSaveSystemInfo() {
|
||||
static void monSaveSystemInfo() {
|
||||
int64_t ts = taosGetTimestampUs();
|
||||
char * sql = tsMonitor.sql;
|
||||
int32_t pos = snprintf(sql, SQL_LENGTH, "insert into %s.dn%d values(%" PRId64, tsMonitorDbName, dnodeGetDnodeId(), ts);
|
||||
|
||||
pos += monitorBuildCpuSql(sql + pos);
|
||||
pos += monitorBuildMemorySql(sql + pos);
|
||||
pos += monitorBuildDiskSql(sql + pos);
|
||||
pos += monitorBuildBandSql(sql + pos);
|
||||
pos += monitorBuildIoSql(sql + pos);
|
||||
pos += monitorBuildReqSql(sql + pos);
|
||||
pos += monBuildCpuSql(sql + pos);
|
||||
pos += monBuildMemorySql(sql + pos);
|
||||
pos += monBuildDiskSql(sql + pos);
|
||||
pos += monBuildBandSql(sql + pos);
|
||||
pos += monBuildIoSql(sql + pos);
|
||||
pos += monBuildReqSql(sql + pos);
|
||||
|
||||
void *res = taos_query(tsMonitor.conn, tsMonitor.sql);
|
||||
int code = taos_errno(res);
|
||||
taos_free_result(res);
|
||||
|
||||
if (code != 0) {
|
||||
mnError("failed to save system info, reason:%s, sql:%s", tstrerror(code), tsMonitor.sql);
|
||||
monError("failed to save system info, reason:%s, sql:%s", tstrerror(code), tsMonitor.sql);
|
||||
} else {
|
||||
mnDebug("successfully to save system info, sql:%s", tsMonitor.sql);
|
||||
monDebug("successfully to save system info, sql:%s", tsMonitor.sql);
|
||||
}
|
||||
}
|
||||
|
||||
static void montiorExecSqlCb(void *param, TAOS_RES *result, int32_t code) {
|
||||
static void monExecSqlCb(void *param, TAOS_RES *result, int32_t code) {
|
||||
int32_t c = taos_errno(result);
|
||||
if (c != TSDB_CODE_SUCCESS) {
|
||||
mnError("save %s failed, reason:%s", (char *)param, tstrerror(c));
|
||||
monError("save %s failed, reason:%s", (char *)param, tstrerror(c));
|
||||
} else {
|
||||
int32_t rows = taos_affected_rows(result);
|
||||
mnDebug("save %s succ, rows:%d", (char *)param, rows);
|
||||
monDebug("save %s succ, rows:%d", (char *)param, rows);
|
||||
}
|
||||
|
||||
taos_free_result(result);
|
||||
}
|
||||
|
||||
void monitorSaveAcctLog(SAcctMonitorObj *pMon) {
|
||||
void monSaveAcctLog(SAcctMonitorObj *pMon) {
|
||||
if (tsMonitor.state != MON_STATE_INITED) return;
|
||||
|
||||
char sql[1024] = {0};
|
||||
|
@ -382,11 +382,11 @@ void monitorSaveAcctLog(SAcctMonitorObj *pMon) {
|
|||
pMon->totalConns, pMon->maxConns,
|
||||
pMon->accessState);
|
||||
|
||||
mnDebug("save account info, sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, montiorExecSqlCb, "account info");
|
||||
monDebug("save account info, sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "account info");
|
||||
}
|
||||
|
||||
void monitorSaveLog(int32_t level, const char *const format, ...) {
|
||||
void monSaveLog(int32_t level, const char *const format, ...) {
|
||||
if (tsMonitor.state != MON_STATE_INITED) return;
|
||||
|
||||
va_list argpointer;
|
||||
|
@ -403,13 +403,13 @@ void monitorSaveLog(int32_t level, const char *const format, ...) {
|
|||
len += sprintf(sql + len, "', '%s')", tsLocalEp);
|
||||
sql[len++] = 0;
|
||||
|
||||
mnDebug("save log, sql: %s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, montiorExecSqlCb, "log");
|
||||
monDebug("save log, sql: %s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "log");
|
||||
}
|
||||
|
||||
void monitorExecuteSQL(char *sql) {
|
||||
void monExecuteSQL(char *sql) {
|
||||
if (tsMonitor.state != MON_STATE_INITED) return;
|
||||
|
||||
mnDebug("execute sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, montiorExecSqlCb, "sql");
|
||||
monDebug("execute sql:%s", sql);
|
||||
taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "sql");
|
||||
}
|
|
@ -83,16 +83,15 @@ typedef struct SResultRec {
|
|||
int32_t threshold; // result size threshold in rows.
|
||||
} SResultRec;
|
||||
|
||||
typedef struct SWindowResInfo {
|
||||
typedef struct SResultRowInfo {
|
||||
SResultRow** pResult; // result list
|
||||
int16_t type:8; // data type for hash key
|
||||
int32_t size:24; // number of result set
|
||||
int32_t threshold; // threshold to halt query and return the generated results.
|
||||
int32_t capacity; // max capacity
|
||||
int32_t curIndex; // current start active index
|
||||
int64_t startTime; // start time of the first time window for sliding query
|
||||
int64_t prevSKey; // previous (not completed) sliding window start key
|
||||
} SWindowResInfo;
|
||||
} SResultRowInfo;
|
||||
|
||||
typedef struct SColumnFilterElem {
|
||||
int16_t bytes; // column length
|
||||
|
@ -115,7 +114,7 @@ typedef struct STableQueryInfo {
|
|||
STimeWindow win;
|
||||
STSCursor cur;
|
||||
void* pTable; // for retrieve the page id list
|
||||
SWindowResInfo windowResInfo;
|
||||
SResultRowInfo windowResInfo;
|
||||
} STableQueryInfo;
|
||||
|
||||
typedef struct SQueryCostInfo {
|
||||
|
@ -179,7 +178,7 @@ typedef struct SQueryRuntimeEnv {
|
|||
uint16_t* offset;
|
||||
uint16_t scanFlag; // denotes reversed scan of data or not
|
||||
SFillInfo* pFillInfo;
|
||||
SWindowResInfo windowResInfo;
|
||||
SResultRowInfo windowResInfo;
|
||||
STSBuf* pTSBuf;
|
||||
STSCursor cur;
|
||||
SQueryCostInfo summary;
|
||||
|
@ -190,6 +189,7 @@ typedef struct SQueryRuntimeEnv {
|
|||
bool groupbyNormalCol; // denote if this is a groupby normal column query
|
||||
bool hasTagResults; // if there are tag values in final result or not
|
||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||
bool queryWindowIdentical; // all query time windows are identical for all tables in one group
|
||||
int32_t interBufSize; // intermediate buffer sizse
|
||||
int32_t prevGroupId; // previous executed group id
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
|
@ -217,7 +217,8 @@ typedef struct SQInfo {
|
|||
STableGroupInfo tableGroupInfo; // table <tid, last_key> list SArray<STableKeyInfo>
|
||||
STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray<STableQueryInfo*> structure
|
||||
SQueryRuntimeEnv runtimeEnv;
|
||||
SArray* arrTableIdInfo;
|
||||
// SArray* arrTableIdInfo;
|
||||
SHashObj* arrTableIdInfo;
|
||||
int32_t groupIndex;
|
||||
|
||||
/*
|
||||
|
|
|
@ -30,19 +30,19 @@ void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pRow, int16_t typ
|
|||
void copyResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* dst, const SResultRow* src, int16_t type);
|
||||
SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index);
|
||||
|
||||
int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, int32_t size, int32_t threshold, int16_t type);
|
||||
int32_t initWindowResInfo(SResultRowInfo* pWindowResInfo, int32_t size, int16_t type);
|
||||
|
||||
void cleanupTimeWindowInfo(SWindowResInfo* pWindowResInfo);
|
||||
void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo* pWindowResInfo);
|
||||
void cleanupTimeWindowInfo(SResultRowInfo* pWindowResInfo);
|
||||
void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pWindowResInfo);
|
||||
void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num);
|
||||
|
||||
void clearClosedTimeWindow(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
int32_t numOfClosedTimeWindow(SWindowResInfo* pWindowResInfo);
|
||||
void closeTimeWindow(SWindowResInfo* pWindowResInfo, int32_t slot);
|
||||
void closeAllTimeWindow(SWindowResInfo* pWindowResInfo);
|
||||
void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_t order);
|
||||
int32_t numOfClosedTimeWindow(SResultRowInfo* pWindowResInfo);
|
||||
void closeTimeWindow(SResultRowInfo* pWindowResInfo, int32_t slot);
|
||||
void closeAllTimeWindow(SResultRowInfo* pWindowResInfo);
|
||||
void removeRedundantWindow(SResultRowInfo *pWindowResInfo, TSKEY lastKey, int32_t order);
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRow(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pWindowResInfo, int32_t slot) {
|
||||
assert(pWindowResInfo != NULL && slot >= 0 && slot < pWindowResInfo->size);
|
||||
return pWindowResInfo->pResult[slot];
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ static FORCE_INLINE SResultRow *getResultRow(SWindowResInfo *pWindowResInfo, int
|
|||
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
||||
#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!sq))? (_q)->pExpr1[1].base.arg->argValue.i64:1)
|
||||
|
||||
bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot);
|
||||
bool isWindowResClosed(SResultRowInfo *pWindowResInfo, int32_t slot);
|
||||
|
||||
int32_t initResultRow(SResultRow *pResultRow);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -405,14 +405,29 @@ void tSQLSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
|||
if (type->type == 0) {
|
||||
pField->bytes = 0;
|
||||
} else {
|
||||
pField->bytes = (int16_t)(-(int32_t)type->type * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
|
||||
int32_t bytes = -(int32_t)(type->type);
|
||||
if (bytes > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
|
||||
// we have to postpone reporting the error because it cannot be done here
|
||||
// as pField->bytes is int16_t, use 'TSDB_MAX_NCHAR_LEN + 1' to avoid overflow
|
||||
bytes = TSDB_MAX_NCHAR_LEN + 1;
|
||||
} else {
|
||||
bytes = bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
|
||||
}
|
||||
pField->bytes = (int16_t)bytes;
|
||||
}
|
||||
} else if (i == TSDB_DATA_TYPE_BINARY) {
|
||||
/* for binary, the TOKENTYPE is the length of binary */
|
||||
if (type->type == 0) {
|
||||
pField->bytes = 0;
|
||||
} else {
|
||||
pField->bytes = (int16_t) (-(int32_t) type->type + VARSTR_HEADER_SIZE);
|
||||
int32_t bytes = -(int32_t)(type->type);
|
||||
if (bytes > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
|
||||
// refer comment for NCHAR above
|
||||
bytes = TSDB_MAX_BINARY_LEN + 1;
|
||||
} else {
|
||||
bytes += VARSTR_HEADER_SIZE;
|
||||
}
|
||||
pField->bytes = (int16_t)bytes;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -43,51 +43,48 @@ int32_t getOutputInterResultBufSize(SQuery* pQuery) {
|
|||
return size;
|
||||
}
|
||||
|
||||
int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, int32_t size, int32_t threshold, int16_t type) {
|
||||
pWindowResInfo->capacity = size;
|
||||
pWindowResInfo->threshold = threshold;
|
||||
int32_t initWindowResInfo(SResultRowInfo *pResultRowInfo, int32_t size, int16_t type) {
|
||||
pResultRowInfo->capacity = size;
|
||||
|
||||
pWindowResInfo->type = type;
|
||||
pWindowResInfo->curIndex = -1;
|
||||
pWindowResInfo->size = 0;
|
||||
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
pResultRowInfo->type = type;
|
||||
pResultRowInfo->curIndex = -1;
|
||||
pResultRowInfo->size = 0;
|
||||
pResultRowInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
|
||||
pWindowResInfo->pResult = calloc(pWindowResInfo->capacity, POINTER_BYTES);
|
||||
if (pWindowResInfo->pResult == NULL) {
|
||||
pResultRowInfo->pResult = calloc(pResultRowInfo->capacity, POINTER_BYTES);
|
||||
if (pResultRowInfo->pResult == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void cleanupTimeWindowInfo(SWindowResInfo *pWindowResInfo) {
|
||||
if (pWindowResInfo == NULL) {
|
||||
void cleanupTimeWindowInfo(SResultRowInfo *pResultRowInfo) {
|
||||
if (pResultRowInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
if (pWindowResInfo->capacity == 0) {
|
||||
assert(pWindowResInfo->pResult == NULL);
|
||||
if (pResultRowInfo->capacity == 0) {
|
||||
assert(pResultRowInfo->pResult == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pWindowResInfo->type == TSDB_DATA_TYPE_BINARY || pWindowResInfo->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
for(int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
tfree(pWindowResInfo->pResult[i]->key);
|
||||
if (pResultRowInfo->type == TSDB_DATA_TYPE_BINARY || pResultRowInfo->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
for(int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
tfree(pResultRowInfo->pResult[i]->key);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pWindowResInfo->pResult);
|
||||
tfree(pResultRowInfo->pResult);
|
||||
}
|
||||
|
||||
void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo) {
|
||||
if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0) {
|
||||
void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo) {
|
||||
if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// assert(pWindowResInfo->size == 1);
|
||||
|
||||
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
SResultRow *pWindowRes = pWindowResInfo->pResult[i];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pWindowResInfo->type);
|
||||
for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
SResultRow *pWindowRes = pResultRowInfo->pResult[i];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pResultRowInfo->type);
|
||||
|
||||
int32_t groupIndex = 0;
|
||||
int64_t uid = 0;
|
||||
|
@ -96,30 +93,30 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
|
|||
taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(sizeof(groupIndex)));
|
||||
}
|
||||
|
||||
pWindowResInfo->curIndex = -1;
|
||||
pWindowResInfo->size = 0;
|
||||
pResultRowInfo->curIndex = -1;
|
||||
pResultRowInfo->size = 0;
|
||||
|
||||
pWindowResInfo->startTime = TSKEY_INITIAL_VAL;
|
||||
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
pResultRowInfo->startTime = TSKEY_INITIAL_VAL;
|
||||
pResultRowInfo->prevSKey = TSKEY_INITIAL_VAL;
|
||||
}
|
||||
|
||||
void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
||||
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||
if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0 || pWindowResInfo->size == 0 || num == 0) {
|
||||
SResultRowInfo *pResultRowInfo = &pRuntimeEnv->windowResInfo;
|
||||
if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0 || pResultRowInfo->size == 0 || num == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo);
|
||||
int32_t numOfClosed = numOfClosedTimeWindow(pResultRowInfo);
|
||||
assert(num >= 0 && num <= numOfClosed);
|
||||
|
||||
int16_t type = pWindowResInfo->type;
|
||||
int16_t type = pResultRowInfo->type;
|
||||
int64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
|
||||
char *key = NULL;
|
||||
int16_t bytes = -1;
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SResultRow *pResult = pWindowResInfo->pResult[i];
|
||||
SResultRow *pResult = pResultRowInfo->pResult[i];
|
||||
if (pResult->closed) { // remove the window slot from hash table
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
|
@ -129,23 +126,23 @@ void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t remain = pWindowResInfo->size - num;
|
||||
int32_t remain = pResultRowInfo->size - num;
|
||||
|
||||
// clear all the closed windows from the window list
|
||||
for (int32_t k = 0; k < remain; ++k) {
|
||||
copyResultRow(pRuntimeEnv, pWindowResInfo->pResult[k], pWindowResInfo->pResult[num + k], type);
|
||||
copyResultRow(pRuntimeEnv, pResultRowInfo->pResult[k], pResultRowInfo->pResult[num + k], type);
|
||||
}
|
||||
|
||||
// move the unclosed window in the front of the window list
|
||||
for (int32_t k = remain; k < pWindowResInfo->size; ++k) {
|
||||
SResultRow *pWindowRes = pWindowResInfo->pResult[k];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pWindowResInfo->type);
|
||||
for (int32_t k = remain; k < pResultRowInfo->size; ++k) {
|
||||
SResultRow *pWindowRes = pResultRowInfo->pResult[k];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pResultRowInfo->type);
|
||||
}
|
||||
|
||||
pWindowResInfo->size = remain;
|
||||
pResultRowInfo->size = remain;
|
||||
|
||||
for (int32_t k = 0; k < pWindowResInfo->size; ++k) {
|
||||
SResultRow *pResult = pWindowResInfo->pResult[k];
|
||||
for (int32_t k = 0; k < pResultRowInfo->size; ++k) {
|
||||
SResultRow *pResult = pResultRowInfo->pResult[k];
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
|
||||
|
@ -153,43 +150,43 @@ void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
|||
assert(p != NULL);
|
||||
|
||||
int32_t v = (*p - num);
|
||||
assert(v >= 0 && v <= pWindowResInfo->size);
|
||||
assert(v >= 0 && v <= pResultRowInfo->size);
|
||||
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), (char *)&v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
pWindowResInfo->curIndex = -1;
|
||||
pResultRowInfo->curIndex = -1;
|
||||
}
|
||||
|
||||
void clearClosedTimeWindow(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||
if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0 || pWindowResInfo->size == 0) {
|
||||
SResultRowInfo *pResultRowInfo = &pRuntimeEnv->windowResInfo;
|
||||
if (pResultRowInfo == NULL || pResultRowInfo->capacity == 0 || pResultRowInfo->size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo);
|
||||
int32_t numOfClosed = numOfClosedTimeWindow(pResultRowInfo);
|
||||
clearFirstNWindowRes(pRuntimeEnv, numOfClosed);
|
||||
}
|
||||
|
||||
int32_t numOfClosedTimeWindow(SWindowResInfo *pWindowResInfo) {
|
||||
int32_t numOfClosedTimeWindow(SResultRowInfo *pResultRowInfo) {
|
||||
int32_t i = 0;
|
||||
while (i < pWindowResInfo->size && pWindowResInfo->pResult[i]->closed) {
|
||||
while (i < pResultRowInfo->size && pResultRowInfo->pResult[i]->closed) {
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void closeAllTimeWindow(SWindowResInfo *pWindowResInfo) {
|
||||
assert(pWindowResInfo->size >= 0 && pWindowResInfo->capacity >= pWindowResInfo->size);
|
||||
void closeAllTimeWindow(SResultRowInfo *pResultRowInfo) {
|
||||
assert(pResultRowInfo->size >= 0 && pResultRowInfo->capacity >= pResultRowInfo->size);
|
||||
|
||||
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
if (pWindowResInfo->pResult[i]->closed) {
|
||||
for (int32_t i = 0; i < pResultRowInfo->size; ++i) {
|
||||
if (pResultRowInfo->pResult[i]->closed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pWindowResInfo->pResult[i]->closed = true;
|
||||
pResultRowInfo->pResult[i]->closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,41 +195,41 @@ void closeAllTimeWindow(SWindowResInfo *pWindowResInfo) {
|
|||
* the last qualified time stamp in case of sliding query, which the sliding time is not equalled to the interval time.
|
||||
* NOTE: remove redundant, only when the result set order equals to traverse order
|
||||
*/
|
||||
void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_t order) {
|
||||
assert(pWindowResInfo->size >= 0 && pWindowResInfo->capacity >= pWindowResInfo->size);
|
||||
if (pWindowResInfo->size <= 1) {
|
||||
void removeRedundantWindow(SResultRowInfo *pResultRowInfo, TSKEY lastKey, int32_t order) {
|
||||
assert(pResultRowInfo->size >= 0 && pResultRowInfo->capacity >= pResultRowInfo->size);
|
||||
if (pResultRowInfo->size <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the result order
|
||||
int32_t resultOrder = (pWindowResInfo->pResult[0]->win.skey < pWindowResInfo->pResult[1]->win.skey)? 1:-1;
|
||||
int32_t resultOrder = (pResultRowInfo->pResult[0]->win.skey < pResultRowInfo->pResult[1]->win.skey)? 1:-1;
|
||||
if (order != resultOrder) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t i = 0;
|
||||
if (order == QUERY_ASC_FORWARD_STEP) {
|
||||
TSKEY ekey = pWindowResInfo->pResult[i]->win.ekey;
|
||||
while (i < pWindowResInfo->size && (ekey < lastKey)) {
|
||||
TSKEY ekey = pResultRowInfo->pResult[i]->win.ekey;
|
||||
while (i < pResultRowInfo->size && (ekey < lastKey)) {
|
||||
++i;
|
||||
}
|
||||
} else if (order == QUERY_DESC_FORWARD_STEP) {
|
||||
while (i < pWindowResInfo->size && (pWindowResInfo->pResult[i]->win.skey > lastKey)) {
|
||||
while (i < pResultRowInfo->size && (pResultRowInfo->pResult[i]->win.skey > lastKey)) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < pWindowResInfo->size) {
|
||||
pWindowResInfo->size = (i + 1);
|
||||
if (i < pResultRowInfo->size) {
|
||||
pResultRowInfo->size = (i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
||||
return (getResultRow(pWindowResInfo, slot)->closed == true);
|
||||
bool isWindowResClosed(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
return (getResultRow(pResultRowInfo, slot)->closed == true);
|
||||
}
|
||||
|
||||
void closeTimeWindow(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
||||
getResultRow(pWindowResInfo, slot)->closed = true;
|
||||
void closeTimeWindow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
getResultRow(pResultRowInfo, slot)->closed = true;
|
||||
}
|
||||
|
||||
void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pWindowRes, int16_t type) {
|
||||
|
|
|
@ -248,8 +248,13 @@ SFileGroup *tsdbCreateFGroupIfNeed(STsdbRepo *pRepo, char *dataDir, int fid) {
|
|||
if (pGroup == NULL) { // if not exists, create one
|
||||
pFGroup->fileId = fid;
|
||||
for (int type = 0; type < TSDB_FILE_TYPE_MAX; type++) {
|
||||
if (tsdbCreateFile(&pFGroup->files[type], pRepo, fid, type) < 0)
|
||||
goto _err;
|
||||
if (tsdbCreateFile(&pFGroup->files[type], pRepo, fid, type) < 0) {
|
||||
for (int i = type; i >= 0; i--) {
|
||||
remove(pFGroup->files[i].fname);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&pFileH->fhlock);
|
||||
|
@ -261,10 +266,6 @@ SFileGroup *tsdbCreateFGroupIfNeed(STsdbRepo *pRepo, char *dataDir, int fid) {
|
|||
}
|
||||
|
||||
return pGroup;
|
||||
|
||||
_err:
|
||||
for (int type = 0; type < TSDB_FILE_TYPE_MAX; type++) tsdbDestroyFile(&pGroup->files[type]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void tsdbInitFileGroupIter(STsdbFileH *pFileH, SFileGroupIter *pIter, int direction) {
|
||||
|
|
|
@ -151,8 +151,9 @@ static void pushfrontNodeInEntryList(SHashEntry *pEntry, SHashNode *pNode);
|
|||
*/
|
||||
|
||||
SHashObj *taosHashInit(size_t capacity, _hash_fn_t fn, bool update, SHashLockTypeE type) {
|
||||
if (capacity == 0 || fn == NULL) {
|
||||
return NULL;
|
||||
assert(fn != NULL);
|
||||
if (capacity == 0) {
|
||||
capacity = 4;
|
||||
}
|
||||
|
||||
SHashObj *pHashObj = (SHashObj *)calloc(1, sizeof(SHashObj));
|
||||
|
|
|
@ -19,9 +19,7 @@
|
|||
#include "taoserror.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "tkey.h"
|
||||
#include "tulog.h"
|
||||
#include "tsocket.h"
|
||||
#include "tsystem.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
|
|
@ -423,14 +423,9 @@ static int taosDecRefCount(int rsetId, int64_t rid, int remove) {
|
|||
if (pNode->next) {
|
||||
pNode->next->prev = pNode->prev;
|
||||
}
|
||||
|
||||
(*pSet->fp)(pNode->p);
|
||||
|
||||
uTrace("rsetId:%d p:%p rid:%" PRId64 " is removed, count:%d, free mem: %p", rsetId, pNode->p, rid, pSet->count, pNode);
|
||||
free(pNode);
|
||||
released = 1;
|
||||
} else {
|
||||
uTrace("rsetId:%d p:%p rid:%" PRId64 " is released, count:%d", rsetId, pNode->p, rid, pNode->count);
|
||||
uTrace("rsetId:%d p:%p rid:%" PRId64 " is released", rsetId, pNode->p, rid);
|
||||
}
|
||||
} else {
|
||||
uTrace("rsetId:%d rid:%" PRId64 " is not there, failed to release/remove", rsetId, rid);
|
||||
|
@ -440,7 +435,13 @@ static int taosDecRefCount(int rsetId, int64_t rid, int remove) {
|
|||
|
||||
taosUnlockList(pSet->lockedBy+hash);
|
||||
|
||||
if (released) taosDecRsetCount(pSet);
|
||||
if (released) {
|
||||
uTrace("rsetId:%d p:%p rid:%" PRId64 " is removed, count:%d, free mem: %p", rsetId, pNode->p, rid, pSet->count, pNode);
|
||||
(*pSet->fp)(pNode->p);
|
||||
free(pNode);
|
||||
|
||||
taosDecRsetCount(pSet);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -267,6 +267,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (tsEnableStream) {
|
||||
SCqCfg cqCfg = {0};
|
||||
sprintf(cqCfg.user, "_root");
|
||||
strcpy(cqCfg.pass, tsInternalPass);
|
||||
|
@ -278,6 +279,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
|
|||
vnodeCleanUp(pVnode);
|
||||
return terrno;
|
||||
}
|
||||
}
|
||||
|
||||
STsdbAppH appH = {0};
|
||||
appH.appH = (void *)pVnode;
|
||||
|
|
|
@ -275,8 +275,11 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
|||
|
||||
vDebug("vgId:%d, QInfo:%p, dnode continues to exec query", pVnode->vgId, *qhandle);
|
||||
|
||||
|
||||
#if _NON_BLOCKING_RETRIEVE
|
||||
// In the retrieve blocking model, only 50% CPU will be used in query processing
|
||||
if (tsHalfCoresForQuery) {
|
||||
qTableQuery(*qhandle); // do execute query
|
||||
qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, false);
|
||||
} else {
|
||||
bool freehandle = false;
|
||||
bool buildRes = qTableQuery(*qhandle); // do execute query
|
||||
|
||||
|
@ -297,7 +300,6 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
|||
} else {
|
||||
void *h1 = qGetResultRetrieveMsg(*qhandle);
|
||||
assert(h1 == NULL);
|
||||
|
||||
freehandle = qQueryCompleted(*qhandle);
|
||||
}
|
||||
|
||||
|
@ -306,10 +308,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
|||
if (freehandle || (!buildRes)) {
|
||||
qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, freehandle);
|
||||
}
|
||||
#else
|
||||
qTableQuery(*qhandle); // do execute query
|
||||
qReleaseQInfo(pVnode->qMgmt, (void **)&qhandle, false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -375,14 +374,16 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
|
|||
freeHandle = true;
|
||||
} else { // result is not ready, return immediately
|
||||
assert(buildRes == true);
|
||||
#if _NON_BLOCKING_RETRIEVE
|
||||
|
||||
// Only effects in the non-blocking model
|
||||
if (!tsHalfCoresForQuery) {
|
||||
if (!buildRes) {
|
||||
assert(pRead->rpcHandle != NULL);
|
||||
|
||||
qReleaseQInfo(pVnode->qMgmt, (void **)&handle, false);
|
||||
return TSDB_CODE_QRY_NOT_READY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ahandle is the sqlObj pointer
|
||||
code = vnodeDumpQueryResult(pRet, pVnode, handle, &freeHandle, pRead->rpcHandle);
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.8</version>
|
||||
<version>2.0.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
|
|
|
@ -6,9 +6,23 @@ TDengine's JDBC demo project is organized in a Maven way so that users can easil
|
|||
Make sure you have already installed a tdengine client on your current develop environment.
|
||||
Download the tdengine package on our website: ``https://www.taosdata.com/cn/all-downloads/`` and install the client.
|
||||
|
||||
## How to run jdbcChecker
|
||||
<pre>mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.JdbcChecker" -Dexec.args="-host localhost"</pre>
|
||||
|
||||
## How to run jdbcTaosDemo
|
||||
run command:
|
||||
<pre> mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.jdbcTaosdemo.JdbcTaosdemo"</pre>
|
||||
and run with your customed args
|
||||
<pre>mvn clean compile exec:java -Dexec.mainClass="com.taosdata.example.jdbcTaosdemo.JdbcTaosdemo" -Dexec.args="-host localhost"</pre>
|
||||
|
||||
## Compile the Demo Code and Run It
|
||||
|
||||
To compile the demo project, go to the source directory ``TDengine/tests/examples/JDBC/JDBCDemo`` and execute
|
||||
<pre>mvn clean package assembly:single</pre>
|
||||
|
||||
<pre>
|
||||
mvn clean package assembly:single
|
||||
</pre>
|
||||
|
||||
The ``pom.xml`` is configured to package all the dependencies into one executable jar file.
|
||||
|
||||
To run it, go to ``examples/JDBC/JDBCDemo/target`` and execute
|
||||
|
|
|
@ -14,9 +14,9 @@ public final class JdbcTaosdemoConfig {
|
|||
//Destination database. Default is 'test'
|
||||
private String dbName = "test";
|
||||
//keep
|
||||
private int keep = 3650;
|
||||
private int keep = 36500;
|
||||
//days
|
||||
private int days = 10;
|
||||
private int days = 120;
|
||||
|
||||
//Super table Name. Default is 'meters'
|
||||
private String stbName = "meters";
|
||||
|
|
|
@ -41,7 +41,7 @@ public class InsertTableTask implements Runnable {
|
|||
long ts = start.toEpochMilli() + (j * timeGap);
|
||||
// insert data into echo table
|
||||
for (int i = startTbIndex; i < startTbIndex + tableNumber; i++) {
|
||||
String sql = SqlSpeller.insertOneRowSQL(config.getDbName(), config.getTbPrefix(), i + 1, ts);
|
||||
String sql = SqlSpeller.insertBatchSizeRowsSQL(config.getDbName(), config.getTbPrefix(), i + 1, ts, config.getNumberOfRecordsPerRequest());
|
||||
logger.info(Thread.currentThread().getName() + ">>> " + sql);
|
||||
Statement statement = connection.createStatement();
|
||||
statement.execute(sql);
|
||||
|
|
|
@ -32,9 +32,9 @@ class TDTestCase:
|
|||
tdSql.query("show databases")
|
||||
tdSql.checkData(0, 14, 2)
|
||||
|
||||
tdSql.execute("alter database db keep 365")
|
||||
tdSql.execute("alter database db keep 365,365,365")
|
||||
tdSql.query("show databases")
|
||||
tdSql.checkData(0, 7, "3650,3650,365")
|
||||
tdSql.checkData(0, 7, "365,365,365")
|
||||
|
||||
tdSql.execute("alter database db quorum 2")
|
||||
tdSql.query("show databases")
|
||||
|
|
|
@ -352,6 +352,12 @@ class ThreadCoordinator:
|
|||
self._execStats.registerFailure("Broken DB Connection")
|
||||
# continue # don't do that, need to tap all threads at
|
||||
# end, and maybe signal them to stop
|
||||
if isinstance(err, CrashGenError): # our own transition failure
|
||||
Logging.info("State transition error")
|
||||
traceback.print_stack()
|
||||
transitionFailed = True
|
||||
self._te = None # Not running any more
|
||||
self._execStats.registerFailure("State transition error")
|
||||
else:
|
||||
raise
|
||||
# return transitionFailed # Why did we have this??!!
|
||||
|
@ -388,12 +394,20 @@ class ThreadCoordinator:
|
|||
self._syncAtBarrier() # For now just cross the barrier
|
||||
Progress.emit(Progress.END_THREAD_STEP)
|
||||
except threading.BrokenBarrierError as err:
|
||||
Logging.info("Main loop aborted, caused by worker thread(s) time-out")
|
||||
self._execStats.registerFailure("Aborted due to worker thread timeout")
|
||||
print("\n\nWorker Thread time-out detected, TAOS related threads are:")
|
||||
Logging.error("\n")
|
||||
Logging.error("Main loop aborted, caused by worker thread(s) time-out of {} seconds".format(
|
||||
ThreadCoordinator.WORKER_THREAD_TIMEOUT))
|
||||
Logging.error("TAOS related threads blocked at (stack frames top-to-bottom):")
|
||||
ts = ThreadStacks()
|
||||
ts.print(filterInternal=True)
|
||||
workerTimeout = True
|
||||
|
||||
# Enable below for deadlock debugging, using gdb to attach to process
|
||||
# while True:
|
||||
# Logging.error("Deadlock detected")
|
||||
# time.sleep(60.0)
|
||||
|
||||
break
|
||||
|
||||
# At this point, all threads should be pass the overall "barrier" and before the per-thread "gate"
|
||||
|
@ -701,7 +715,7 @@ class AnyState:
|
|||
# task.logDebug("Task success found")
|
||||
sCnt += 1
|
||||
if (sCnt >= 2):
|
||||
raise RuntimeError(
|
||||
raise CrashGenError(
|
||||
"Unexpected more than 1 success with task: {}".format(cls))
|
||||
|
||||
def assertIfExistThenSuccess(self, tasks, cls):
|
||||
|
@ -714,7 +728,7 @@ class AnyState:
|
|||
if task.isSuccess():
|
||||
sCnt += 1
|
||||
if (exists and sCnt <= 0):
|
||||
raise RuntimeError("Unexpected zero success for task type: {}, from tasks: {}"
|
||||
raise CrashGenError("Unexpected zero success for task type: {}, from tasks: {}"
|
||||
.format(cls, tasks))
|
||||
|
||||
def assertNoTask(self, tasks, cls):
|
||||
|
@ -727,7 +741,7 @@ class AnyState:
|
|||
for task in tasks:
|
||||
if isinstance(task, cls):
|
||||
if task.isSuccess():
|
||||
raise RuntimeError(
|
||||
raise CrashGenError(
|
||||
"Unexpected successful task: {}".format(cls))
|
||||
|
||||
def hasSuccess(self, tasks, cls):
|
||||
|
@ -926,8 +940,9 @@ class StateMechine:
|
|||
Logging.debug("[STT] DB_ONLY found, between {} and {}".format(ts, time.time()))
|
||||
return StateDbOnly()
|
||||
|
||||
# For sure we have tables, which means we must have the super table. # TODO: are we sure?
|
||||
sTable = self._db.getFixedSuperTable()
|
||||
if sTable.hasRegTables(dbc, dbName): # no regular tables
|
||||
if sTable.hasRegTables(dbc): # no regular tables
|
||||
Logging.debug("[STT] SUPER_TABLE_ONLY found, between {} and {}".format(ts, time.time()))
|
||||
return StateSuperTableOnly()
|
||||
else: # has actual tables
|
||||
|
@ -1050,9 +1065,8 @@ class Database:
|
|||
def getFixedSuperTableName(cls):
|
||||
return "fs_table"
|
||||
|
||||
@classmethod
|
||||
def getFixedSuperTable(cls) -> TdSuperTable:
|
||||
return TdSuperTable(cls.getFixedSuperTableName())
|
||||
def getFixedSuperTable(self) -> TdSuperTable:
|
||||
return TdSuperTable(self.getFixedSuperTableName(), self.getName())
|
||||
|
||||
# We aim to create a starting time tick, such that, whenever we run our test here once
|
||||
# We should be able to safely create 100,000 records, which will not have any repeated time stamp
|
||||
|
@ -1107,6 +1121,11 @@ class Database:
|
|||
# print("Float obtained: {}".format(ret))
|
||||
return ret
|
||||
|
||||
ALL_COLORS = ['red', 'white', 'blue', 'green', 'purple']
|
||||
|
||||
def getNextColor(self):
|
||||
return random.choice(self.ALL_COLORS)
|
||||
|
||||
|
||||
class TaskExecutor():
|
||||
class BoundedList:
|
||||
|
@ -1240,7 +1259,7 @@ class Task():
|
|||
if errno in [
|
||||
0x05, # TSDB_CODE_RPC_NOT_READY
|
||||
0x0B, # Unable to establish connection, more details in TD-1648
|
||||
0x200, # invalid SQL, TODO: re-examine with TD-934
|
||||
# 0x200, # invalid SQL, TODO: re-examine with TD-934
|
||||
0x20F, # query terminated, possibly due to vnoding being dropped, see TD-1776
|
||||
0x213, # "Disconnected from service", result of "kill connection ???"
|
||||
0x217, # "db not selected", client side defined error code
|
||||
|
@ -1569,8 +1588,8 @@ class TaskCreateSuperTable(StateTransitionTask):
|
|||
sTable = self._db.getFixedSuperTable() # type: TdSuperTable
|
||||
# wt.execSql("use db") # should always be in place
|
||||
|
||||
sTable.create(wt.getDbConn(), self._db.getName(),
|
||||
{'ts':'timestamp', 'speed':'int'}, {'b':'binary(200)', 'f':'float'},
|
||||
sTable.create(wt.getDbConn(),
|
||||
{'ts':'TIMESTAMP', 'speed':'INT', 'color':'BINARY(16)'}, {'b':'BINARY(200)', 'f':'FLOAT'},
|
||||
dropIfExists = True
|
||||
)
|
||||
# self.execWtSql(wt,"create table db.{} (ts timestamp, speed int) tags (b binary(200), f float) ".format(tblName))
|
||||
|
@ -1579,30 +1598,33 @@ class TaskCreateSuperTable(StateTransitionTask):
|
|||
|
||||
|
||||
class TdSuperTable:
|
||||
def __init__(self, stName):
|
||||
def __init__(self, stName, dbName):
|
||||
self._stName = stName
|
||||
self._dbName = dbName
|
||||
|
||||
def getName(self):
|
||||
return self._stName
|
||||
|
||||
def drop(self, dbc, dbName, skipCheck = False):
|
||||
if self.exists(dbc, dbName) : # if myself exists
|
||||
def drop(self, dbc, skipCheck = False):
|
||||
dbName = self._dbName
|
||||
if self.exists(dbc) : # if myself exists
|
||||
fullTableName = dbName + '.' + self._stName
|
||||
dbc.execute("DROP TABLE {}".format(fullTableName))
|
||||
else:
|
||||
if not skipCheck:
|
||||
raise CrashGenError("Cannot drop non-existant super table: {}".format(self._stName))
|
||||
|
||||
def exists(self, dbc, dbName):
|
||||
dbc.execute("USE " + dbName)
|
||||
def exists(self, dbc):
|
||||
dbc.execute("USE " + self._dbName)
|
||||
return dbc.existsSuperTable(self._stName)
|
||||
|
||||
# TODO: odd semantic, create() method is usually static?
|
||||
def create(self, dbc, dbName, cols: dict, tags: dict,
|
||||
def create(self, dbc, cols: dict, tags: dict,
|
||||
dropIfExists = False
|
||||
):
|
||||
|
||||
'''Creating a super table'''
|
||||
|
||||
dbName = self._dbName
|
||||
dbc.execute("USE " + dbName)
|
||||
fullTableName = dbName + '.' + self._stName
|
||||
if dbc.existsSuperTable(self._stName):
|
||||
|
@ -1623,7 +1645,8 @@ class TdSuperTable:
|
|||
)
|
||||
dbc.execute(sql)
|
||||
|
||||
def getRegTables(self, dbc: DbConn, dbName: str):
|
||||
def getRegTables(self, dbc: DbConn):
|
||||
dbName = self._dbName
|
||||
try:
|
||||
dbc.query("select TBNAME from {}.{}".format(dbName, self._stName)) # TODO: analyze result set later
|
||||
except taos.error.ProgrammingError as err:
|
||||
|
@ -1634,10 +1657,11 @@ class TdSuperTable:
|
|||
qr = dbc.getQueryResult()
|
||||
return [v[0] for v in qr] # list transformation, ref: https://stackoverflow.com/questions/643823/python-list-transformation
|
||||
|
||||
def hasRegTables(self, dbc: DbConn, dbName: str):
|
||||
return dbc.query("SELECT * FROM {}.{}".format(dbName, self._stName)) > 0
|
||||
def hasRegTables(self, dbc: DbConn):
|
||||
return dbc.query("SELECT * FROM {}.{}".format(self._dbName, self._stName)) > 0
|
||||
|
||||
def ensureTable(self, task: Task, dbc: DbConn, dbName: str, regTableName: str):
|
||||
def ensureTable(self, task: Task, dbc: DbConn, regTableName: str):
|
||||
dbName = self._dbName
|
||||
sql = "select tbname from {}.{} where tbname in ('{}')".format(dbName, self._stName, regTableName)
|
||||
if dbc.query(sql) >= 1 : # reg table exists already
|
||||
return
|
||||
|
@ -1650,15 +1674,15 @@ class TdSuperTable:
|
|||
# print("(" + fullTableName[-3:] + ")", end="", flush=True)
|
||||
try:
|
||||
sql = "CREATE TABLE {} USING {}.{} tags ({})".format(
|
||||
fullTableName, dbName, self._stName, self._getTagStrForSql(dbc, dbName)
|
||||
fullTableName, dbName, self._stName, self._getTagStrForSql(dbc)
|
||||
)
|
||||
dbc.execute(sql)
|
||||
finally:
|
||||
if task is not None:
|
||||
task.unlockTable(fullTableName) # no matter what
|
||||
|
||||
def _getTagStrForSql(self, dbc, dbName: str) :
|
||||
tags = self._getTags(dbc, dbName)
|
||||
def _getTagStrForSql(self, dbc) :
|
||||
tags = self._getTags(dbc)
|
||||
tagStrs = []
|
||||
for tagName in tags:
|
||||
tagType = tags[tagName]
|
||||
|
@ -1672,36 +1696,86 @@ class TdSuperTable:
|
|||
raise RuntimeError("Unexpected tag type: {}".format(tagType))
|
||||
return ", ".join(tagStrs)
|
||||
|
||||
def _getTags(self, dbc, dbName) -> dict:
|
||||
dbc.query("DESCRIBE {}.{}".format(dbName, self._stName))
|
||||
def _getTags(self, dbc) -> dict:
|
||||
dbc.query("DESCRIBE {}.{}".format(self._dbName, self._stName))
|
||||
stCols = dbc.getQueryResult()
|
||||
# print(stCols)
|
||||
ret = {row[0]:row[1] for row in stCols if row[3]=='TAG'} # name:type
|
||||
# print("Tags retrieved: {}".format(ret))
|
||||
return ret
|
||||
|
||||
def addTag(self, dbc, dbName, tagName, tagType):
|
||||
if tagName in self._getTags(dbc, dbName): # already
|
||||
def addTag(self, dbc, tagName, tagType):
|
||||
if tagName in self._getTags(dbc): # already
|
||||
return
|
||||
# sTable.addTag("extraTag", "int")
|
||||
sql = "alter table {}.{} add tag {} {}".format(dbName, self._stName, tagName, tagType)
|
||||
sql = "alter table {}.{} add tag {} {}".format(
|
||||
self._dbName, self._stName, tagName, tagType)
|
||||
dbc.execute(sql)
|
||||
|
||||
def dropTag(self, dbc, dbName, tagName):
|
||||
if not tagName in self._getTags(dbc, dbName): # don't have this tag
|
||||
def dropTag(self, dbc, tagName):
|
||||
if not tagName in self._getTags(dbc): # don't have this tag
|
||||
return
|
||||
sql = "alter table {}.{} drop tag {}".format(dbName, self._stName, tagName)
|
||||
sql = "alter table {}.{} drop tag {}".format(self._dbName, self._stName, tagName)
|
||||
dbc.execute(sql)
|
||||
|
||||
def changeTag(self, dbc, dbName, oldTag, newTag):
|
||||
tags = self._getTags(dbc, dbName)
|
||||
def changeTag(self, dbc, oldTag, newTag):
|
||||
tags = self._getTags(dbc)
|
||||
if not oldTag in tags: # don't have this tag
|
||||
return
|
||||
if newTag in tags: # already have this tag
|
||||
return
|
||||
sql = "alter table {}.{} change tag {} {}".format(dbName, self._stName, oldTag, newTag)
|
||||
sql = "alter table {}.{} change tag {} {}".format(self._dbName, self._stName, oldTag, newTag)
|
||||
dbc.execute(sql)
|
||||
|
||||
def generateQueries(self, dbc: DbConn) -> List[SqlQuery]:
|
||||
''' Generate queries to test/exercise this super table '''
|
||||
ret = [] # type: List[SqlQuery]
|
||||
|
||||
for rTbName in self.getRegTables(dbc): # regular tables
|
||||
|
||||
filterExpr = Dice.choice([ # TODO: add various kind of WHERE conditions
|
||||
None
|
||||
])
|
||||
|
||||
# Run the query against the regular table first
|
||||
doAggr = (Dice.throw(2) == 0) # 1 in 2 chance
|
||||
if not doAggr: # don't do aggregate query, just simple one
|
||||
ret.append(SqlQuery( # reg table
|
||||
"select {} from {}.{}".format('*', self._dbName, rTbName)))
|
||||
ret.append(SqlQuery( # super table
|
||||
"select {} from {}.{}".format('*', self._dbName, self.getName())))
|
||||
else: # Aggregate query
|
||||
aggExpr = Dice.choice([
|
||||
'count(*)',
|
||||
'avg(speed)',
|
||||
# 'twa(speed)', # TODO: this one REQUIRES a where statement, not reasonable
|
||||
'sum(speed)',
|
||||
'stddev(speed)',
|
||||
# SELECTOR functions
|
||||
'min(speed)',
|
||||
'max(speed)',
|
||||
'first(speed)',
|
||||
'last(speed)',
|
||||
'top(speed, 50)', # TODO: not supported?
|
||||
'bottom(speed, 50)', # TODO: not supported?
|
||||
'apercentile(speed, 10)', # TODO: TD-1316
|
||||
'last_row(speed)',
|
||||
# Transformation Functions
|
||||
# 'diff(speed)', # TODO: no supported?!
|
||||
'spread(speed)'
|
||||
]) # TODO: add more from 'top'
|
||||
|
||||
|
||||
if aggExpr not in ['stddev(speed)']: #TODO: STDDEV not valid for super tables?!
|
||||
sql = "select {} from {}.{}".format(aggExpr, self._dbName, self.getName())
|
||||
if Dice.throw(3) == 0: # 1 in X chance
|
||||
sql = sql + ' GROUP BY color'
|
||||
Progress.emit(Progress.QUERY_GROUP_BY)
|
||||
# Logging.info("Executing GROUP-BY query: " + sql)
|
||||
ret.append(SqlQuery(sql))
|
||||
|
||||
return ret
|
||||
|
||||
class TaskReadData(StateTransitionTask):
|
||||
@classmethod
|
||||
def getEndState(cls):
|
||||
|
@ -1716,10 +1790,8 @@ class TaskReadData(StateTransitionTask):
|
|||
# return True # always
|
||||
# return gSvcMgr.isActive() # only if it's running TODO: race condition here
|
||||
|
||||
def _executeInternal(self, te: TaskExecutor, wt: WorkerThread):
|
||||
sTable = self._db.getFixedSuperTable()
|
||||
|
||||
# 1 in 5 chance, simulate a broken connection, only if service stable (not restarting)
|
||||
def _reconnectIfNeeded(self, wt):
|
||||
# 1 in 20 chance, simulate a broken connection, only if service stable (not restarting)
|
||||
if random.randrange(20)==0: # and self._canRestartService(): # TODO: break connection in all situations
|
||||
# Logging.info("Attempting to reconnect to server") # TODO: change to DEBUG
|
||||
Progress.emit(Progress.SERVICE_RECONNECT_START)
|
||||
|
@ -1744,43 +1816,36 @@ class TaskReadData(StateTransitionTask):
|
|||
return # TODO: fix server restart status race condtion
|
||||
|
||||
|
||||
def _executeInternal(self, te: TaskExecutor, wt: WorkerThread):
|
||||
self._reconnectIfNeeded(wt)
|
||||
|
||||
dbc = wt.getDbConn()
|
||||
dbName = self._db.getName()
|
||||
for rTbName in sTable.getRegTables(dbc, dbName): # regular tables
|
||||
aggExpr = Dice.choice([
|
||||
'*',
|
||||
'count(*)',
|
||||
'avg(speed)',
|
||||
# 'twa(speed)', # TODO: this one REQUIRES a where statement, not reasonable
|
||||
'sum(speed)',
|
||||
'stddev(speed)',
|
||||
# SELECTOR functions
|
||||
'min(speed)',
|
||||
'max(speed)',
|
||||
'first(speed)',
|
||||
'last(speed)',
|
||||
'top(speed, 50)', # TODO: not supported?
|
||||
'bottom(speed, 50)', # TODO: not supported?
|
||||
'apercentile(speed, 10)', # TODO: TD-1316
|
||||
'last_row(speed)',
|
||||
# Transformation Functions
|
||||
# 'diff(speed)', # TODO: no supported?!
|
||||
'spread(speed)'
|
||||
]) # TODO: add more from 'top'
|
||||
filterExpr = Dice.choice([ # TODO: add various kind of WHERE conditions
|
||||
None
|
||||
])
|
||||
sTable = self._db.getFixedSuperTable()
|
||||
|
||||
for q in sTable.generateQueries(dbc): # regular tables
|
||||
try:
|
||||
# Run the query against the regular table first
|
||||
dbc.execute("select {} from {}.{}".format(aggExpr, dbName, rTbName))
|
||||
# Then run it against the super table
|
||||
if aggExpr not in ['stddev(speed)']: #TODO: STDDEV not valid for super tables?!
|
||||
dbc.execute("select {} from {}.{}".format(aggExpr, dbName, sTable.getName()))
|
||||
sql = q.getSql()
|
||||
# if 'GROUP BY' in sql:
|
||||
# Logging.info("Executing GROUP-BY query: " + sql)
|
||||
dbc.execute(sql)
|
||||
except taos.error.ProgrammingError as err:
|
||||
errno2 = Helper.convertErrno(err.errno)
|
||||
Logging.debug("[=] Read Failure: errno=0x{:X}, msg: {}, SQL: {}".format(errno2, err, dbc.getLastSql()))
|
||||
raise
|
||||
|
||||
class SqlQuery:
|
||||
@classmethod
|
||||
def buildRandom(cls, db: Database):
|
||||
'''Build a random query against a certain database'''
|
||||
|
||||
dbName = db.getName()
|
||||
|
||||
def __init__(self, sql:str = None):
|
||||
self._sql = sql
|
||||
|
||||
def getSql(self):
|
||||
return self._sql
|
||||
|
||||
class TaskDropSuperTable(StateTransitionTask):
|
||||
@classmethod
|
||||
def getEndState(cls):
|
||||
|
@ -1837,19 +1902,18 @@ class TaskAlterTags(StateTransitionTask):
|
|||
# tblName = self._dbManager.getFixedSuperTableName()
|
||||
dbc = wt.getDbConn()
|
||||
sTable = self._db.getFixedSuperTable()
|
||||
dbName = self._db.getName()
|
||||
dice = Dice.throw(4)
|
||||
if dice == 0:
|
||||
sTable.addTag(dbc, dbName, "extraTag", "int")
|
||||
sTable.addTag(dbc, "extraTag", "int")
|
||||
# sql = "alter table db.{} add tag extraTag int".format(tblName)
|
||||
elif dice == 1:
|
||||
sTable.dropTag(dbc, dbName, "extraTag")
|
||||
sTable.dropTag(dbc, "extraTag")
|
||||
# sql = "alter table db.{} drop tag extraTag".format(tblName)
|
||||
elif dice == 2:
|
||||
sTable.dropTag(dbc, dbName, "newTag")
|
||||
sTable.dropTag(dbc, "newTag")
|
||||
# sql = "alter table db.{} drop tag newTag".format(tblName)
|
||||
else: # dice == 3
|
||||
sTable.changeTag(dbc, dbName, "extraTag", "newTag")
|
||||
sTable.changeTag(dbc, "extraTag", "newTag")
|
||||
# sql = "alter table db.{} change tag extraTag newTag".format(tblName)
|
||||
|
||||
class TaskRestartService(StateTransitionTask):
|
||||
|
@ -1920,15 +1984,17 @@ class TaskAddData(StateTransitionTask):
|
|||
for j in range(numRecords): # number of records per table
|
||||
nextInt = db.getNextInt()
|
||||
nextTick = db.getNextTick()
|
||||
sql += "('{}', {});".format(nextTick, nextInt)
|
||||
nextColor = db.getNextColor()
|
||||
sql += "('{}', {}, '{}');".format(nextTick, nextInt, nextColor)
|
||||
dbc.execute(sql)
|
||||
|
||||
def _addData(self, db, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches
|
||||
def _addData(self, db: Database, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches
|
||||
numRecords = self.LARGE_NUMBER_OF_RECORDS if gConfig.larger_data else self.SMALL_NUMBER_OF_RECORDS
|
||||
|
||||
for j in range(numRecords): # number of records per table
|
||||
nextInt = db.getNextInt()
|
||||
nextTick = db.getNextTick()
|
||||
nextColor = db.getNextColor()
|
||||
if gConfig.record_ops:
|
||||
self.prepToRecordOps()
|
||||
self.fAddLogReady.write("Ready to write {} to {}\n".format(nextInt, regTableName))
|
||||
|
@ -1942,11 +2008,11 @@ class TaskAddData(StateTransitionTask):
|
|||
# print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written
|
||||
|
||||
try:
|
||||
sql = "insert into {} values ('{}', {});".format( # removed: tags ('{}', {})
|
||||
sql = "insert into {} values ('{}', {}, '{}');".format( # removed: tags ('{}', {})
|
||||
fullTableName,
|
||||
# ds.getFixedSuperTableName(),
|
||||
# ds.getNextBinary(), ds.getNextFloat(),
|
||||
nextTick, nextInt)
|
||||
nextTick, nextInt, nextColor)
|
||||
dbc.execute(sql)
|
||||
except: # Any exception at all
|
||||
if gConfig.verify_data:
|
||||
|
@ -1964,10 +2030,10 @@ class TaskAddData(StateTransitionTask):
|
|||
.format(nextInt, readBack), 0x999)
|
||||
except taos.error.ProgrammingError as err:
|
||||
errno = Helper.convertErrno(err.errno)
|
||||
if errno in [0x991, 0x992] : # not a single result
|
||||
if errno in [CrashGenError.INVALID_EMPTY_RESULT, CrashGenError.INVALID_MULTIPLE_RESULT] : # not a single result
|
||||
raise taos.error.ProgrammingError(
|
||||
"Failed to read back same data for tick: {}, wrote: {}, read: {}"
|
||||
.format(nextTick, nextInt, "Empty Result" if errno==0x991 else "Multiple Result"),
|
||||
.format(nextTick, nextInt, "Empty Result" if errno == CrashGenError.INVALID_EMPTY_RESULT else "Multiple Result"),
|
||||
errno)
|
||||
elif errno in [0x218, 0x362]: # table doesn't exist
|
||||
# do nothing
|
||||
|
@ -2000,11 +2066,12 @@ class TaskAddData(StateTransitionTask):
|
|||
else:
|
||||
self.activeTable.add(i) # marking it active
|
||||
|
||||
dbName = db.getName()
|
||||
sTable = db.getFixedSuperTable()
|
||||
regTableName = self.getRegTableName(i) # "db.reg_table_{}".format(i)
|
||||
fullTableName = db.getName() + '.' + regTableName
|
||||
fullTableName = dbName + '.' + regTableName
|
||||
# self._lockTable(fullTableName) # "create table" below. Stop it if the table is "locked"
|
||||
sTable.ensureTable(self, wt.getDbConn(), db.getName(), regTableName) # Ensure the table exists
|
||||
sTable.ensureTable(self, wt.getDbConn(), regTableName) # Ensure the table exists
|
||||
# self._unlockTable(fullTableName)
|
||||
|
||||
if Dice.throw(1) == 0: # 1 in 2 chance
|
||||
|
@ -2024,7 +2091,7 @@ class ThreadStacks: # stack info for all threads
|
|||
self._allStacks[th.native_id] = stack
|
||||
|
||||
def print(self, filteredEndName = None, filterInternal = False):
|
||||
for thNid, stack in self._allStacks.items(): # for each thread
|
||||
for thNid, stack in self._allStacks.items(): # for each thread, stack frames top to bottom
|
||||
lastFrame = stack[-1]
|
||||
if filteredEndName: # we need to filter out stacks that match this name
|
||||
if lastFrame.name == filteredEndName : # end did not match
|
||||
|
@ -2036,9 +2103,9 @@ class ThreadStacks: # stack info for all threads
|
|||
'__init__']: # the thread that extracted the stack
|
||||
continue # ignore
|
||||
# Now print
|
||||
print("\n<----- Thread Info for LWP/ID: {} (Execution stopped at Bottom Frame) <-----".format(thNid))
|
||||
print("\n<----- Thread Info for LWP/ID: {} (most recent call last) <-----".format(thNid))
|
||||
stackFrame = 0
|
||||
for frame in stack:
|
||||
for frame in stack: # was using: reversed(stack)
|
||||
# print(frame)
|
||||
print("[{sf}] File {filename}, line {lineno}, in {name}".format(
|
||||
sf=stackFrame, filename=frame.filename, lineno=frame.lineno, name=frame.name))
|
||||
|
|
|
@ -78,7 +78,7 @@ class DbConn:
|
|||
if nRows != 1:
|
||||
raise taos.error.ProgrammingError(
|
||||
"Unexpected result for query: {}, rows = {}".format(sql, nRows),
|
||||
(0x991 if nRows==0 else 0x992)
|
||||
(CrashGenError.INVALID_EMPTY_RESULT if nRows==0 else CrashGenError.INVALID_MULTIPLE_RESULT)
|
||||
)
|
||||
if self.getResultRows() != 1 or self.getResultCols() != 1:
|
||||
raise RuntimeError("Unexpected result set for query: {}".format(sql))
|
||||
|
@ -349,7 +349,8 @@ class DbConnNative(DbConn):
|
|||
|
||||
def execute(self, sql):
|
||||
if (not self.isOpen):
|
||||
raise RuntimeError("Cannot execute database commands until connection is open")
|
||||
raise CrashGenError(
|
||||
"Cannot exec SQL unless db connection is open", CrashGenError.DB_CONNECTION_NOT_OPEN)
|
||||
Logging.debug("[SQL] Executing SQL: {}".format(sql))
|
||||
self._lastSql = sql
|
||||
nRows = self._tdSql.execute(sql)
|
||||
|
@ -360,8 +361,8 @@ class DbConnNative(DbConn):
|
|||
|
||||
def query(self, sql): # return rows affected
|
||||
if (not self.isOpen):
|
||||
raise RuntimeError(
|
||||
"Cannot query database until connection is open")
|
||||
raise CrashGenError(
|
||||
"Cannot query database until connection is open, restarting?", CrashGenError.DB_CONNECTION_NOT_OPEN)
|
||||
Logging.debug("[SQL] Executing SQL: {}".format(sql))
|
||||
self._lastSql = sql
|
||||
nRows = self._tdSql.query(sql)
|
||||
|
|
|
@ -3,14 +3,20 @@ import random
|
|||
import logging
|
||||
import os
|
||||
|
||||
import taos
|
||||
|
||||
class CrashGenError(Exception):
|
||||
def __init__(self, msg=None, errno=None):
|
||||
self.msg = msg
|
||||
self.errno = errno
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
class CrashGenError(taos.error.ProgrammingError):
|
||||
INVALID_EMPTY_RESULT = 0x991
|
||||
INVALID_MULTIPLE_RESULT = 0x992
|
||||
DB_CONNECTION_NOT_OPEN = 0x993
|
||||
# def __init__(self, msg=None, errno=None):
|
||||
# self.msg = msg
|
||||
# self.errno = errno
|
||||
|
||||
# def __str__(self):
|
||||
# return self.msg
|
||||
pass
|
||||
|
||||
|
||||
class LoggingFilter(logging.Filter):
|
||||
|
@ -168,6 +174,7 @@ class Progress:
|
|||
SERVICE_RECONNECT_FAILURE = 6
|
||||
SERVICE_START_NAP = 7
|
||||
CREATE_TABLE_ATTEMPT = 8
|
||||
QUERY_GROUP_BY = 9
|
||||
|
||||
tokens = {
|
||||
STEP_BOUNDARY: '.',
|
||||
|
@ -178,7 +185,8 @@ class Progress:
|
|||
SERVICE_RECONNECT_SUCCESS: '.r>',
|
||||
SERVICE_RECONNECT_FAILURE: '.xr>',
|
||||
SERVICE_START_NAP: '_zz',
|
||||
CREATE_TABLE_ATTEMPT: '_c',
|
||||
CREATE_TABLE_ATTEMPT: 'c',
|
||||
QUERY_GROUP_BY: 'g',
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -51,10 +51,12 @@ class TdeInstance():
|
|||
def prepareGcovEnv(cls, env):
|
||||
# Ref: https://gcc.gnu.org/onlinedocs/gcc/Cross-profiling.html
|
||||
bPath = cls._getBuildPath() # build PATH
|
||||
numSegments = len(bPath.split('/')) - 1 # "/x/TDengine/build" should yield 3
|
||||
numSegments = numSegments - 1 # DEBUG only
|
||||
env['GCOV_PREFIX'] = bPath + '/svc_gcov'
|
||||
numSegments = len(bPath.split('/')) # "/x/TDengine/build" should yield 3
|
||||
# numSegments += 2 # cover "/src" after build
|
||||
# numSegments = numSegments - 1 # DEBUG only
|
||||
env['GCOV_PREFIX'] = bPath + '/src_s' # Server side source
|
||||
env['GCOV_PREFIX_STRIP'] = str(numSegments) # Strip every element, plus, ENV needs strings
|
||||
# VERY VERY important note: GCOV data collection NOT effective upon SIG_KILL
|
||||
Logging.info("Preparing GCOV environement to strip {} elements and use path: {}".format(
|
||||
numSegments, env['GCOV_PREFIX'] ))
|
||||
|
||||
|
@ -258,14 +260,15 @@ class TdeSubProcess:
|
|||
TdeInstance.prepareGcovEnv(myEnv)
|
||||
|
||||
# print(myEnv)
|
||||
# print(myEnv.items())
|
||||
# print("Starting TDengine with env: ", myEnv.items())
|
||||
# print("Starting TDengine via Shell: {}".format(cmdLineStr))
|
||||
|
||||
useShell = True
|
||||
self.subProcess = subprocess.Popen(
|
||||
' '.join(cmdLine) if useShell else cmdLine,
|
||||
shell=useShell,
|
||||
# svcCmdSingle, shell=True, # capture core dump?
|
||||
# ' '.join(cmdLine) if useShell else cmdLine,
|
||||
# shell=useShell,
|
||||
' '.join(cmdLine),
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
# bufsize=1, # not supported in binary mode
|
||||
|
@ -273,7 +276,8 @@ class TdeSubProcess:
|
|||
env=myEnv
|
||||
) # had text=True, which interferred with reading EOF
|
||||
|
||||
STOP_SIGNAL = signal.SIGKILL # What signal to use (in kill) to stop a taosd process?
|
||||
STOP_SIGNAL = signal.SIGKILL # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process?
|
||||
SIG_KILL_RETCODE = 137 # ref: https://stackoverflow.com/questions/43268156/process-finished-with-exit-code-137-in-pycharm
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
|
@ -321,7 +325,11 @@ class TdeSubProcess:
|
|||
# May throw subprocess.TimeoutExpired exception above, therefore
|
||||
# The process is guranteed to have ended by now
|
||||
self.subProcess = None
|
||||
if retCode != 0: # != (- signal.SIGINT):
|
||||
if retCode == self.SIG_KILL_RETCODE:
|
||||
Logging.info("TSP.stop(): sub proc KILLED, as expected")
|
||||
elif retCode == (- self.STOP_SIGNAL):
|
||||
Logging.info("TSP.stop(), sub process STOPPED, as expected")
|
||||
elif retCode != 0: # != (- signal.SIGINT):
|
||||
Logging.error("TSP.stop(): Failed to stop sub proc properly w/ SIG {}, retCode={}".format(
|
||||
self.STOP_SIGNAL, retCode))
|
||||
else:
|
||||
|
|
|
@ -19,6 +19,7 @@ python3 ./test.py -f insert/randomNullCommit.py
|
|||
python3 insert/retentionpolicy.py
|
||||
python3 ./test.py -f insert/alterTableAndInsert.py
|
||||
python3 ./test.py -f insert/insertIntoTwoTables.py
|
||||
python3 ./test.py -f insert/before_1970.py
|
||||
|
||||
python3 ./test.py -f table/alter_wal0.py
|
||||
python3 ./test.py -f table/column_name.py
|
||||
|
@ -228,6 +229,7 @@ python3 ./test.py -f update/merge_commit_data2.py
|
|||
python3 ./test.py -f update/merge_commit_data2_update0.py
|
||||
python3 ./test.py -f update/merge_commit_last-0.py
|
||||
python3 ./test.py -f update/merge_commit_last.py
|
||||
python3 ./test.py -f update/bug_td2279.py
|
||||
|
||||
# wal
|
||||
python3 ./test.py -f wal/addOldWalTest.py
|
|
@ -0,0 +1,249 @@
|
|||
#!/usr/bin/python3
|
||||
###################################################################
|
||||
# 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
|
||||
#
|
||||
###################################################################
|
||||
# install pip
|
||||
# pip install src/connector/python/linux/python2/
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import time
|
||||
import glob
|
||||
import getopt
|
||||
import subprocess
|
||||
from shutil import which
|
||||
from multipledispatch import dispatch
|
||||
|
||||
|
||||
@dispatch(str, str)
|
||||
def v_print(msg: str, arg: str):
|
||||
if verbose:
|
||||
print(msg % arg)
|
||||
|
||||
|
||||
@dispatch(str, int)
|
||||
def v_print(msg: str, arg: int):
|
||||
if verbose:
|
||||
print(msg % int(arg))
|
||||
|
||||
|
||||
@dispatch(str, int, int)
|
||||
def v_print(msg: str, arg1: int, arg2: int):
|
||||
if verbose:
|
||||
print(msg % (int(arg1), int(arg2)))
|
||||
|
||||
|
||||
@dispatch(str, int, int, int)
|
||||
def v_print(msg: str, arg1: int, arg2: int, arg3: int):
|
||||
if verbose:
|
||||
print(msg % (int(arg1), int(arg2), int(arg3)))
|
||||
|
||||
|
||||
@dispatch(str, int, int, int, int)
|
||||
def v_print(msg: str, arg1: int, arg2: int, arg3: int, arg4: int):
|
||||
if verbose:
|
||||
print(msg % (int(arg1), int(arg2), int(arg3), int(arg4)))
|
||||
|
||||
|
||||
def isHiveMQInstalled():
|
||||
v_print("%s", "Check if HiveMQ installed")
|
||||
defaultHiveMQPath = "/opt/hivemq*"
|
||||
hiveMQDir = glob.glob(defaultHiveMQPath)
|
||||
if (len(hiveMQDir) == 0):
|
||||
v_print("%s", "ERROR: HiveMQ NOT found")
|
||||
return False
|
||||
else:
|
||||
v_print("HiveMQ installed at %s", hiveMQDir[0])
|
||||
return True
|
||||
|
||||
|
||||
def isMosquittoInstalled():
|
||||
v_print("%s", "Check if mosquitto installed")
|
||||
if not which('mosquitto_pub'):
|
||||
v_print("%s", "ERROR: mosquitto is NOT installed")
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def installExtension():
|
||||
currentDir = os.getcwd()
|
||||
extDir = 'src/connector/hivemq-tdengine-extension'
|
||||
os.chdir('../..')
|
||||
os.system('git submodule update --init -- %s' % extDir)
|
||||
os.chdir(extDir)
|
||||
v_print("%s", "build extension..")
|
||||
os.system('mvn clean package')
|
||||
|
||||
tdExtensionZip = 'target/hivemq-tdengine-extension*.zip'
|
||||
tdExtensionZipDir = glob.glob(tdExtensionZip)
|
||||
|
||||
defaultHiveMQPath = "/opt/hivemq*"
|
||||
hiveMQDir = glob.glob(defaultHiveMQPath)
|
||||
extPath = hiveMQDir[0] + '/extensions'
|
||||
|
||||
tdExtDir = glob.glob(extPath + '/hivemq-tdengine-extension')
|
||||
if len(tdExtDir):
|
||||
v_print("%s", "delete exist extension..")
|
||||
os.system('rm -rf %s' % tdExtDir[0])
|
||||
|
||||
v_print("%s", "unzip extension..")
|
||||
os.system('unzip %s -d %s' % (tdExtensionZipDir[0], extPath))
|
||||
|
||||
os.chdir(currentDir)
|
||||
|
||||
|
||||
def stopProgram(prog: str):
|
||||
psCmd = "ps ax|grep -w %s| grep -v grep | awk '{print $1}'" % prog
|
||||
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
while(processID):
|
||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||
os.system(killCmd)
|
||||
time.sleep(1)
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
pass
|
||||
|
||||
|
||||
def stopHiveMQ():
|
||||
stopProgram("hivemq.jar")
|
||||
v_print("%s", "ERROR: HiveMQ is NOT running")
|
||||
|
||||
|
||||
def checkProgramRunning(prog: str):
|
||||
psCmd = "ps ax|grep -w %s| grep -v grep | awk '{print $1}'" % prog
|
||||
|
||||
processID = subprocess.check_output(
|
||||
psCmd, shell=True).decode("utf-8")
|
||||
|
||||
if not processID:
|
||||
v_print("ERROR: %s is NOT running", prog)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
def runHiveMQ():
|
||||
defaultHiveMQPath = "/opt/hivemq*"
|
||||
hiveMQDir = glob.glob(defaultHiveMQPath)
|
||||
runPath = hiveMQDir[0] + '/bin/run.sh > /dev/null &'
|
||||
os.system(runPath)
|
||||
time.sleep(10)
|
||||
|
||||
if not checkProgramRunning("hivemq.jar"):
|
||||
return False
|
||||
else:
|
||||
v_print("%s", "hivemq is running")
|
||||
return True
|
||||
|
||||
|
||||
def getBuildPath():
|
||||
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
binPath = ''
|
||||
|
||||
if ("community" in selfPath):
|
||||
projPath = selfPath[:selfPath.find("community")]
|
||||
else:
|
||||
projPath = selfPath[:selfPath.find("tests")]
|
||||
|
||||
for root, dirs, files in os.walk(projPath):
|
||||
if ("taosd" in files):
|
||||
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||
if ("packaging" not in rootRealPath):
|
||||
binPath = root[:len(root) - len("/build/bin")]
|
||||
break
|
||||
return binPath
|
||||
|
||||
|
||||
def runTDengine():
|
||||
stopProgram("taosd")
|
||||
|
||||
buildPath = getBuildPath()
|
||||
|
||||
if (buildPath == ""):
|
||||
v_print("%s", "ERROR: taosd NOT found!")
|
||||
sys.exit(1)
|
||||
else:
|
||||
v_print("%s", "taosd found in %s" % buildPath)
|
||||
|
||||
binPath = buildPath + "/build/bin/taosd"
|
||||
|
||||
os.system('%s > /dev/null &' % binPath)
|
||||
time.sleep(10)
|
||||
if not checkProgramRunning("taosd"):
|
||||
return False
|
||||
else:
|
||||
v_print("%s", "TDengine is running")
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def reCreateDatabase():
|
||||
buildPath = getBuildPath()
|
||||
binPath = buildPath + "/build/bin/taos"
|
||||
|
||||
os.system('%s -s "DROP DATABASE IF EXISTS hivemq"' % binPath)
|
||||
os.system('%s -s "CREATE DATABASE IF NOT EXISTS hivemq"' % binPath)
|
||||
|
||||
|
||||
def sendMqttMsg(topic: str, payload: str):
|
||||
testStr = 'mosquitto_pub -t %s -m "%s"' % (topic, payload)
|
||||
os.system(testStr)
|
||||
time.sleep(3)
|
||||
|
||||
|
||||
def checkTDengineData(topic: str, payload: str):
|
||||
buildPath = getBuildPath()
|
||||
binPath = buildPath + "/build/bin/taos"
|
||||
|
||||
output = subprocess.check_output(
|
||||
'%s -s "select * from hivemq.mqtt_payload"' %
|
||||
binPath, shell=True).decode('utf-8')
|
||||
if (topic in output) and (payload in output):
|
||||
v_print("%s", output)
|
||||
return True
|
||||
else:
|
||||
v_print("%s", "ERROR: mqtt topic or payload NOT found")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
verbose = True
|
||||
testTopic = 'test'
|
||||
testPayload = 'hello world'
|
||||
|
||||
if not isHiveMQInstalled():
|
||||
sys.exit(1)
|
||||
|
||||
if not isMosquittoInstalled():
|
||||
sys.exit(1)
|
||||
|
||||
stopHiveMQ()
|
||||
|
||||
installExtension()
|
||||
|
||||
if not runTDengine():
|
||||
sys.exit(1)
|
||||
|
||||
reCreateDatabase()
|
||||
|
||||
if not runHiveMQ():
|
||||
sys.exit(1)
|
||||
|
||||
sendMqttMsg(testTopic, testPayload)
|
||||
|
||||
if not checkTDengineData(testTopic, testPayload):
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
|
@ -0,0 +1,67 @@
|
|||
###################################################################
|
||||
# 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
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import *
|
||||
|
||||
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
|
||||
self.ts = 1606700000000
|
||||
|
||||
def restartTaosd(self):
|
||||
tdDnodes.stop(1)
|
||||
tdDnodes.startWithoutSleep(1)
|
||||
tdSql.execute("use db")
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
|
||||
print("==============step1")
|
||||
tdSql.execute("create table t (ts timestamp, a int)")
|
||||
|
||||
for i in range(3276):
|
||||
tdSql.execute("insert into t values(%d, 0)" % (self.ts + i))
|
||||
|
||||
newTs = 1606700010000
|
||||
for i in range(3275):
|
||||
tdSql.execute("insert into t values(%d, 0)" % (self.ts + i))
|
||||
tdSql.execute("insert into t values(%d, 0)" % 1606700013280)
|
||||
|
||||
self.restartTaosd()
|
||||
|
||||
for i in range(1606700003275, 1606700006609):
|
||||
tdSql.execute("insert into t values(%d, 0)" % i)
|
||||
tdSql.execute("insert into t values(%d, 0)" % 1606700006612)
|
||||
|
||||
self.restartTaosd()
|
||||
|
||||
tdSql.execute("insert into t values(%d, 0)" % 1606700006610)
|
||||
tdSql.query("select * from t")
|
||||
tdSql.checkRows(6612)
|
||||
|
||||
tdDnodes.stop(1)
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -24,7 +24,7 @@ sql alter dnode 1 debugFlag 135
|
|||
sql alter dnode 1 debugFlag 131
|
||||
sql alter dnode 1 monitor 0
|
||||
sql alter dnode 1 debugFlag 135
|
||||
sql alter dnode 1 monitorDebugFlag 135
|
||||
sql alter dnode 1 monDebugFlag 135
|
||||
sql alter dnode 1 vDebugFlag 135
|
||||
sql alter dnode 1 mDebugFlag 135
|
||||
sql alter dnode 1 cDebugFlag 135
|
||||
|
@ -44,15 +44,15 @@ sql_error alter dnode 2 tmrDebugFlag 135
|
|||
|
||||
print ======== step3
|
||||
sql_error alter $hostname1 debugFlag 135
|
||||
sql_error alter $hostname1 monitorDebugFlag 135
|
||||
sql_error alter $hostname1 monDebugFlag 135
|
||||
sql_error alter $hostname1 vDebugFlag 135
|
||||
sql_error alter $hostname1 mDebugFlag 135
|
||||
sql_error alter dnode $hostname2 debugFlag 135
|
||||
sql_error alter dnode $hostname2 monitorDebugFlag 135
|
||||
sql_error alter dnode $hostname2 monDebugFlag 135
|
||||
sql_error alter dnode $hostname2 vDebugFlag 135
|
||||
sql_error alter dnode $hostname2 mDebugFlag 135
|
||||
sql alter dnode $hostname1 debugFlag 135
|
||||
sql alter dnode $hostname1 monitorDebugFlag 135
|
||||
sql alter dnode $hostname1 monDebugFlag 135
|
||||
sql alter dnode $hostname1 vDebugFlag 135
|
||||
sql alter dnode $hostname1 tmrDebugFlag 131
|
||||
|
||||
|
|
|
@ -115,13 +115,6 @@ if $data7_db != 20,20,20 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql alter database db keep 10
|
||||
sql show databases
|
||||
print keep $data7_db
|
||||
if $data7_db != 20,20,10 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql alter database db keep 20
|
||||
sql show databases
|
||||
print keep $data7_db
|
||||
|
@ -136,10 +129,17 @@ if $data7_db != 20,20,30 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql alter database db keep 40
|
||||
sql show databases
|
||||
print keep $data7_db
|
||||
if $data7_db != 20,20,40 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql alter database db keep 40
|
||||
sql alter database db keep 30
|
||||
sql alter database db keep 20
|
||||
sql alter database db keep 10
|
||||
sql_error alter database db keep 10
|
||||
sql_error alter database db keep 9
|
||||
sql_error alter database db keep 1
|
||||
sql alter database db keep 0
|
||||
|
|
|
@ -47,6 +47,7 @@ while $i < $tbNum
|
|||
|
||||
$i = $i + 1
|
||||
endw
|
||||
|
||||
$ts = $ts + 60000
|
||||
$tb = $tbPrefix . 0
|
||||
sql insert into $tb (ts) values ( $ts )
|
||||
|
@ -84,4 +85,43 @@ sleep 500
|
|||
|
||||
run general/parser/first_last_query.sim
|
||||
|
||||
print =================> insert data regression test
|
||||
sql create database test keep 36500
|
||||
sql use test
|
||||
sql create table tm0 (ts timestamp, k int)
|
||||
|
||||
print =========================> td-2298
|
||||
$ts0 = 1537146000000
|
||||
$xs = 6000
|
||||
|
||||
$x = 0
|
||||
while $x < 5000
|
||||
$ts = $ts0 + $xs
|
||||
$ts1 = $ts + $xs
|
||||
$x1 = $x + 1
|
||||
|
||||
sql insert into tm0 values ( $ts , $x ) ( $ts1 , $x1 )
|
||||
$x = $x1
|
||||
$ts0 = $ts1
|
||||
endw
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
sleep 3000
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
print ================== server restart completed
|
||||
sql connect
|
||||
sleep 500
|
||||
|
||||
sql use test
|
||||
sql select count(*), last(ts) from tm0 interval(1s)
|
||||
if $rows != 10000 then
|
||||
print expect 10000, actual: $rows
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select last(ts) from tm0 interval(1s)
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -267,3 +267,5 @@ if $data14 != @test2@ then
|
|||
print expect test2 , actual: $data14
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql drop table stest
|
|
@ -0,0 +1,228 @@
|
|||
system sh/stop_dnodes.sh
|
||||
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
||||
system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 500
|
||||
sql connect
|
||||
|
||||
$dbPrefix = m_func_db
|
||||
$tbPrefix = m_func_tb
|
||||
$mtPrefix = m_func_mt
|
||||
|
||||
$tbNum = 10
|
||||
$rowNum = 5
|
||||
$totalNum = $tbNum * $rowNum
|
||||
$ts0 = 1537146000000
|
||||
$delta = 600000
|
||||
print ========== alter.sim
|
||||
$i = 0
|
||||
$db = $dbPrefix . $i
|
||||
$mt = $mtPrefix . $i
|
||||
|
||||
sql drop database if exists $db
|
||||
sql create database $db
|
||||
sql use $db
|
||||
|
||||
print =====================================> test case for twa in single block
|
||||
|
||||
sql create table t1 (ts timestamp, k float);
|
||||
sql insert into t1 values('2015-08-18 00:00:00', 2.064);
|
||||
sql insert into t1 values('2015-08-18 00:06:00', 2.116);
|
||||
sql insert into t1 values('2015-08-18 00:12:00', 2.028);
|
||||
sql insert into t1 values('2015-08-18 00:18:00', 2.126);
|
||||
sql insert into t1 values('2015-08-18 00:24:00', 2.041);
|
||||
sql insert into t1 values('2015-08-18 00:30:00', 2.051);
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:05:00'
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 2.063999891 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.063999891 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:07:00'
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 2.089999914 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.089999914 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:07:00' interval(1m) order by ts asc
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @15-08-18 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.068333156 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 2.063999891 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != @15-08-18 00:06:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 2.115999937 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data12 != 2.115999937 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data13 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:07:00' interval(1m) order by ts desc;
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @15-08-18 00:06:00.00@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.115999937 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 2.115999937 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 2.068333156 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:27:00' interval(10m) order by ts asc
|
||||
if $rows != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.088666666 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 2.089999914 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 2.077099980 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data12 != 2.077000022 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data13 != 2 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data21 != 2.069333235 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data22 != 2.040999889 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data23 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:27:00' interval(10m) order by ts desc
|
||||
if $rows != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.069333235 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 2.077099980 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data21 != 2.088666666 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' order by ts asc
|
||||
if $data00 != 2.073699975 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.070999980 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 6 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' order by ts desc
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 2.073699975 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 2.070999980 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 6 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' interval(10m) order by ts asc
|
||||
sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' interval(10m) order by ts desc
|
||||
|
||||
|
||||
#todo add test case while column filte exists.
|
||||
|
||||
select count(*),TWA(k) from tm0 where ts>='1970-1-1 13:43:00' and ts<='1970-1-1 13:44:10' interval(9s)
|
|
@ -120,7 +120,7 @@ echo "cDebugFlag 143" >> $TAOS_CFG
|
|||
echo "jnidebugFlag 143" >> $TAOS_CFG
|
||||
echo "odbcdebugFlag 143" >> $TAOS_CFG
|
||||
echo "httpDebugFlag 143" >> $TAOS_CFG
|
||||
echo "monitorDebugFlag 143" >> $TAOS_CFG
|
||||
echo "monDebugFlag 143" >> $TAOS_CFG
|
||||
echo "mqttDebugFlag 143" >> $TAOS_CFG
|
||||
echo "qdebugFlag 143" >> $TAOS_CFG
|
||||
echo "rpcDebugFlag 143" >> $TAOS_CFG
|
||||
|
|
Loading…
Reference in New Issue