Merge branch '3.0' into feature/tq

This commit is contained in:
Liu Jicong 2021-10-28 17:33:27 +08:00
commit 4e902908fa
54 changed files with 2796 additions and 2473 deletions

View File

@ -706,41 +706,31 @@ typedef struct {
} SStatusRsp; } SStatusRsp;
typedef struct { typedef struct {
uint32_t vgId; uint16_t port;
int32_t dbCfgVersion; char fqdn[TSDB_FQDN_LEN];
int32_t maxTables;
int32_t cacheBlockSize;
int32_t totalBlocks;
int32_t daysPerFile;
int32_t daysToKeep;
int32_t daysToKeep1;
int32_t daysToKeep2;
int32_t minRowsPerFileBlock;
int32_t maxRowsPerFileBlock;
int32_t commitTime;
int32_t fsyncPeriod;
int8_t precision;
int8_t compression;
int8_t walLevel;
int8_t vgReplica;
int8_t wals;
int8_t quorum;
int8_t update;
int8_t cacheLastRow;
int32_t vgCfgVersion;
int8_t dbReplica;
int8_t dbType;
int8_t reserved[8];
} SVnodeCfg;
typedef struct {
int32_t nodeId;
char nodeEp[TSDB_EP_LEN];
} SVnodeDesc; } SVnodeDesc;
typedef struct { typedef struct {
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
SVnodeCfg cfg; uint32_t vgId;
int32_t cacheBlockSize;
int32_t totalBlocks;
int32_t daysPerFile;
int32_t daysToKeep0;
int32_t daysToKeep1;
int32_t daysToKeep2;
int32_t minRowsPerFileBlock;
int32_t maxRowsPerFileBlock;
int32_t fsyncPeriod;
int8_t reserved[16];
int8_t precision;
int8_t compression;
int8_t cacheLastRow;
int8_t update;
int8_t walLevel;
int8_t replica;
int8_t quorum;
int8_t selfIndex;
SVnodeDesc nodes[TSDB_MAX_REPLICA]; SVnodeDesc nodes[TSDB_MAX_REPLICA];
} SCreateVnodeMsg, SAlterVnodeMsg; } SCreateVnodeMsg, SAlterVnodeMsg;

View File

@ -308,7 +308,7 @@ static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSche
SET_DOUBLE_PTR(pData, value); SET_DOUBLE_PTR(pData, value);
break; break;
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP:
if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
*(TSKEY *)pData = tdGetKey(*(TKEY *)value); *(TSKEY *)pData = tdGetKey(*(TKEY *)value);
} else { } else {
*(TSKEY *)pData = *(TSKEY *)value; *(TSKEY *)pData = *(TSKEY *)value;

View File

@ -23,6 +23,8 @@ extern "C" {
#include "taosdef.h" #include "taosdef.h"
#include "taosmsg.h" #include "taosmsg.h"
#define TIME_IS_VAR_DURATION(_t) ((_t) == 'n' || (_t) == 'y' || (_t) == 'N' || (_t) == 'Y')
/* /*
* @return timestamp decided by global conf variable, tsTimePrecision * @return timestamp decided by global conf variable, tsTimePrecision
* if precision == TSDB_TIME_PRECISION_MICRO, it returns timestamp in microsecond. * if precision == TSDB_TIME_PRECISION_MICRO, it returns timestamp in microsecond.
@ -50,7 +52,6 @@ void deltaToUtcInitOnce();
int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision); int64_t convertTimePrecision(int64_t time, int32_t fromPrecision, int32_t toPrecision);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef TDENGINE_TFUNCTION_H #ifndef TDENGINE_FUNCTION_H
#define TDENGINE_TFUNCTION_H #define TDENGINE_FUNCTION_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -24,6 +24,8 @@ extern "C" {
#include "tvariant.h" #include "tvariant.h"
#include "tbuffer.h" #include "tbuffer.h"
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
#define FUNCTION_SCALAR 1 #define FUNCTION_SCALAR 1
#define FUNCTION_AGG 2 #define FUNCTION_AGG 2
@ -184,6 +186,25 @@ typedef struct SResultDataInfo {
int32_t intermediateBytes; int32_t intermediateBytes;
} SResultDataInfo; } SResultDataInfo;
typedef struct SMultiFunctionsDesc {
bool stableQuery;
bool groupbyColumn;
bool simpleAgg;
bool arithmeticOnAgg;
bool projectionQuery;
bool hasFilter;
bool onlyTagQuery;
bool orderProjectQuery;
bool stateWindow;
bool globalMerge;
bool multigroupResult;
bool blockDistribution;
bool timewindow;
bool topbotQuery;
bool interpQuery;
} SMultiFunctionsDesc;
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength, int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
bool isSuperTable); bool isSuperTable);
@ -199,8 +220,10 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct
const char* qGetFunctionName(int32_t functionId); const char* qGetFunctionName(int32_t functionId);
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // TDENGINE_TFUNCTION_H #endif // TDENGINE_FUNCTION_H

View File

@ -24,6 +24,7 @@ extern "C" {
#include "common.h" #include "common.h"
#include "tname.h" #include "tname.h"
#include "tvariant.h" #include "tvariant.h"
#include "function.h"
typedef struct SColumn { typedef struct SColumn {
uint64_t tableUid; uint64_t tableUid;
@ -130,20 +131,6 @@ typedef struct STableMetaInfo {
SArray *tagColList; // SArray<SColumn*>, involved tag columns SArray *tagColList; // SArray<SColumn*>, involved tag columns
} STableMetaInfo; } STableMetaInfo;
typedef struct SQueryAttrInfo {
bool stableQuery;
bool groupbyColumn;
bool simpleAgg;
bool arithmeticOnAgg;
bool projectionQuery;
bool hasFilter;
bool onlyTagQuery;
bool orderProjectQuery;
bool stateWindow;
bool globalMerge;
bool multigroupResult;
} SQueryAttrInfo;
typedef struct SQueryStmtInfo { typedef struct SQueryStmtInfo {
int16_t command; // the command may be different for each subclause, so keep it seperately. int16_t command; // the command may be different for each subclause, so keep it seperately.
uint32_t type; // query/insert type uint32_t type; // query/insert type
@ -177,7 +164,6 @@ typedef struct SQueryStmtInfo {
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
bool distinct; // distinct tag or not bool distinct; // distinct tag or not
bool onlyHasTagCond;
int32_t bufLen; int32_t bufLen;
char* buf; char* buf;
SArray *pUdfInfo; SArray *pUdfInfo;
@ -186,7 +172,7 @@ typedef struct SQueryStmtInfo {
SArray *pUpstream; // SArray<struct SQueryStmtInfo> SArray *pUpstream; // SArray<struct SQueryStmtInfo>
struct SQueryStmtInfo *pDownstream; struct SQueryStmtInfo *pDownstream;
int32_t havingFieldNum; int32_t havingFieldNum;
SQueryAttrInfo info; SMultiFunctionsDesc info;
} SQueryStmtInfo; } SQueryStmtInfo;
typedef struct SColumnIndex { typedef struct SColumnIndex {

View File

@ -22,11 +22,10 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include "taosdef.h" #include "taosdef.h"
#include "wal.h"
typedef int64_t SyncNodeId; typedef int32_t SyncNodeId;
typedef int32_t SyncGroupId; typedef int32_t SyncGroupId;
typedef int64_t SyncIndex; typedef int64_t SyncIndex;
typedef uint64_t SSyncTerm; typedef uint64_t SSyncTerm;
typedef enum { typedef enum {
@ -41,41 +40,42 @@ typedef struct {
} SSyncBuffer; } SSyncBuffer;
typedef struct { typedef struct {
uint16_t nodePort; // node sync Port SyncNodeId nodeId;
char nodeFqdn[TSDB_FQDN_LEN]; // node FQDN uint16_t nodePort; // node sync Port
char nodeFqdn[TSDB_FQDN_LEN]; // node FQDN
} SNodeInfo; } SNodeInfo;
typedef struct { typedef struct {
int selfIndex; int32_t selfIndex;
int nNode; int32_t replica;
SNodeInfo* nodeInfo; SNodeInfo nodeInfo[TSDB_MAX_REPLICA];
} SSyncCluster; } SSyncCluster;
typedef struct { typedef struct {
int32_t selfIndex; int32_t selfIndex;
int nNode; int32_t replica;
SNodeInfo* node; SNodeInfo node[TSDB_MAX_REPLICA];
ESyncRole* role; ESyncRole role[TSDB_MAX_REPLICA];
} SNodesRole; } SNodesRole;
typedef struct SSyncFSM { typedef struct SSyncFSM {
void* pData; void* pData;
// apply committed log, bufs will be free by raft module // apply committed log, bufs will be free by raft module
int (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData); int32_t (*applyLog)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf, void* pData);
// cluster commit callback // cluster commit callback
int (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData); int32_t (*onClusterChanged)(struct SSyncFSM* fsm, const SSyncCluster* cluster, void* pData);
// fsm return snapshot in ppBuf, bufs will be free by raft module // fsm return snapshot in ppBuf, bufs will be free by raft module
// TODO: getSnapshot SHOULD be async? // TODO: getSnapshot SHOULD be async?
int (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int* objId, bool* isLast); int32_t (*getSnapshot)(struct SSyncFSM* fsm, SSyncBuffer** ppBuf, int32_t* objId, bool* isLast);
// fsm apply snapshot with pBuf data // fsm apply snapshot with pBuf data
int (*applySnapshot)(struct SSyncFSM* fsm, SSyncBuffer* pBuf, int objId, bool isLast); int32_t (*applySnapshot)(struct SSyncFSM* fsm, SSyncBuffer* pBuf, int32_t objId, bool isLast);
// call when restore snapshot and log done // call when restore snapshot and log done
int (*onRestoreDone)(struct SSyncFSM* fsm); int32_t (*onRestoreDone)(struct SSyncFSM* fsm);
void (*onRollback)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf); void (*onRollback)(struct SSyncFSM* fsm, SyncIndex index, const SSyncBuffer* buf);
@ -83,52 +83,79 @@ typedef struct SSyncFSM {
} SSyncFSM; } SSyncFSM;
typedef struct SSyncLogStore {
void* pData;
// write log with given index
int32_t (*logWrite)(struct SSyncLogStore* logStore, SyncIndex index, SSyncBuffer* pBuf);
// mark log with given index has been commtted
int32_t (*logCommit)(struct SSyncLogStore* logStore, SyncIndex index);
// prune log before given index
int32_t (*logPrune)(struct SSyncLogStore* logStore, SyncIndex index);
// rollback log after given index
int32_t (*logRollback)(struct SSyncLogStore* logStore, SyncIndex index);
} SSyncLogStore;
typedef struct SSyncServerState { typedef struct SSyncServerState {
SNodeInfo voteFor; SyncNodeId voteFor;
SSyncTerm term; SSyncTerm term;
} SSyncServerState; } SSyncServerState;
typedef struct SSyncClusterConfig {
// Log index number of current cluster config.
SyncIndex index;
// Log index number of previous cluster config.
SyncIndex prevIndex;
// current cluster
const SSyncCluster* cluster;
} SSyncClusterConfig;
typedef struct SStateManager { typedef struct SStateManager {
void* pData; void* pData;
void (*saveServerState)(struct SStateManager* stateMng, const SSyncServerState* state); int32_t (*saveServerState)(struct SStateManager* stateMng, SSyncServerState* state);
const SSyncServerState* (*readServerState)(struct SStateManager* stateMng); int32_t (*readServerState)(struct SStateManager* stateMng, SSyncServerState* state);
void (*saveCluster)(struct SStateManager* stateMng, const SSyncCluster* cluster); // void (*saveCluster)(struct SStateManager* stateMng, const SSyncClusterConfig* cluster);
const SSyncCluster* (*readCluster)(struct SStateManager* stateMng); // const SSyncClusterConfig* (*readCluster)(struct SStateManager* stateMng);
} SStateManager; } SStateManager;
typedef struct { typedef struct {
SyncGroupId vgId; SyncGroupId vgId;
SyncIndex snapshotIndex;
twalh walHandle; SSyncCluster syncCfg;
SSyncFSM fsm;
SyncIndex snapshotIndex; SSyncLogStore logStore;
SSyncCluster syncCfg;
SSyncFSM fsm;
SStateManager stateManager; SStateManager stateManager;
} SSyncInfo; } SSyncInfo;
struct SSyncNode;
typedef struct SSyncNode SSyncNode;
int32_t syncInit(); int32_t syncInit();
void syncCleanUp(); void syncCleanUp();
SyncNodeId syncStart(const SSyncInfo*); SSyncNode* syncStart(const SSyncInfo*);
void syncStop(SyncNodeId); void syncReconfig(const SSyncNode*, const SSyncCluster*);
void syncStop(const SSyncNode*);
int32_t syncPropose(SyncNodeId nodeId, SSyncBuffer buffer, void* pData, bool isWeak); int32_t syncPropose(SSyncNode* syncNode, SSyncBuffer buffer, void* pData, bool isWeak);
int32_t syncAddNode(SyncNodeId nodeId, const SNodeInfo *pNode); // int32_t syncAddNode(SSyncNode syncNode, const SNodeInfo *pNode);
int32_t syncRemoveNode(SyncNodeId nodeId, const SNodeInfo *pNode); // int32_t syncRemoveNode(SSyncNode syncNode, const SNodeInfo *pNode);
extern int32_t syncDebugFlag; extern int32_t syncDebugFlag;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /*_TD_LIBS_SYNC_H*/ #endif /*_TD_LIBS_SYNC_H*/

View File

@ -44,41 +44,41 @@ typedef struct {
EWalType walLevel; // wal level EWalType walLevel; // wal level
} SWalCfg; } SWalCfg;
typedef void * twalh; // WAL HANDLE struct SWal;
typedef int32_t FWalWrite(void *ahandle, void *pHead, int32_t qtype, void *pMsg); typedef struct SWal SWal; // WAL HANDLE
typedef int32_t (*FWalWrite)(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
//module initialization // module initialization
int32_t walInit(); int32_t walInit();
void walCleanUp(); void walCleanUp();
//handle open and ctl // handle open and ctl
twalh walOpen(char *path, SWalCfg *pCfg); SWal *walOpen(char *path, SWalCfg *pCfg);
int32_t walAlter(twalh, SWalCfg *pCfg); int32_t walAlter(SWal *, SWalCfg *pCfg);
void walStop(twalh); void walClose(SWal *);
void walClose(twalh);
//write // write
//int64_t walWriteWithMsgType(twalh, int8_t msgType, void* body, int32_t bodyLen); // int64_t walWriteWithMsgType(SWal*, int8_t msgType, void* body, int32_t bodyLen);
int64_t walWrite(twalh, void* body, int32_t bodyLen); int64_t walWrite(SWal *, int64_t index, void *body, int32_t bodyLen);
int64_t walWriteBatch(twalh, void** bodies, int32_t* bodyLen, int32_t batchSize); int64_t walWriteBatch(SWal *, void **bodies, int32_t *bodyLen, int32_t batchSize);
//apis for lifecycle management // apis for lifecycle management
void walFsync(twalh, bool force); void walFsync(SWal *, bool force);
int32_t walCommit(twalh, int64_t ver); int32_t walCommit(SWal *, int64_t ver);
//truncate after // truncate after
int32_t walRollback(twalh, int64_t ver); int32_t walRollback(SWal *, int64_t ver);
//notify that previous log can be pruned safely // notify that previous log can be pruned safely
int32_t walPrune(twalh, int64_t ver); int32_t walPrune(SWal *, int64_t ver);
//read // read
int32_t walRead(twalh, SWalHead **, int64_t ver); int32_t walRead(SWal *, SWalHead **, int64_t ver);
int32_t walReadWithFp(twalh, FWalWrite writeFp, int64_t verStart, int readNum); int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum);
//lifecycle check // lifecycle check
int32_t walFirstVer(twalh); int32_t walFirstVer(SWal *);
int32_t walPersistedVer(twalh); int32_t walPersistedVer(SWal *);
int32_t walLastVer(twalh); int32_t walLastVer(SWal *);
//int32_t walDataCorrupted(twalh); // int32_t walDataCorrupted(SWal*);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -67,6 +67,11 @@ void dnodeSendRedirectMsg(struct SRpcMsg *rpcMsg, bool forShell);
*/ */
void dnodeGetEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port); void dnodeGetEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
/**
* Report the startup progress.
*/
void dnodeReportStartup(char *name, char *desc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -46,6 +46,11 @@ typedef struct {
*/ */
void (*GetDnodeEp)(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port); void (*GetDnodeEp)(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
/**
* Report the startup progress.
*/
void (*ReportStartup)(char *name, char *desc);
} SVnodeFp; } SVnodeFp;
typedef struct { typedef struct {

View File

@ -233,11 +233,11 @@ int32_t* taosGetErrno();
#define TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR TAOS_DEF_ERROR_CODE(0, 0x0507) //"Missing data file") #define TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR TAOS_DEF_ERROR_CODE(0, 0x0507) //"Missing data file")
#define TSDB_CODE_VND_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0508) //"Out of memory") #define TSDB_CODE_VND_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x0508) //"Out of memory")
#define TSDB_CODE_VND_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0509) //"Unexpected generic error in vnode") #define TSDB_CODE_VND_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0509) //"Unexpected generic error in vnode")
#define TSDB_CODE_VND_INVALID_VRESION_FILE TAOS_DEF_ERROR_CODE(0, 0x050A) //"Invalid version file") #define TSDB_CODE_VND_INVALID_CFG_FILE TAOS_DEF_ERROR_CODE(0, 0x050A) //"Invalid config file)
#define TSDB_CODE_VND_IS_FULL TAOS_DEF_ERROR_CODE(0, 0x050B) //"Database memory is full for commit failed") #define TSDB_CODE_VND_INVALID_TERM_FILE TAOS_DEF_ERROR_CODE(0, 0x050B) //"Invalid term file")
#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit") #define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full")
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping") #define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing") #define TSDB_CODE_VND_IS_UPDATING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is updating")
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing") #define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing")
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended") #define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied") #define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")

View File

@ -303,7 +303,7 @@ do { \
#define TSDB_MAX_FIELD_LEN 16384 #define TSDB_MAX_FIELD_LEN 16384
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384 #define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
#define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384 #define TSDB_MAX_NCHAR_LEN (TSDB_MAX_FIELD_LEN-TSDB_KEYSIZE) // keep 16384
#define PRIMARYKEY_TIMESTAMP_COL_INDEX 0 #define PRIMARYKEY_TIMESTAMP_COL_ID 0
#define TSDB_MAX_RPC_THREADS 5 #define TSDB_MAX_RPC_THREADS 5
@ -382,6 +382,9 @@ do { \
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes #define TSDB_DATA_TYPE_UINT 13 // 4 bytes
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes #define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED };
enum { TRANS_OPER_INIT = 0, TRANS_OPER_EXECUTE, TRANS_OPER_ROLLBACK };
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -48,7 +48,7 @@
* An encoding of midnight at the end of the day as 24:00:00 - ie. midnight * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
* tomorrow - (allowable under ISO 8601) is supported. * tomorrow - (allowable under ISO 8601) is supported.
*/ */
int64_t user_mktime64(const unsigned int year0, const unsigned int mon0, static int64_t user_mktime64(const unsigned int year0, const unsigned int mon0,
const unsigned int day, const unsigned int hour, const unsigned int day, const unsigned int hour,
const unsigned int min, const unsigned int sec, int64_t time_zone) const unsigned int min, const unsigned int sec, int64_t time_zone)
{ {
@ -79,19 +79,18 @@ void deltaToUtcInitOnce() {
(void)strptime("1970-01-01 00:00:00", (const char *)("%Y-%m-%d %H:%M:%S"), &tm); (void)strptime("1970-01-01 00:00:00", (const char *)("%Y-%m-%d %H:%M:%S"), &tm);
m_deltaUtc = (int64_t)mktime(&tm); m_deltaUtc = (int64_t)mktime(&tm);
//printf("====delta:%lld\n\n", seconds); //printf("====delta:%lld\n\n", seconds);
return;
} }
static int64_t parseFraction(char* str, char** end, int32_t timePrec); static int64_t parseFraction(char* str, char** end, int32_t timePrec);
static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim); static int32_t parseTimeWithTz(char* timestr, int64_t* time, int32_t timePrec, char delim);
static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec); static int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec);
static int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec); static int32_t parseLocaltimeDst(char* timestr, int64_t* time, int32_t timePrec);
static char* forwardToTimeStringEnd(char* str); static char* forwardToTimeStringEnd(char* str);
static bool checkTzPresent(char *str, int32_t len); static bool checkTzPresent(char *str, int32_t len);
static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = { static int32_t (*parseLocaltimeFp[]) (char* timestr, int64_t* time, int32_t timePrec) = {
parseLocaltime, parseLocaltime,
parseLocaltimeWithDst parseLocaltimeDst
}; };
int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) { int32_t taosParseTime(char* timestr, int64_t* time, int32_t len, int32_t timePrec, int8_t day_light) {
@ -116,8 +115,8 @@ bool checkTzPresent(char *str, int32_t len) {
} }
c--; c--;
} }
return false;
return false;
} }
char* forwardToTimeStringEnd(char* str) { char* forwardToTimeStringEnd(char* str) {
@ -344,7 +343,7 @@ int32_t parseLocaltime(char* timestr, int64_t* time, int32_t timePrec) {
return 0; return 0;
} }
int32_t parseLocaltimeWithDst(char* timestr, int64_t* time, int32_t timePrec) { int32_t parseLocaltimeDst(char* timestr, int64_t* time, int32_t timePrec) {
*time = 0; *time = 0;
struct tm tm = {0}; struct tm tm = {0};
tm.tm_isdst = -1; tm.tm_isdst = -1;

View File

@ -7,6 +7,6 @@ target_include_directories(
) )
target_link_libraries( target_link_libraries(
function function
PRIVATE os util common PRIVATE os util common
) )

View File

@ -56,8 +56,6 @@ typedef struct SResultRowCellInfo {
#define QUERY_DESC_FORWARD_STEP -1 #define QUERY_DESC_FORWARD_STEP -1
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP) #define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
#define TOP_BOTTOM_QUERY_LIMIT 100 #define TOP_BOTTOM_QUERY_LIMIT 100
enum { enum {

View File

@ -513,7 +513,7 @@ static void count_func_merge(SQLFunctionCtx *pCtx) {
* @return * @return
*/ */
int32_t countRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) { int32_t countRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
if (colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { if (colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
return BLK_DATA_NO_NEEDED; return BLK_DATA_NO_NEEDED;
} else { } else {
return BLK_DATA_STATIS_NEEDED; return BLK_DATA_STATIS_NEEDED;
@ -2303,10 +2303,10 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
tValuePair **tvp = pRes->res; tValuePair **tvp = pRes->res;
// user specify the order of output by sort the result according to timestamp // user specify the order of output by sort the result according to timestamp
if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) { if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_ID) {
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn; __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
} else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX)*/ { } else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_ID)*/ {
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn; __compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator); qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
} }

View File

@ -128,18 +128,26 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
if (*pExpr == NULL) { if (*pExpr == NULL) {
return; return;
} }
if ((*pExpr)->nodeType == TEXPR_BINARYEXPR_NODE) { int32_t type = (*pExpr)->nodeType;
if (type == TEXPR_BINARYEXPR_NODE) {
doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp); doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
doExprTreeDestroy(&(*pExpr)->_node.pRight, fp); doExprTreeDestroy(&(*pExpr)->_node.pRight, fp);
if (fp != NULL) { if (fp != NULL) {
fp((*pExpr)->_node.info); fp((*pExpr)->_node.info);
} }
} else if ((*pExpr)->nodeType == TEXPR_VALUE_NODE) { } else if (type == TEXPR_UNARYEXPR_NODE) {
doExprTreeDestroy(&(*pExpr)->_node.pLeft, fp);
if (fp != NULL) {
fp((*pExpr)->_node.info);
}
assert((*pExpr)->_node.pRight == NULL);
} else if (type == TEXPR_VALUE_NODE) {
taosVariantDestroy((*pExpr)->pVal); taosVariantDestroy((*pExpr)->pVal);
free((*pExpr)->pVal); free((*pExpr)->pVal);
} else if ((*pExpr)->nodeType == TEXPR_COL_NODE) { } else if (type == TEXPR_COL_NODE) {
free((*pExpr)->pSchema); free((*pExpr)->pSchema);
} }

View File

@ -52,7 +52,7 @@ bool isTagsQuery(SArray* pFunctionIdList) {
int16_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); int16_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
// "select count(tbname)" query // "select count(tbname)" query
// if (functId == FUNCTION_COUNT && pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { // if (functId == FUNCTION_COUNT && pExpr->base.colpDesc->colId == TSDB_TBNAME_COLUMN_INDEX) {
// continue; // continue;
// } // }
@ -80,19 +80,6 @@ bool isTagsQuery(SArray* pFunctionIdList) {
// return false; // return false;
//} //}
bool isBlockInfoQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
if (f == FUNCTION_BLKINFO) {
return true;
}
}
return false;
}
bool isProjectionQuery(SArray* pFunctionIdList) { bool isProjectionQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) { for (int32_t i = 0; i < num; ++i) {
@ -101,8 +88,12 @@ bool isProjectionQuery(SArray* pFunctionIdList) {
continue; continue;
} }
if (f != FUNCTION_PRJ && f != FUNCTION_TAGPRJ && f != FUNCTION_TAG && if (f != FUNCTION_PRJ &&
f != FUNCTION_TS && f != FUNCTION_ARITHM && f != FUNCTION_DIFF && f != FUNCTION_TAGPRJ &&
f != FUNCTION_TAG &&
f != FUNCTION_TS &&
f != FUNCTION_ARITHM &&
f != FUNCTION_DIFF &&
f != FUNCTION_DERIVATIVE) { f != FUNCTION_DERIVATIVE) {
return false; return false;
} }
@ -111,7 +102,7 @@ bool isProjectionQuery(SArray* pFunctionIdList) {
return true; return true;
} }
bool isDiffDerivQuery(SArray* pFunctionIdList) { bool isDiffDerivativeQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) { for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
@ -127,7 +118,7 @@ bool isDiffDerivQuery(SArray* pFunctionIdList) {
return false; return false;
} }
bool isPointInterpQuery(SArray* pFunctionIdList) { bool isInterpQuery(SArray* pFunctionIdList) {
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
for (int32_t i = 0; i < num; ++i) { for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i); int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
@ -264,8 +255,6 @@ bool needReverseScan(SArray* pFunctionIdList) {
} }
bool isSimpleAggregateRv(SArray* pFunctionIdList) { bool isSimpleAggregateRv(SArray* pFunctionIdList) {
assert(0);
// if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) { // if (pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0) {
// return false; // return false;
// } // }
@ -380,33 +369,17 @@ bool isProjectionQueryOnSTable(SArray* pFunctionIdList, int32_t tableIndex) {
} }
bool hasTagValOutput(SArray* pFunctionIdList) { bool hasTagValOutput(SArray* pFunctionIdList) {
// size_t numOfExprs = getNumOfExprs(pQueryInfo); size_t size = taosArrayGetSize(pFunctionIdList);
// SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0);
// // if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) {
// if (numOfExprs == 1 && pExpr1->base.functionId == FUNCTION_TS_COMP) {
// return true; // return true;
// }
//
// for (int32_t i = 0; i < numOfExprs; ++i) {
// SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
// if (pExpr == NULL) {
// continue;
// }
//
// // ts_comp column required the tag value for join filter
// if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) {
// return true;
// }
// } // }
return false; for (int32_t i = 0; i < size; ++i) {
} int32_t functionId = *(int16_t*) taosArrayGet(pFunctionIdList, i);
bool timeWindowInterpoRequired(SArray* pFunctionIdList) { // ts_comp column required the tag value for join filter
int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList); if (functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
for (int32_t i = 0; i < num; ++i) {
int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
if (f == FUNCTION_TWA || f == FUNCTION_INTERP) {
return true; return true;
} }
} }
@ -414,8 +387,28 @@ bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
return false; return false;
} }
//SQueryAttrInfo setQueryType(SArray* pFunctionIdList) { //bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
// assert(pFunctionIdList != NULL); // int32_t num = (int32_t) taosArrayGetSize(pFunctionIdList);
// for (int32_t i = 0; i < num; ++i) {
// int32_t f = *(int16_t*) taosArrayGet(pFunctionIdList, i);
// if (f == FUNCTION_TWA || f == FUNCTION_INTERP) {
// return true;
// }
// }
// //
// // return false;
//} //}
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc) {
assert(pFunctionIdList != NULL);
pDesc->blockDistribution = isBlockDistQuery(pFunctionIdList);
if (pDesc->blockDistribution) {
return;
}
pDesc->projectionQuery = isProjectionQuery(pFunctionIdList);
pDesc->onlyTagQuery = isTagsQuery(pFunctionIdList);
pDesc->interpQuery = isInterpQuery(pFunctionIdList);
}

View File

@ -298,7 +298,7 @@ void* destroyCreateTableSql(SCreateTableSql* pCreate);
void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken); void setDropFuncInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken);
void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPath, SField *output, SToken* bufSize, int32_t funcType); void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPath, SField *output, SToken* bufSize, int32_t funcType);
void SqlInfoDestroy(SSqlInfo *pInfo); void destroySqlInfo(SSqlInfo *pInfo);
void setDCLSqlElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...); void setDCLSqlElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...);
void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken, SToken* existsCheck,int16_t dbType,int16_t tableType); void setDropDbTableInfo(SSqlInfo *pInfo, int32_t type, SToken* pToken, SToken* existsCheck,int16_t dbType,int16_t tableType);

View File

@ -73,7 +73,9 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf); int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
void initQueryInfo(SQueryStmtInfo* pQueryInfo); SQueryStmtInfo* createQueryInfo();
void destroyQueryInfo(SQueryStmtInfo* pQueryInfo);
int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf); int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
@ -87,6 +89,12 @@ int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
*/ */
int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen); int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen);
/**
* Destroy the meta data request structure.
* @param pMetaInfo
*/
void qParserClearupMetaRequestInfo(SMetaReq* pMetaInfo);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -30,9 +30,7 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta);
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex); SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo); size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
//SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema); SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
void destroyExprInfoList();
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo); void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize); void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
@ -42,9 +40,11 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
int32_t getExprFunctionId(SExprInfo *pExprInfo);
void cleanupFieldInfo(SFieldInfo* pFieldInfo); void cleanupFieldInfo(SFieldInfo* pFieldInfo);
STableComInfo getTableInfo(const STableMeta* pTableMeta); STableComInfo getTableInfo(const STableMeta* pTableMeta);
SArray* extractFunctionIdList(SArray* pExprInfoList);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -242,7 +242,6 @@ tSqlExpr *tSqlExprClone(tSqlExpr *pSrc) {
} }
void tSqlExprCompact(tSqlExpr **pExpr) { void tSqlExprCompact(tSqlExpr **pExpr) {
if (*pExpr == NULL || tSqlExprIsParentOfLeaf(*pExpr)) { if (*pExpr == NULL || tSqlExprIsParentOfLeaf(*pExpr)) {
return; return;
} }
@ -770,8 +769,11 @@ void setCreateFuncInfo(SSqlInfo *pInfo, int32_t type, SToken *pName, SToken *pPa
} }
} }
void SqlInfoDestroy(SSqlInfo *pInfo) { void destroySqlInfo(SSqlInfo *pInfo) {
if (pInfo == NULL) return;; if (pInfo == NULL) {
return;
}
taosArrayDestroy(pInfo->funcs); taosArrayDestroy(pInfo->funcs);
if (pInfo->type == TSDB_SQL_SELECT) { if (pInfo->type == TSDB_SQL_SELECT) {
destroyAllSqlNode(pInfo->list); destroyAllSqlNode(pInfo->list);

File diff suppressed because it is too large Load Diff

View File

@ -185,4 +185,13 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
} }
return code; return code;
} }
void qParserClearupMetaRequestInfo(SMetaReq* pMetaReq) {
if (pMetaReq == NULL) {
return;
}
taosArrayDestroy(pMetaReq->pTableName);
taosArrayDestroy(pMetaReq->pUdf);
}

View File

@ -576,13 +576,6 @@ TAOS_FIELD* getFieldInfo(SFieldInfo* pFieldInfo, int32_t index) {
return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field; return &((SInternalField*)TARRAY_GET_ELEM(pFieldInfo->internalField, index))->field;
} }
int16_t getFieldInfoOffset(SQueryStmtInfo* pQueryInfo, int32_t index) {
SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, index);
assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL);
return 0;
// return pInfo->pExpr->base.offset;
}
int32_t fieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) { int32_t fieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2, int32_t *diffSize) {
assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL); assert(pFieldInfo1 != NULL && pFieldInfo2 != NULL);
@ -780,8 +773,8 @@ SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid
} }
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) { SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) {
SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_ID};
return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s); return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_ID, tableUid, &s);
} }
void columnCopy(SColumn* pDest, const SColumn* pSrc); void columnCopy(SColumn* pDest, const SColumn* pSrc);

View File

@ -1,4 +1,5 @@
#include "queryInfoUtil.h" #include "queryInfoUtil.h"
#include <function.h>
#include "astGenerator.h" #include "astGenerator.h"
#include "function.h" #include "function.h"
#include "os.h" #include "os.h"
@ -55,7 +56,6 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
} }
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) { static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) {
if (pColumnNode == NULL) { if (pColumnNode == NULL) {
pColumnNode = calloc(1, sizeof(tExprNode)); pColumnNode = calloc(1, sizeof(tExprNode));
pColumnNode->nodeType = TEXPR_COL_NODE; pColumnNode->nodeType = TEXPR_COL_NODE;
@ -167,6 +167,10 @@ SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
void destroyExprInfo(SExprInfo* pExprInfo) { void destroyExprInfo(SExprInfo* pExprInfo) {
tExprTreeDestroy(pExprInfo->pExpr, NULL); tExprTreeDestroy(pExprInfo->pExpr, NULL);
for(int32_t i = 0; i < pExprInfo->base.numOfParams; ++i) {
taosVariantDestroy(&pExprInfo->base.param[i]);
}
tfree(pExprInfo); tfree(pExprInfo);
} }
@ -192,6 +196,11 @@ void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt
assert(pExpr->numOfParams <= 3); assert(pExpr->numOfParams <= 3);
} }
int32_t getExprFunctionId(SExprInfo *pExprInfo) {
assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
return pExprInfo->pExpr->_node.functionId;
}
void assignExprInfo(SExprInfo* dst, const SExprInfo* src) { void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
assert(dst != NULL && src != NULL); assert(dst != NULL && src != NULL);
@ -284,62 +293,11 @@ int32_t getResRowLength(SArray* pExprList) {
return size; return size;
} }
static void freeQueryInfoImpl(SQueryStmtInfo* pQueryInfo) {
cleanupTagCond(&pQueryInfo->tagCond);
cleanupColumnCond(&pQueryInfo->colCond);
cleanupFieldInfo(&pQueryInfo->fieldsInfo);
dropAllExprInfo(pQueryInfo->exprList);
pQueryInfo->exprList = NULL;
if (pQueryInfo->exprList1 != NULL) {
dropAllExprInfo(pQueryInfo->exprList1);
pQueryInfo->exprList1 = NULL;
}
columnListDestroy(pQueryInfo->colList);
pQueryInfo->colList = NULL;
if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
taosArrayDestroy(pQueryInfo->groupbyExpr.columnInfo);
pQueryInfo->groupbyExpr.columnInfo = NULL;
}
pQueryInfo->fillType = 0;
tfree(pQueryInfo->fillVal);
tfree(pQueryInfo->buf);
taosArrayDestroy(pQueryInfo->pUpstream);
pQueryInfo->pUpstream = NULL;
pQueryInfo->bufLen = 0;
}
void freeQueryInfo(SQueryStmtInfo* pQueryInfo, bool removeCachedMeta, uint64_t id) {
while(pQueryInfo != NULL) {
SQueryStmtInfo* p = pQueryInfo->sibling;
size_t numOfUpstream = taosArrayGetSize(pQueryInfo->pUpstream);
for(int32_t i = 0; i < numOfUpstream; ++i) {
SQueryStmtInfo* pUpQueryInfo = taosArrayGetP(pQueryInfo->pUpstream, i);
freeQueryInfoImpl(pUpQueryInfo);
clearAllTableMetaInfo(pUpQueryInfo, removeCachedMeta, id);
tfree(pUpQueryInfo);
}
freeQueryInfoImpl(pQueryInfo);
clearAllTableMetaInfo(pQueryInfo, removeCachedMeta, id);
tfree(pQueryInfo);
pQueryInfo = p;
}
}
SArray* extractFunctionIdList(SArray* pExprInfoList) { SArray* extractFunctionIdList(SArray* pExprInfoList) {
assert(pExprInfoList != NULL); assert(pExprInfoList != NULL);
size_t len = taosArrayGetSize(pExprInfoList); size_t len = taosArrayGetSize(pExprInfoList);
SArray* p = taosArrayInit(len, sizeof(int16_t)); SArray* p = taosArrayInit(len, sizeof(int32_t));
for(int32_t i = 0; i < len; ++i) { for(int32_t i = 0; i < len; ++i) {
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i); SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
taosArrayPush(p, &pExprInfo->pExpr->_node.functionId); taosArrayPush(p, &pExprInfo->pExpr->_node.functionId);

View File

@ -5,14 +5,14 @@ MESSAGE(STATUS "build parser unit test")
SET(CMAKE_CXX_STANDARD 11) SET(CMAKE_CXX_STANDARD 11)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
ADD_EXECUTABLE(astTest ${SOURCE_LIST}) ADD_EXECUTABLE(parserTest ${SOURCE_LIST})
TARGET_LINK_LIBRARIES( TARGET_LINK_LIBRARIES(
astTest parserTest
PUBLIC os util common parser catalog transport gtest PUBLIC os util common parser catalog transport gtest function
) )
TARGET_INCLUDE_DIRECTORIES( TARGET_INCLUDE_DIRECTORIES(
astTest parserTest
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/parser/" PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/parser/"
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/inc" PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/inc"
) )

View File

@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <function.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <iostream> #include <iostream>
#pragma GCC diagnostic ignored "-Wwrite-strings" #pragma GCC diagnostic ignored "-Wwrite-strings"
@ -65,61 +66,64 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
} }
} }
//TEST(testCase, validateAST_test) { TEST(testCase, validateAST_test) {
// SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99"); SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
// ASSERT_EQ(info1.valid, true); ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0}; char msg[128] = {0};
// SMsgBuf buf; SMsgBuf buf;
// buf.len = 128; buf.len = 128;
// buf.buf = msg; buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0); ASSERT_EQ(code, 0);
//
// SMetaReq req = {0}; SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0); ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo); setTableMetaInfo(pQueryInfo, &req);
// setTableMetaInfo(pQueryInfo, &req);
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
// SArray* pExprList = pQueryInfo->exprList;
// SArray* pExprList = pQueryInfo->exprList; ASSERT_EQ(taosArrayGetSize(pExprList), 3);
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); ASSERT_EQ(p1->base.uid, 110);
// ASSERT_EQ(p1->base.uid, 110); ASSERT_EQ(p1->base.numOfParams, 0);
// ASSERT_EQ(p1->base.numOfParams, 0); ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT); ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111"); ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a"); ASSERT_EQ(p1->base.colInfo.colId, 1);
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ(p1->base.token, "a");
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
ASSERT_EQ(p2->base.uid, 0);
ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
// ASSERT_EQ(p1->base.colInfo.colId, 1); // ASSERT_EQ(p1->base.colInfo.colId, 1);
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); // ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "a"); ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
//
// ASSERT_EQ(taosArrayGetSize(pExprList), 3); ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
// SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
// ASSERT_EQ(p2->base.uid, 0); destroyQueryInfo(pQueryInfo);
// ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression. qParserClearupMetaRequestInfo(&req);
// ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); destroySqlInfo(&info1);
// ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22"); }
//
//// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
//// ASSERT_EQ(p1->base.colInfo.colId, 1);
//// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
//}
//
//TEST(testCase, function_Test) { //TEST(testCase, function_Test) {
// SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`"); // SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
// ASSERT_EQ(info1.valid, true); // ASSERT_EQ(info1.valid, true);
@ -138,8 +142,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
// //
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo);
// setTableMetaInfo(pQueryInfo, &req); // setTableMetaInfo(pQueryInfo, &req);
// //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@ -161,6 +164,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// //
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); // ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); // ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//} //}
// //
//TEST(testCase, function_Test2) { //TEST(testCase, function_Test2) {
@ -181,8 +188,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
// //
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo);
// setTableMetaInfo(pQueryInfo, &req); // setTableMetaInfo(pQueryInfo, &req);
// //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@ -204,6 +210,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// //
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2); // ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); // ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//} //}
// //
//TEST(testCase, function_Test3) { //TEST(testCase, function_Test3) {
@ -224,8 +234,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
// //
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo);
// setTableMetaInfo(pQueryInfo, &req); // setTableMetaInfo(pQueryInfo, &req);
// //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@ -246,6 +255,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(p1->base.interBytes, 24); // ASSERT_EQ(p1->base.interBytes, 24);
// //
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4); // ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//} //}
// //
//TEST(testCase, function_Test4) { //TEST(testCase, function_Test4) {
@ -266,8 +279,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
// //
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo);
// setTableMetaInfo(pQueryInfo, &req); // setTableMetaInfo(pQueryInfo, &req);
// //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@ -289,6 +301,10 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// //
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1); // ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); // ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//} //}
// //
//TEST(testCase, function_Test5) { //TEST(testCase, function_Test5) {
@ -309,8 +325,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
// //
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
// initQueryInfo(pQueryInfo);
// setTableMetaInfo(pQueryInfo, &req); // setTableMetaInfo(pQueryInfo, &req);
// //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
@ -333,46 +348,63 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
// //
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); // ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); // ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//} //}
//
TEST(testCase, function_Test6) { //TEST(testCase, function_Test6) {
SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc`"); // SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc` interval(10s, 1s)");
ASSERT_EQ(info1.valid, true); // ASSERT_EQ(info1.valid, true);
//
char msg[128] = {0}; // char msg[128] = {0};
SMsgBuf buf; // SMsgBuf buf;
buf.len = 128; // buf.len = 128;
buf.buf = msg; // buf.buf = msg;
//
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); // SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); // int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
ASSERT_EQ(code, 0); // ASSERT_EQ(code, 0);
//
SMetaReq req = {0}; // SMetaReq req = {0};
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); // int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
ASSERT_EQ(ret, 0); // ASSERT_EQ(ret, 0);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); // ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo)); // SQueryStmtInfo* pQueryInfo = createQueryInfo();
initQueryInfo(pQueryInfo); // setTableMetaInfo(pQueryInfo, &req);
setTableMetaInfo(pQueryInfo, &req); //
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0); // ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); // ASSERT_EQ(ret, 0);
ASSERT_EQ(ret, 0); //
// SArray* pExprList = pQueryInfo->exprList;
SArray* pExprList = pQueryInfo->exprList; // ASSERT_EQ(taosArrayGetSize(pExprList), 2);
ASSERT_EQ(taosArrayGetSize(pExprList), 2); //
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0); // ASSERT_EQ(p1->base.uid, 110);
ASSERT_EQ(p1->base.uid, 110); // ASSERT_EQ(p1->base.numOfParams, 0);
ASSERT_EQ(p1->base.numOfParams, 0); // ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); // ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); // ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); // ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)"); // ASSERT_EQ(p1->base.interBytes, 16);
ASSERT_EQ(p1->base.interBytes, 16); // ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
// ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_SUM);
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); // ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); //
} // tExprNode* pParam = p1->pExpr->_node.pLeft;
//
// ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
// ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD);
// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE);
// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE);
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}

View File

@ -667,51 +667,59 @@ TEST(testCase, isValidNumber_test) {
EXPECT_EQ(tGetNumericStringType(&t1), TK_FLOAT); EXPECT_EQ(tGetNumericStringType(&t1), TK_FLOAT);
} }
TEST(testCase, generateAST_test) { //TEST(testCase, generateAST_test) {
SSqlInfo info = doGenerateAST("select * from t1 where ts < now"); // SSqlInfo info = doGenerateAST("select * from t1 where ts < now");
ASSERT_EQ(info.valid, true); // ASSERT_EQ(info.valid, true);
//
SSqlInfo info1 = doGenerateAST("select * from `t.1abc` where ts<now+2h and col < 20+99"); // SSqlInfo info1 = doGenerateAST("select * from `t.1abc` where ts<now+2h and col < 20+99");
ASSERT_EQ(info1.valid, true); // ASSERT_EQ(info1.valid, true);
//
char msg[128] = {0}; // char msg[128] = {0};
//
SMsgBuf msgBuf = {0}; // SMsgBuf msgBuf = {0};
msgBuf.buf = msg; // msgBuf.buf = msg;
msgBuf.len = 128; // msgBuf.len = 128;
//
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); // SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf); // int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
ASSERT_EQ(code, 0); // ASSERT_EQ(code, 0);
//
SSqlInfo info2 = doGenerateAST("select * from abc where ts<now+2"); // SSqlInfo info2 = doGenerateAST("select * from abc where ts<now+2");
SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.list), 0); // SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.list), 0);
code = evaluateSqlNode(pNode2, TSDB_TIME_PRECISION_MILLI, &msgBuf); // code = evaluateSqlNode(pNode2, TSDB_TIME_PRECISION_MILLI, &msgBuf);
ASSERT_NE(code, 0); // ASSERT_NE(code, 0);
} //
// destroySqlInfo(&info);
TEST(testCase, evaluateAST_test) { // destroySqlInfo(&info1);
SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99"); // destroySqlInfo(&info2);
ASSERT_EQ(info1.valid, true); //}
//
char msg[128] = {0}; //TEST(testCase, evaluateAST_test) {
SMsgBuf msgBuf = {0}; // SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99");
msgBuf.buf = msg; // ASSERT_EQ(info1.valid, true);
msgBuf.len = 128; //
// char msg[128] = {0};
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0); // SMsgBuf msgBuf = {0};
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf); // msgBuf.buf = msg;
ASSERT_EQ(code, 0); // msgBuf.len = 128;
} //
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
TEST(testCase, extractMeta_test) { // int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99"); // ASSERT_EQ(code, 0);
ASSERT_EQ(info1.valid, true); // destroySqlInfo(&info1);
//}
char msg[128] = {0}; //
SMetaReq req = {0}; //TEST(testCase, extractMeta_test) {
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); // SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99");
ASSERT_EQ(ret, 0); // ASSERT_EQ(info1.valid, true);
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); //
} // char msg[128] = {0};
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}

View File

@ -15,5 +15,12 @@
#include "sync.h" #include "sync.h"
int32_t syncInit() {return 0;} int32_t syncInit() { return 0; }
void syncCleanUp() {}
void syncCleanUp() {}
SSyncNode* syncStart(const SSyncInfo* pInfo) { return NULL; }
void syncStop(const SSyncNode* pNode) {}
void syncReconfig(const SSyncNode* pNode, const SSyncCluster* pCfg) {}

View File

@ -15,5 +15,22 @@
#include "wal.h" #include "wal.h"
int32_t walInit() {return 0;} int32_t walInit() { return 0; }
void walCleanUp() {}
void walCleanUp() {}
SWal *walOpen(char *path, SWalCfg *pCfg) { return NULL; }
int32_t walAlter(SWal *pWal, SWalCfg *pCfg) { return 0; }
void walClose(SWal *pWal) {}
void walFsync(SWal *pWal, bool force) {}
int64_t walWrite(SWal *pWal, int64_t index, void *body, int32_t bodyLen) {}
int32_t walCommit(SWal *pWal, int64_t ver) { return 0; }
int32_t walRollback(SWal *pWal, int64_t ver) { return 0; }
int32_t walPrune(SWal *pWal, int64_t ver) { return 0; }

View File

@ -37,7 +37,7 @@ EDnStat dnodeGetRunStat() { return tsDnode.runStatus; }
void dnodeSetRunStat(EDnStat stat) { tsDnode.runStatus = stat; } void dnodeSetRunStat(EDnStat stat) { tsDnode.runStatus = stat; }
static void dnodeReportStartup(char *name, char *desc) { void dnodeReportStartup(char *name, char *desc) {
SStartupStep *startup = &tsDnode.startup; SStartupStep *startup = &tsDnode.startup;
tstrncpy(startup->name, name, strlen(startup->name)); tstrncpy(startup->name, name, strlen(startup->name));
tstrncpy(startup->desc, desc, strlen(startup->desc)); tstrncpy(startup->desc, desc, strlen(startup->desc));
@ -58,6 +58,7 @@ static int32_t dnodeInitVnode() {
para.fp.GetDnodeEp = dnodeGetEp; para.fp.GetDnodeEp = dnodeGetEp;
para.fp.SendMsgToDnode = dnodeSendMsgToDnode; para.fp.SendMsgToDnode = dnodeSendMsgToDnode;
para.fp.SendMsgToMnode = dnodeSendMsgToMnode; para.fp.SendMsgToMnode = dnodeSendMsgToMnode;
para.fp.ReportStartup = dnodeReportStartup;
return vnodeInit(para); return vnodeInit(para);
} }

View File

@ -24,7 +24,7 @@ extern "C" {
tmr_h mnodeGetTimer(); tmr_h mnodeGetTimer();
int32_t mnodeGetDnodeId(); int32_t mnodeGetDnodeId();
char *mnodeGetClusterId(); int64_t mnodeGetClusterId();
EMnStatus mnodeGetStatus(); EMnStatus mnodeGetStatus();
void mnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg); void mnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg);

View File

@ -202,12 +202,13 @@ static void mnodeSendTelemetryReport() {
return; return;
} }
char clusterId[TSDB_CLUSTER_ID_LEN] = {0}; int64_t clusterId = mnodeGetClusterId();
mnodeGetClusterId(clusterId); char clusterIdStr[20] = {0};
snprintf(clusterIdStr, sizeof(clusterIdStr), "%" PRId64, clusterId);
SBufferWriter bw = tbufInitWriter(NULL, false); SBufferWriter bw = tbufInitWriter(NULL, false);
mnodeBeginObject(&bw); mnodeBeginObject(&bw);
mnodeAddStringField(&bw, "instanceId", clusterId); mnodeAddStringField(&bw, "instanceId", clusterIdStr);
mnodeAddIntField(&bw, "reportVersion", 1); mnodeAddIntField(&bw, "reportVersion", 1);
mnodeAddOsInfo(&bw); mnodeAddOsInfo(&bw);
mnodeAddCpuInfo(&bw); mnodeAddCpuInfo(&bw);

View File

@ -39,7 +39,7 @@
static struct { static struct {
int32_t state; int32_t state;
int32_t dnodeId; int32_t dnodeId;
char clusterId[TSDB_CLUSTER_ID_LEN]; int64_t clusterId;
tmr_h timer; tmr_h timer;
SMnodeFp fp; SMnodeFp fp;
SSteps * steps1; SSteps * steps1;
@ -50,7 +50,7 @@ tmr_h mnodeGetTimer() { return tsMint.timer; }
int32_t mnodeGetDnodeId() { return tsMint.dnodeId; } int32_t mnodeGetDnodeId() { return tsMint.dnodeId; }
char *mnodeGetClusterId() { return tsMint.clusterId; } int64_t mnodeGetClusterId() { return tsMint.clusterId; }
EMnStatus mnodeGetStatus() { return tsMint.state; } EMnStatus mnodeGetStatus() { return tsMint.state; }
@ -71,12 +71,14 @@ int32_t mnodeGetStatistics(SMnodeStat *stat) { return 0; }
static int32_t mnodeSetPara(SMnodePara para) { static int32_t mnodeSetPara(SMnodePara para) {
tsMint.fp = para.fp; tsMint.fp = para.fp;
tsMint.dnodeId = para.dnodeId; tsMint.dnodeId = para.dnodeId;
strncpy(tsMint.clusterId, para.clusterId, TSDB_CLUSTER_ID_LEN); tsMint.clusterId = para.clusterId;
if (tsMint.fp.SendMsgToDnode == NULL) return -1; if (tsMint.fp.SendMsgToDnode == NULL) return -1;
if (tsMint.fp.SendMsgToMnode == NULL) return -1; if (tsMint.fp.SendMsgToMnode == NULL) return -1;
if (tsMint.fp.SendRedirectMsg == NULL) return -1; if (tsMint.fp.SendRedirectMsg == NULL) return -1;
if (tsMint.fp.GetDnodeEp == NULL) return -1;
if (tsMint.dnodeId < 0) return -1; if (tsMint.dnodeId < 0) return -1;
if (tsMint.clusterId < 0) return -1;
return 0; return 0;
} }
@ -141,7 +143,7 @@ static void mnodeCleanupStep2() { taosStepCleanup(tsMint.steps2); }
static bool mnodeNeedDeploy() { static bool mnodeNeedDeploy() {
if (tsMint.dnodeId > 0) return false; if (tsMint.dnodeId > 0) return false;
if (tsMint.clusterId[0] != 0) return false; if (tsMint.clusterId > 0) return false;
if (strcmp(tsFirst, tsLocalEp) != 0) return false; if (strcmp(tsFirst, tsLocalEp) != 0) return false;
return true; return true;
} }
@ -154,7 +156,7 @@ int32_t mnodeDeploy() {
tsMint.state = MN_STATUS_INIT; tsMint.state = MN_STATUS_INIT;
} }
if (tsMint.dnodeId <= 0 || tsMint.clusterId[0] == 0) { if (tsMint.dnodeId <= 0 || tsMint.clusterId <= 0) {
mError("failed to deploy mnode since cluster not ready"); mError("failed to deploy mnode since cluster not ready");
return TSDB_CODE_MND_NOT_READY; return TSDB_CODE_MND_NOT_READY;
} }

View File

@ -21,8 +21,10 @@ extern "C" {
#endif #endif
#include "vnodeInt.h" #include "vnodeInt.h"
int32_t vnodeReadCfg(SVnode *pVnode); int32_t vnodeReadCfg(int32_t vgId, SVnodeCfg *pCfg);
int32_t vnodeWriteCfg(SCreateVnodeMsg *pVnodeCfg); int32_t vnodeWriteCfg(int32_t vgId, SVnodeCfg *pCfg);
int32_t vnodeReadState(int32_t vgId, SSyncServerState *pState);
int32_t vnodeSaveState(int32_t vgid, SSyncServerState *pState);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -16,11 +16,12 @@
#ifndef _TD_VNODE_INT_H_ #ifndef _TD_VNODE_INT_H_
#define _TD_VNODE_INT_H_ #define _TD_VNODE_INT_H_
#include "os.h"
#include "amalloc.h" #include "amalloc.h"
#include "meta.h" #include "meta.h"
#include "os.h"
#include "sync.h" #include "sync.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tglobal.h"
#include "tlog.h" #include "tlog.h"
#include "tq.h" #include "tq.h"
#include "tqueue.h" #include "tqueue.h"
@ -43,57 +44,70 @@ extern int32_t vDebugFlag;
#define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }} #define vDebug(...) { if (vDebugFlag & DEBUG_DEBUG) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
#define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }} #define vTrace(...) { if (vDebugFlag & DEBUG_TRACE) { taosPrintLog("VND ", vDebugFlag, __VA_ARGS__); }}
typedef struct STsdbCfg {
int32_t cacheBlockSize; // MB
int32_t totalBlocks;
int32_t daysPerFile;
int32_t daysToKeep0;
int32_t daysToKeep1;
int32_t daysToKeep2;
int32_t minRowsPerFileBlock;
int32_t maxRowsPerFileBlock;
uint8_t precision; // time resolution
int8_t compression;
int8_t cacheLastRow;
int8_t update;
} STsdbCfg;
typedef struct SMetaCfg {
} SMetaCfg;
typedef struct SVnodeCfg {
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
int8_t dropped;
int8_t quorum;
SWalCfg wal;
STsdbCfg tsdb;
SMetaCfg meta;
SSyncCluster sync;
} SVnodeCfg;
typedef struct { typedef struct {
int32_t vgId; // global vnode group ID int32_t vgId; // global vnode group ID
int32_t refCount; // reference count int32_t refCount; // reference count
SMemAllocator *allocator; SMemAllocator *allocator;
SMeta *pMeta; SMeta *pMeta;
STsdb *pTsdb; STsdb *pTsdb;
STQ *pTQ; STQ *pTQ;
twalh pWal; SWal *pWal;
SyncNodeId syncNode; void *pQuery;
taos_queue pWriteQ; // write queue SSyncNode *pSync;
taos_queue pQueryQ; // read query queue taos_queue pWriteQ; // write queue
taos_queue pFetchQ; // read fetch/cancel queue taos_queue pQueryQ; // read query queue
SWalCfg walCfg; taos_queue pFetchQ; // read fetch/cancel queue
SSyncCluster syncCfg; SVnodeCfg cfg;
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; SSyncServerState term;
int64_t queuedWMsgSize; int64_t queuedWMsgSize;
int32_t queuedWMsg; int32_t queuedWMsg;
int32_t queuedRMsg; int32_t queuedRMsg;
int32_t numOfQHandle; // current initialized and existed query handle in current dnode int32_t numOfQHandle; // current initialized and existed query handle in current dnode
int8_t status; int8_t role;
int8_t role; int8_t accessState;
int8_t accessState; int8_t dropped;
int8_t dropped; int8_t status;
pthread_mutex_t statusMutex; pthread_mutex_t statusMutex;
} SVnode; } SVnode;
typedef struct { typedef struct {
int32_t len; int32_t len;
void * rsp; void *rsp;
void * qhandle; // used by query and retrieve msg void *qhandle; // used by query and retrieve msg
} SVnRsp; } SVnRsp;
void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg); void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg);
void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg); void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg);
void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port); void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
void vnodeReportStartup(char *name, char *desc);
int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeDrop(int32_t vgId);
int32_t vnodeOpen(int32_t vgId);
int32_t vnodeAlter(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeSync(int32_t vgId);
int32_t vnodeClose(int32_t vgId);
void vnodeCleanUp(SVnode *pVnode);
void vnodeDestroy(SVnode *pVnode);
int32_t vnodeCompact(int32_t vgId);
void vnodeBackup(int32_t vgId);
void vnodeGetStatus(struct SStatusMsg *status);
SVnode *vnodeAcquire(int32_t vgId);
SVnode *vnodeAcquireNotClose(int32_t vgId);
void vnodeRelease(SVnode *pVnode);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -13,23 +13,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _TD_VNODE_MGMT_MSG_H_ #ifndef _TD_VNODE_MAIN_H_
#define _TD_VNODE_MGMT_MSG_H_ #define _TD_VNODE_MAIN_H_
#include "vnodeInt.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "vnodeInt.h"
int32_t vnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg); int32_t vnodeInitMain();
int32_t vnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg); void vnodeCleanupMain();
int32_t vnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg);
int32_t vnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg); SVnode *vnodeAcquireInAllState(int32_t vgId);
int32_t vnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg); SVnode *vnodeAcquire(int32_t vgId);
int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg); void vnodeRelease(SVnode *pVnode);
int32_t vnodeCreateVnode(int32_t vgId, SVnodeCfg *pCfg);
int32_t vnodeAlterVnode(SVnode *pVnode, SVnodeCfg *pCfg);
int32_t vnodeDropVnode(SVnode *pVnode);
int32_t vnodeSyncVnode(SVnode *pVnode);
int32_t vnodeCompactVnode(SVnode *pVnode);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /*_TD_VNODE_MGMT_H_*/ #endif /*_TD_VNODE_MAIN_H_*/

View File

@ -21,6 +21,14 @@ extern "C" {
#endif #endif
#include "vnodeInt.h" #include "vnodeInt.h"
typedef struct {
SVnode *pVnode;
SRpcMsg rpcMsg;
char pCont[];
} SVnMgmtMsg;
int32_t vnodeInitMgmt(); int32_t vnodeInitMgmt();
void vnodeCleanupMgmt(); void vnodeCleanupMgmt();
void vnodeProcessMgmtMsg(SRpcMsg *pMsg); void vnodeProcessMgmtMsg(SRpcMsg *pMsg);

View File

@ -1,47 +0,0 @@
/*
* 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 _TD_VNODE_STATUS_H_
#define _TD_VNODE_STATUS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "vnodeInt.h"
typedef enum _VN_STATUS {
TAOS_VN_STATUS_INIT = 0,
TAOS_VN_STATUS_READY = 1,
TAOS_VN_STATUS_CLOSING = 2,
TAOS_VN_STATUS_UPDATING = 3
} EVnodeStatus;
// vnodeStatus
extern char* vnodeStatus[];
bool vnodeSetInitStatus(SVnode* pVnode);
bool vnodeSetReadyStatus(SVnode* pVnode);
bool vnodeSetClosingStatus(SVnode* pVnode);
bool vnodeSetUpdatingStatus(SVnode* pVnode);
bool vnodeInInitStatus(SVnode* pVnode);
bool vnodeInReadyStatus(SVnode* pVnode);
bool vnodeInClosingStatus(SVnode* pVnode);
#ifdef __cplusplus
}
#endif
#endif /*_TD_VNODE_STATUS_H_*/

View File

@ -1,31 +0,0 @@
/*
* 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 _TD_VNODE_VERSION_H_
#define _TD_VNODE_VERSION_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "vnodeInt.h"
int32_t vnodeReadVersion(SVnode *pVnode);
int32_t vnodeSaveVersion(SVnode *pVnode);
#ifdef __cplusplus
}
#endif
#endif /*_TD_VNODE_VERSION_H_*/

View File

@ -1,34 +0,0 @@
/*
* 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 _TD_VNODE_WORKER_H_
#define _TD_VNODE_WORKER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "vnodeInt.h"
int32_t vnodeInitWorker();
void vnodeCleanupWorker();
void vnodeProcessCleanupTask(SVnode *pVnode);
void vnodeProcessDestroyTask(SVnode *pVnode);
void vnodeProcessBackupTask(SVnode *pVnode);
#ifdef __cplusplus
}
#endif
#endif /*_TD_VNODE_WORKER_H_*/

View File

@ -1,381 +0,0 @@
/*
* 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 "cJSON.h"
#include "tglobal.h"
#include "vnodeCfg.h"
static void vnodeLoadCfg(SVnode *pVnode, SCreateVnodeMsg *vnodeMsg) {
#if 0
tstrncpy(pVnode->db, vnodeMsg->db, sizeof(pVnode->db));
pVnode->dbCfgVersion = vnodeMsg->cfg.dbCfgVersion;
pVnode->vgCfgVersion = vnodeMsg->cfg.vgCfgVersion;
pVnode->tsdbCfg.cacheBlockSize = vnodeMsg->cfg.cacheBlockSize;
pVnode->tsdbCfg.totalBlocks = vnodeMsg->cfg.totalBlocks;
pVnode->tsdbCfg.daysPerFile = vnodeMsg->cfg.daysPerFile;
pVnode->tsdbCfg.keep = vnodeMsg->cfg.daysToKeep;
pVnode->tsdbCfg.keep1 = vnodeMsg->cfg.daysToKeep1;
pVnode->tsdbCfg.keep2 = vnodeMsg->cfg.daysToKeep2;
pVnode->tsdbCfg.minRowsPerFileBlock = vnodeMsg->cfg.minRowsPerFileBlock;
pVnode->tsdbCfg.maxRowsPerFileBlock = vnodeMsg->cfg.maxRowsPerFileBlock;
pVnode->tsdbCfg.precision = vnodeMsg->cfg.precision;
pVnode->tsdbCfg.compression = vnodeMsg->cfg.compression;
pVnode->tsdbCfg.update = vnodeMsg->cfg.update;
pVnode->tsdbCfg.cacheLastRow = vnodeMsg->cfg.cacheLastRow;
pVnode->walCfg.walLevel = vnodeMsg->cfg.walLevel;
pVnode->walCfg.fsyncPeriod = vnodeMsg->cfg.fsyncPeriod;
pVnode->walCfg.keep = TAOS_WAL_NOT_KEEP;
pVnode->syncCfg.replica = vnodeMsg->cfg.vgReplica;
pVnode->syncCfg.quorum = vnodeMsg->cfg.quorum;
pVnode->dbReplica = vnodeMsg->cfg.dbReplica;
pVnode->dbType = vnodeMsg->cfg.dbType;
for (int i = 0; i < pVnode->syncCfg.replica; ++i) {
SVnodeDesc *node = &vnodeMsg->nodes[i];
pVnode->syncCfg.nodeInfo[i].nodeId = node->nodeId;
taosGetFqdnPortFromEp(node->nodeEp, pVnode->syncCfg.nodeInfo[i].nodeFqdn, &pVnode->syncCfg.nodeInfo[i].nodePort);
pVnode->syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
}
vInfo("vgId:%d, load vnode cfg successfully, replcia:%d", pVnode->vgId, pVnode->syncCfg.replica);
for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
SNodeInfo *node = &pVnode->syncCfg.nodeInfo[i];
vInfo("vgId:%d, dnode:%d, %s:%u", pVnode->vgId, node->nodeId, node->nodeFqdn, node->nodePort);
}
#endif
}
int32_t vnodeReadCfg(SVnode *pVnode) {
#if 0
int32_t ret = TSDB_CODE_VND_APP_ERROR;
int32_t len = 0;
int maxLen = 1000;
char * content = calloc(1, maxLen + 1);
cJSON * root = NULL;
FILE * fp = NULL;
bool nodeChanged = false;
SCreateVnodeMsg vnodeMsg;
char file[TSDB_FILENAME_LEN + 30] = {0};
sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pVnode->vgId);
vnodeMsg.cfg.vgId = pVnode->vgId;
fp = fopen(file, "r");
if (!fp) {
vError("vgId:%d, failed to open vnode cfg file:%s to read, error:%s", pVnode->vgId, file, strerror(errno));
ret = TAOS_SYSTEM_ERROR(errno);
goto PARSE_VCFG_ERROR;
}
len = (int32_t)fread(content, 1, maxLen, fp);
if (len <= 0) {
vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
content[len] = 0;
root = cJSON_Parse(content);
if (root == NULL) {
vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
cJSON *db = cJSON_GetObjectItem(root, "db");
if (!db || db->type != cJSON_String || db->valuestring == NULL) {
vError("vgId:%d, failed to read %s, db not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
tstrncpy(vnodeMsg.db, db->valuestring, sizeof(vnodeMsg.db));
cJSON *dbCfgVersion = cJSON_GetObjectItem(root, "cfgVersion");
if (!dbCfgVersion || dbCfgVersion->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, cfgVersion not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.dbCfgVersion = (int32_t)dbCfgVersion->valueint;
cJSON *vgCfgVersion = cJSON_GetObjectItem(root, "vgCfgVersion");
if (!vgCfgVersion || vgCfgVersion->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, vgCfgVersion not found", pVnode->vgId, file);
vnodeMsg.cfg.vgCfgVersion = 0;
} else {
vnodeMsg.cfg.vgCfgVersion = (int32_t)vgCfgVersion->valueint;
}
cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, cacheBlockSize not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.cacheBlockSize = (int32_t)cacheBlockSize->valueint;
cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
if (!totalBlocks || totalBlocks->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, totalBlocks not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.totalBlocks = (int32_t)totalBlocks->valueint;
cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
if (!daysPerFile || daysPerFile->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, daysPerFile not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.daysPerFile = (int32_t)daysPerFile->valueint;
cJSON *daysToKeep = cJSON_GetObjectItem(root, "daysToKeep");
if (!daysToKeep || daysToKeep->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, daysToKeep not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.daysToKeep = (int32_t)daysToKeep->valueint;
cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, daysToKeep1 not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.daysToKeep1 = (int32_t)daysToKeep1->valueint;
cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, daysToKeep2 not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.daysToKeep2 = (int32_t)daysToKeep2->valueint;
cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, minRowsPerFileBlock not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.minRowsPerFileBlock = (int32_t)minRowsPerFileBlock->valueint;
cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, maxRowsPerFileBlock not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.maxRowsPerFileBlock = (int32_t)maxRowsPerFileBlock->valueint;
cJSON *precision = cJSON_GetObjectItem(root, "precision");
if (!precision || precision->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, precision not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.precision = (int8_t)precision->valueint;
cJSON *compression = cJSON_GetObjectItem(root, "compression");
if (!compression || compression->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, compression not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.compression = (int8_t)compression->valueint;
cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
if (!walLevel || walLevel->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, walLevel not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.walLevel = (int8_t)walLevel->valueint;
cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsync");
if (!walLevel || walLevel->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, fsyncPeriod not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.fsyncPeriod = (int32_t)fsyncPeriod->valueint;
cJSON *wals = cJSON_GetObjectItem(root, "wals");
if (!wals || wals->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, wals not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.wals = (int8_t)wals->valueint;
cJSON *vgReplica = cJSON_GetObjectItem(root, "replica");
if (!vgReplica || vgReplica->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, replica not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.vgReplica = (int8_t)vgReplica->valueint;
cJSON *dbReplica = cJSON_GetObjectItem(root, "dbReplica");
if (!dbReplica || dbReplica->type != cJSON_Number) {
vWarn("vgId:%d, failed to read %s, dbReplica not found", pVnode->vgId, file);
vnodeMsg.cfg.dbReplica = vnodeMsg.cfg.vgReplica;
vnodeMsg.cfg.vgCfgVersion = 0;
} else {
vnodeMsg.cfg.dbReplica = (int8_t)dbReplica->valueint;
}
cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
if (!quorum || quorum->type != cJSON_Number) {
vError("vgId: %d, failed to read %s, quorum not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
vnodeMsg.cfg.quorum = (int8_t)quorum->valueint;
cJSON *update = cJSON_GetObjectItem(root, "update");
if (!update || update->type != cJSON_Number) {
vWarn("vgId: %d, failed to read %s, update not found", pVnode->vgId, file);
vnodeMsg.cfg.update = 0;
vnodeMsg.cfg.vgCfgVersion = 0;
} else {
vnodeMsg.cfg.update = (int8_t)update->valueint;
}
cJSON *cacheLastRow = cJSON_GetObjectItem(root, "cacheLastRow");
if (!cacheLastRow || cacheLastRow->type != cJSON_Number) {
vWarn("vgId: %d, failed to read %s, cacheLastRow not found", pVnode->vgId, file);
vnodeMsg.cfg.cacheLastRow = 0;
vnodeMsg.cfg.vgCfgVersion = 0;
} else {
vnodeMsg.cfg.cacheLastRow = (int8_t)cacheLastRow->valueint;
}
cJSON *dbType = cJSON_GetObjectItem(root, "dbType");
if (!dbType || dbType->type != cJSON_Number) {
vWarn("vgId: %d, failed to read %s, dbType not found", pVnode->vgId, file);
vnodeMsg.cfg.dbType = 0;
} else {
vnodeMsg.cfg.dbType = (int8_t)dbType->valueint;
}
cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
if (!nodeInfos || nodeInfos->type != cJSON_Array) {
vError("vgId:%d, failed to read %s, nodeInfos not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
int size = cJSON_GetArraySize(nodeInfos);
if (size != vnodeMsg.cfg.vgReplica) {
vError("vgId:%d, failed to read %s, nodeInfos size not matched", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
for (int i = 0; i < size; ++i) {
cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
if (nodeInfo == NULL) continue;
SVnodeDesc *node = &vnodeMsg.nodes[i];
cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
if (!nodeId || nodeId->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, nodeId not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
node->nodeId = (int32_t)nodeId->valueint;
cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
vError("vgId:%d, failed to read %s, nodeFqdn not found", pVnode->vgId, file);
goto PARSE_VCFG_ERROR;
}
tstrncpy(node->nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
char nodeEpStr[TSDB_EP_LEN];
vnodeGetDnodeEp(node->nodeId, nodeEpStr, NULL, NULL);
bool changed = (strcmp(node->nodeEp, nodeEpStr) != 0);
if (changed) {
tstrncpy(node->nodeEp, nodeEpStr, TSDB_EP_LEN);
nodeChanged = changed;
}
}
ret = TSDB_CODE_SUCCESS;
PARSE_VCFG_ERROR:
if (content != NULL) free(content);
if (root != NULL) cJSON_Delete(root);
if (fp != NULL) fclose(fp);
if (nodeChanged) {
vnodeWriteCfg(&vnodeMsg);
}
if (ret == TSDB_CODE_SUCCESS) {
vnodeLoadCfg(pVnode, &vnodeMsg);
}
terrno = 0;
return ret;
}
int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) {
char file[TSDB_FILENAME_LEN + 30] = {0};
sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pMsg->cfg.vgId);
FILE *fp = fopen(file, "w");
if (!fp) {
vError("vgId:%d, failed to write %s error:%s", pMsg->cfg.vgId, file, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return terrno;
}
int32_t len = 0;
int32_t maxLen = 1000;
char * content = calloc(1, maxLen + 1);
len += snprintf(content + len, maxLen - len, "{\n");
len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pMsg->db);
len += snprintf(content + len, maxLen - len, " \"cfgVersion\": %d,\n", pMsg->cfg.dbCfgVersion);
len += snprintf(content + len, maxLen - len, " \"vgCfgVersion\": %d,\n", pMsg->cfg.vgCfgVersion);
len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pMsg->cfg.cacheBlockSize);
len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pMsg->cfg.totalBlocks);
len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pMsg->cfg.daysPerFile);
len += snprintf(content + len, maxLen - len, " \"daysToKeep\": %d,\n", pMsg->cfg.daysToKeep);
len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pMsg->cfg.daysToKeep1);
len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pMsg->cfg.daysToKeep2);
len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pMsg->cfg.minRowsPerFileBlock);
len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pMsg->cfg.maxRowsPerFileBlock);
len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pMsg->cfg.precision);
len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pMsg->cfg.compression);
len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pMsg->cfg.walLevel);
len += snprintf(content + len, maxLen - len, " \"fsync\": %d,\n", pMsg->cfg.fsyncPeriod);
len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pMsg->cfg.vgReplica);
len += snprintf(content + len, maxLen - len, " \"dbReplica\": %d,\n", pMsg->cfg.dbReplica);
len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pMsg->cfg.wals);
len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pMsg->cfg.quorum);
len += snprintf(content + len, maxLen - len, " \"update\": %d,\n", pMsg->cfg.update);
len += snprintf(content + len, maxLen - len, " \"cacheLastRow\": %d,\n", pMsg->cfg.cacheLastRow);
len += snprintf(content + len, maxLen - len, " \"dbType\": %d,\n", pMsg->cfg.dbType);
len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
for (int32_t i = 0; i < pMsg->cfg.vgReplica; i++) {
SVnodeDesc *node = &pMsg->nodes[i];
vnodeGetDnodeEp(node->nodeId, node->nodeEp, NULL, NULL);
len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", node->nodeId);
len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", node->nodeEp);
if (i < pMsg->cfg.vgReplica - 1) {
len += snprintf(content + len, maxLen - len, " },{\n");
} else {
len += snprintf(content + len, maxLen - len, " }]\n");
}
}
len += snprintf(content + len, maxLen - len, "}\n");
fwrite(content, 1, len, fp);
taosFsync(fileno(fp));
fclose(fp);
free(content);
terrno = 0;
vInfo("vgId:%d, successed to write %s", pMsg->cfg.vgId, file);
#endif
return TSDB_CODE_SUCCESS;
}

View File

@ -0,0 +1,372 @@
/*
* 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 "cJSON.h"
#include "vnodeFile.h"
int32_t vnodeReadCfg(int32_t vgId, SVnodeCfg *pCfg) {
int32_t ret = TSDB_CODE_VND_APP_ERROR;
int32_t len = 0;
int maxLen = 1000;
char *content = calloc(1, maxLen + 1);
cJSON *root = NULL;
FILE *fp = NULL;
char file[PATH_MAX + 30] = {0};
sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, vgId);
fp = fopen(file, "r");
if (!fp) {
vError("vgId:%d, failed to open vnode cfg file:%s to read since %s", vgId, file, strerror(errno));
ret = TAOS_SYSTEM_ERROR(errno);
goto PARSE_VCFG_ERROR;
}
len = (int32_t)fread(content, 1, maxLen, fp);
if (len <= 0) {
vError("vgId:%d, failed to read %s since content is null", vgId, file);
goto PARSE_VCFG_ERROR;
}
content[len] = 0;
root = cJSON_Parse(content);
if (root == NULL) {
vError("vgId:%d, failed to read %s since invalid json format", vgId, file);
goto PARSE_VCFG_ERROR;
}
cJSON *db = cJSON_GetObjectItem(root, "db");
if (!db || db->type != cJSON_String || db->valuestring == NULL) {
vError("vgId:%d, failed to read %s since db not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
tstrncpy(pCfg->db, db->valuestring, sizeof(pCfg->db));
cJSON *dropped = cJSON_GetObjectItem(root, "dropped");
if (!dropped || dropped->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since dropped not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->dropped = (int32_t)dropped->valueint;
cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
if (!quorum || quorum->type != cJSON_Number) {
vError("vgId: %d, failed to read %s, quorum not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->quorum = (int8_t)quorum->valueint;
cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since cacheBlockSize not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.cacheBlockSize = (int32_t)cacheBlockSize->valueint;
cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
if (!totalBlocks || totalBlocks->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since totalBlocks not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.totalBlocks = (int32_t)totalBlocks->valueint;
cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
if (!daysPerFile || daysPerFile->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since daysPerFile not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.daysPerFile = (int32_t)daysPerFile->valueint;
cJSON *daysToKeep0 = cJSON_GetObjectItem(root, "daysToKeep0");
if (!daysToKeep0 || daysToKeep0->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since daysToKeep0 not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.daysToKeep0 = (int32_t)daysToKeep0->valueint;
cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since daysToKeep1 not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.daysToKeep1 = (int32_t)daysToKeep1->valueint;
cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since daysToKeep2 not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.daysToKeep2 = (int32_t)daysToKeep2->valueint;
cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since minRowsPerFileBlock not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.minRowsPerFileBlock = (int32_t)minRowsPerFileBlock->valueint;
cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since maxRowsPerFileBlock not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.maxRowsPerFileBlock = (int32_t)maxRowsPerFileBlock->valueint;
cJSON *precision = cJSON_GetObjectItem(root, "precision");
if (!precision || precision->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since precision not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.precision = (int8_t)precision->valueint;
cJSON *compression = cJSON_GetObjectItem(root, "compression");
if (!compression || compression->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since compression not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.compression = (int8_t)compression->valueint;
cJSON *update = cJSON_GetObjectItem(root, "update");
if (!update || update->type != cJSON_Number) {
vError("vgId: %d, failed to read %s since update not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.update = (int8_t)update->valueint;
cJSON *cacheLastRow = cJSON_GetObjectItem(root, "cacheLastRow");
if (!cacheLastRow || cacheLastRow->type != cJSON_Number) {
vError("vgId: %d, failed to read %s since cacheLastRow not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->tsdb.cacheLastRow = (int8_t)cacheLastRow->valueint;
cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
if (!walLevel || walLevel->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since walLevel not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->wal.walLevel = (int8_t)walLevel->valueint;
cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsyncPeriod");
if (!walLevel || walLevel->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since fsyncPeriod not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->wal.fsyncPeriod = (int32_t)fsyncPeriod->valueint;
cJSON *selfIndex = cJSON_GetObjectItem(root, "selfIndex");
if (!selfIndex || selfIndex->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since selfIndex not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->sync.selfIndex = selfIndex->valueint;
cJSON *replica = cJSON_GetObjectItem(root, "replica");
if (!replica || replica->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since replica not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
pCfg->sync.replica = replica->valueint;
cJSON *nodes = cJSON_GetObjectItem(root, "nodes");
if (!nodes || nodes->type != cJSON_Array) {
vError("vgId:%d, failed to read %s, nodes not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
int size = cJSON_GetArraySize(nodes);
if (size != pCfg->sync.replica) {
vError("vgId:%d, failed to read %s since nodes size not matched", vgId, file);
goto PARSE_VCFG_ERROR;
}
for (int i = 0; i < size; ++i) {
cJSON *nodeInfo = cJSON_GetArrayItem(nodes, i);
if (nodeInfo == NULL) continue;
SNodeInfo *node = &pCfg->sync.nodeInfo[i];
cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "id");
if (!nodeId || nodeId->type != cJSON_Number) {
vError("vgId:%d, failed to read %s since nodeId not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
node->nodeId = nodeId->valueint;
cJSON *nodePort = cJSON_GetObjectItem(nodeInfo, "port");
if (!nodePort || nodePort->type != cJSON_Number) {
vError("vgId:%d, failed to read %s sincenodePort not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
node->nodePort = (uint16_t)nodePort->valueint;
cJSON *nodeFqdn = cJSON_GetObjectItem(nodeInfo, "fqdn");
if (!nodeFqdn || nodeFqdn->type != cJSON_String || nodeFqdn->valuestring == NULL) {
vError("vgId:%d, failed to read %s since nodeFqdn not found", vgId, file);
goto PARSE_VCFG_ERROR;
}
tstrncpy(node->nodeFqdn, nodeFqdn->valuestring, TSDB_FQDN_LEN);
}
ret = TSDB_CODE_SUCCESS;
PARSE_VCFG_ERROR:
if (content != NULL) free(content);
if (root != NULL) cJSON_Delete(root);
if (fp != NULL) fclose(fp);
terrno = 0;
return ret;
}
int32_t vnodeWriteCfg(int32_t vgId, SVnodeCfg *pCfg) {
int32_t code = 0;
char file[PATH_MAX + 30] = {0};
sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, vgId);
FILE *fp = fopen(file, "w");
if (!fp) {
vError("vgId:%d, failed to write %s error:%s", vgId, file, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return terrno;
}
int32_t len = 0;
int32_t maxLen = 1000;
char *content = calloc(1, maxLen + 1);
len += snprintf(content + len, maxLen - len, "{\n");
// vnode
len += snprintf(content + len, maxLen - len, " \"vgId\": %d,\n", vgId);
len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pCfg->db);
len += snprintf(content + len, maxLen - len, " \"dropped\": %d,\n", pCfg->dropped);
len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pCfg->quorum);
// tsdb
len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pCfg->tsdb.cacheBlockSize);
len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pCfg->tsdb.totalBlocks);
len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pCfg->tsdb.daysPerFile);
len += snprintf(content + len, maxLen - len, " \"daysToKeep0\": %d,\n", pCfg->tsdb.daysToKeep0);
len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pCfg->tsdb.daysToKeep1);
len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pCfg->tsdb.daysToKeep2);
len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pCfg->tsdb.minRowsPerFileBlock);
len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pCfg->tsdb.maxRowsPerFileBlock);
len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pCfg->tsdb.precision);
len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pCfg->tsdb.compression);
len += snprintf(content + len, maxLen - len, " \"cacheLastRow\": %d,\n", pCfg->tsdb.cacheLastRow);
len += snprintf(content + len, maxLen - len, " \"update\": %d,\n", pCfg->tsdb.update);
// wal
len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pCfg->wal.walLevel);
len += snprintf(content + len, maxLen - len, " \"fsyncPeriod\": %d,\n", pCfg->wal.fsyncPeriod);
// sync
len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pCfg->sync.replica);
len += snprintf(content + len, maxLen - len, " \"selfIndex\": %d,\n", pCfg->sync.selfIndex);
len += snprintf(content + len, maxLen - len, " \"nodes\": [{\n");
for (int32_t i = 0; i < pCfg->sync.replica; i++) {
SNodeInfo *node = &pCfg->sync.nodeInfo[i];
len += snprintf(content + len, maxLen - len, " \"id\": %d,\n", node->nodeId);
len += snprintf(content + len, maxLen - len, " \"port\": %u,\n", node->nodePort);
len += snprintf(content + len, maxLen - len, " \"fqdn\": \"%s\"\n", node->nodeFqdn);
if (i < pCfg->sync.replica - 1) {
len += snprintf(content + len, maxLen - len, " },{\n");
} else {
len += snprintf(content + len, maxLen - len, " }]\n");
}
}
len += snprintf(content + len, maxLen - len, "}\n");
fwrite(content, 1, len, fp);
taosFsyncFile(fileno(fp));
fclose(fp);
free(content);
terrno = 0;
vInfo("vgId:%d, successed to write %s", vgId, file);
return TSDB_CODE_SUCCESS;
}
int32_t vnodeReadState(int32_t vgId, SSyncServerState *pState) {
int32_t ret = TSDB_CODE_VND_APP_ERROR;
int32_t len = 0;
int32_t maxLen = 100;
char *content = calloc(1, maxLen + 1);
cJSON *root = NULL;
FILE *fp = NULL;
char file[PATH_MAX + 30] = {0};
sprintf(file, "%s/vnode%d/state.json", tsVnodeDir, vgId);
len = (int32_t)fread(content, 1, maxLen, fp);
if (len <= 0) {
vError("vgId:%d, failed to read %s since content is null", vgId, file);
goto PARSE_TERM_ERROR;
}
root = cJSON_Parse(content);
if (root == NULL) {
vError("vgId:%d, failed to read %s since invalid json format", vgId, file);
goto PARSE_TERM_ERROR;
}
cJSON *term = cJSON_GetObjectItem(root, "term");
if (!term || term->type != cJSON_String) {
vError("vgId:%d, failed to read %s since term not found", vgId, file);
goto PARSE_TERM_ERROR;
}
pState->term = atoll(term->valuestring);
cJSON *voteFor = cJSON_GetObjectItem(root, "voteFor");
if (!voteFor || voteFor->type != cJSON_String) {
vError("vgId:%d, failed to read %s since voteFor not found", vgId, file);
goto PARSE_TERM_ERROR;
}
pState->voteFor = atoi(voteFor->valuestring);
vInfo("vgId:%d, read %s success, voteFor:%d, term:%" PRIu64, vgId, file, pState->voteFor, pState->term);
PARSE_TERM_ERROR:
if (content != NULL) free(content);
if (root != NULL) cJSON_Delete(root);
if (fp != NULL) fclose(fp);
return ret;
}
int32_t vnodeSaveState(int32_t vgId, SSyncServerState *pState) {
char file[PATH_MAX + 30] = {0};
sprintf(file, "%s/vnode%d/state.json", tsVnodeDir, vgId);
FILE *fp = fopen(file, "w");
if (!fp) {
vError("vgId:%d, failed to write %s since %s", vgId, file, strerror(errno));
return -1;
}
int32_t len = 0;
int32_t maxLen = 100;
char *content = calloc(1, maxLen + 1);
len += snprintf(content + len, maxLen - len, "{\n");
len += snprintf(content + len, maxLen - len, " \"term\": \"%" PRIu64 "\",\n", pState->term);
len += snprintf(content + len, maxLen - len, " \"voteFor\": \"%d\"\n", pState->voteFor);
len += snprintf(content + len, maxLen - len, "}\n");
fwrite(content, 1, len, fp);
taosFsyncFile(fileno(fp));
fclose(fp);
free(content);
vInfo("vgId:%d, write %s success, voteFor:%d, term:%" PRIu64, vgId, file, pState->voteFor, pState->term);
return TSDB_CODE_SUCCESS;
}

View File

@ -14,935 +14,78 @@
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "tglobal.h" #include "os.h"
#include "ttimer.h"
#include "thash.h"
// #include "query.h"
#include "vnodeCfg.h"
#include "vnodeMgmt.h"
#include "vnodeRead.h"
#include "vnodeStatus.h"
#include "vnodeVersion.h"
#include "vnodeWorker.h"
#include "vnodeWrite.h"
#include "tstep.h" #include "tstep.h"
#include "vnodeMain.h"
#include "vnodeMgmt.h" #include "vnodeMgmt.h"
#include "vnodeRead.h" #include "vnodeRead.h"
#include "vnodeWorker.h"
#include "vnodeWrite.h" #include "vnodeWrite.h"
typedef struct {
pthread_t thread;
int32_t threadIndex;
int32_t failed;
int32_t opened;
int32_t vnodeNum;
int32_t * vnodeList;
} SOpenVnodeThread;
static struct { static struct {
SSteps *steps; SSteps *steps;
SVnodeFp fp; SVnodeFp fp;
void * timer;
SHashObj *hash;
int32_t openVnodes;
int32_t totalVnodes;
void (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *); void (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
} tsVnode; } tsVint;
void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port) { void vnodeGetDnodeEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port) {
return (*tsVnode.fp.GetDnodeEp)(dnodeId, ep, fqdn, port); return (*tsVint.fp.GetDnodeEp)(dnodeId, ep, fqdn, port);
} }
void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg) { void vnodeSendMsgToDnode(struct SRpcEpSet *epSet, struct SRpcMsg *rpcMsg) {
(*tsVnode.fp.SendMsgToDnode)(epSet, rpcMsg); (*tsVint.fp.SendMsgToDnode)(epSet, rpcMsg);
} }
void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg) { return (*tsVnode.fp.SendMsgToMnode)(rpcMsg); } void vnodeSendMsgToMnode(struct SRpcMsg *rpcMsg) { return (*tsVint.fp.SendMsgToMnode)(rpcMsg); }
static void vnodeIncRef(void *ptNode) { void vnodeReportStartup(char *name, char *desc) { (*tsVint.fp.ReportStartup)(name, desc); }
assert(ptNode != NULL);
SVnode **ppVnode = (SVnode **)ptNode;
assert(ppVnode);
assert(*ppVnode);
SVnode *pVnode = *ppVnode;
atomic_add_fetch_32(&pVnode->refCount, 1);
vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
}
SVnode *vnodeAcquire(int32_t vgId) {
SVnode *pVnode = NULL;
// taosHashGetClone(tsVnode.hash, &vgId, sizeof(int32_t), vnodeIncRef, (void*)&pVnode);
if (pVnode == NULL) {
terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
vDebug("vgId:%d, not exist", vgId);
return NULL;
}
return pVnode;
}
SVnode *vnodeAcquireNotClose(int32_t vgId) {
// SVnode *pVnode = vnodeAcquire(vgId);
// if (pVnode != NULL && pVnode->preClose == 1) {
// vnodeRelease(pVnode);
// terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
// vDebug("vgId:%d, not exist, pre closing", vgId);
// return NULL;
// }
// return pVnode;
return NULL;
}
void vnodeRelease(SVnode *pVnode) {
if (pVnode == NULL) return;
int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
int32_t vgId = pVnode->vgId;
vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", vgId, refCount, pVnode);
assert(refCount >= 0);
if (refCount <= 0) {
vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", vgId, refCount, pVnode);
vnodeProcessDestroyTask(pVnode);
int32_t count = taosHashGetSize(tsVnode.hash);
vDebug("vgId:%d, vnode is destroyed, vnodes:%d", vgId, count);
}
}
static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno);
int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
int32_t code;
SVnode *pVnode = vnodeAcquire(pVnodeCfg->cfg.vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, vnode already exist, refCount:%d pVnode:%p", pVnodeCfg->cfg.vgId, pVnode->refCount, pVnode);
vnodeRelease(pVnode);
return TSDB_CODE_SUCCESS;
}
#if 0
if (tfsMkdir("vnode") < 0) {
vError("vgId:%d, failed to create vnode dir, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
return terrno;
}
char vnodeDir[TSDB_FILENAME_LEN] = "\0";
snprintf(vnodeDir, TSDB_FILENAME_LEN, "/vnode/vnode%d", pVnodeCfg->cfg.vgId);
if (tfsMkdir(vnodeDir) < 0) {
vError("vgId:%d, failed to create vnode dir %s, reason:%s", pVnodeCfg->cfg.vgId, vnodeDir, strerror(errno));
return terrno;
}
code = vnodeWriteCfg(pVnodeCfg);
if (code != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to save vnode cfg, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(code));
return code;
}
if (tsdbCreateRepo(pVnodeCfg->cfg.vgId) < 0) {
vError("vgId:%d, failed to create tsdb in vnode, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
return TSDB_CODE_VND_INIT_FAILED;
}
#endif
vInfo("vgId:%d, vnode dir is created, walLevel:%d fsyncPeriod:%d", pVnodeCfg->cfg.vgId, pVnodeCfg->cfg.walLevel,
pVnodeCfg->cfg.fsyncPeriod);
code = vnodeOpen(pVnodeCfg->cfg.vgId);
return code;
}
int32_t vnodeSync(int32_t vgId) {
#if 0
SVnode *pVnode = vnodeAcquireNotClose(vgId);
if (pVnode == NULL) {
vDebug("vgId:%d, failed to sync, vnode not find", vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
if (pVnode->role == TAOS_SYNC_ROLE_SLAVE) {
vInfo("vgId:%d, vnode will sync, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
pVnode->version = 0;
pVnode->fversion = 0;
walResetVersion(pVnode->wal, pVnode->fversion);
syncRecover(pVnode->sync);
}
vnodeRelease(pVnode);
#endif
return TSDB_CODE_SUCCESS;
}
int32_t vnodeDrop(int32_t vgId) {
SVnode *pVnode = vnodeAcquireNotClose(vgId);
if (pVnode == NULL) {
vDebug("vgId:%d, failed to drop, vnode not find", vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
if (pVnode->dropped) {
vnodeRelease(pVnode);
return TSDB_CODE_SUCCESS;
}
vInfo("vgId:%d, vnode will be dropped, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
pVnode->dropped = 1;
vnodeRelease(pVnode);
vnodeProcessCleanupTask(pVnode);
return TSDB_CODE_SUCCESS;
}
int32_t vnodeCompact(int32_t vgId) {
#if 0
SVnode *pVnode = vnodeAcquire(vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, compact vnode msg is received", vgId);
// not care success or not
tsdbCompact(((SVnode *)pVnode)->tsdb);
vnodeRelease(pVnode);
} else {
vInfo("vgId:%d, vnode not exist, can't compact it", vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
#endif
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeAlterImp(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg) {
#if 0
STsdbCfg tsdbCfg = pVnode->tsdbCfg;
SSyncCfg syncCfg = pVnode->syncCfg;
int32_t dbCfgVersion = pVnode->dbCfgVersion;
int32_t vgCfgVersion = pVnode->vgCfgVersion;
int32_t code = vnodeWriteCfg(pVnodeCfg);
if (code != TSDB_CODE_SUCCESS) {
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
return code;
}
code = vnodeReadCfg(pVnode);
if (code != TSDB_CODE_SUCCESS) {
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
return code;
}
code = walAlter(pVnode->wal, &pVnode->walCfg);
if (code != TSDB_CODE_SUCCESS) {
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
return code;
}
bool tsdbCfgChanged = (memcmp(&tsdbCfg, &pVnode->tsdbCfg, sizeof(STsdbCfg)) != 0);
bool syncCfgChanged = (memcmp(&syncCfg, &pVnode->syncCfg, sizeof(SSyncCfg)) != 0);
vDebug("vgId:%d, tsdbchanged:%d syncchanged:%d while alter vnode", pVnode->vgId, tsdbCfgChanged, syncCfgChanged);
if (tsdbCfgChanged || syncCfgChanged) {
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
// dbCfgVersion can be corrected by status msg
if (syncCfgChanged) {
if (!vnodeSetUpdatingStatus(pVnode)) {
vDebug("vgId:%d, vnode is not ready, do alter operation later", pVnode->vgId);
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
return TSDB_CODE_SUCCESS;
}
code = syncReconfig(pVnode->sync, &pVnode->syncCfg);
if (code != TSDB_CODE_SUCCESS) {
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
vnodeSetReadyStatus(pVnode);
return code;
}
}
if (tsdbCfgChanged && pVnode->tsdb) {
code = tsdbConfigRepo(pVnode->tsdb, &pVnode->tsdbCfg);
if (code != TSDB_CODE_SUCCESS) {
pVnode->dbCfgVersion = dbCfgVersion;
pVnode->vgCfgVersion = vgCfgVersion;
pVnode->syncCfg = syncCfg;
pVnode->tsdbCfg = tsdbCfg;
vnodeSetReadyStatus(pVnode);
return code;
}
}
vnodeSetReadyStatus(pVnode);
}
#endif
return 0;
}
int32_t vnodeAlter(SVnode *pVnode, SCreateVnodeMsg *pVnodeCfg) {
#if 0
vDebug("vgId:%d, current dbCfgVersion:%d vgCfgVersion:%d, input dbCfgVersion:%d vgCfgVersion:%d", pVnode->vgId,
pVnode->dbCfgVersion, pVnode->vgCfgVersion, pVnodeCfg->cfg.dbCfgVersion, pVnodeCfg->cfg.vgCfgVersion);
if (pVnode->dbCfgVersion == pVnodeCfg->cfg.dbCfgVersion && pVnode->vgCfgVersion == pVnodeCfg->cfg.vgCfgVersion) {
vDebug("vgId:%d, cfg not change", pVnode->vgId);
return TSDB_CODE_SUCCESS;
}
int32_t code = vnodeAlterImp(pVnode, pVnodeCfg);
if (code != 0) {
vError("vgId:%d, failed to alter vnode, code:0x%x", pVnode->vgId, code);
} else {
vDebug("vgId:%d, vnode is altered", pVnode->vgId);
}
return code;
#endif
return 0;
}
static void vnodeFindWalRootDir(int32_t vgId, char *walRootDir) {
#if 0
char vnodeDir[TSDB_FILENAME_LEN] = "\0";
snprintf(vnodeDir, TSDB_FILENAME_LEN, "/vnode/vnode%d/wal", vgId);
TDIR *tdir = tfsOpendir(vnodeDir);
if (!tdir) return;
const TFILE *tfile = tfsReaddir(tdir);
if (!tfile) {
tfsClosedir(tdir);
return;
}
sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(tfile->level, tfile->id), vgId);
tfsClosedir(tdir);
#endif
}
int32_t vnodeOpen(int32_t vgId) {
#if 0
char temp[TSDB_FILENAME_LEN * 3];
char rootDir[TSDB_FILENAME_LEN * 2];
char walRootDir[TSDB_FILENAME_LEN * 2] = {0};
snprintf(rootDir, TSDB_FILENAME_LEN * 2, "%s/vnode%d", tsVnodeDir, vgId);
SVnode *pVnode = calloc(sizeof(SVnode), 1);
if (pVnode == NULL) {
vError("vgId:%d, failed to open vnode since no enough memory", vgId);
return TAOS_SYSTEM_ERROR(errno);
}
atomic_add_fetch_32(&pVnode->refCount, 1);
pVnode->vgId = vgId;
pVnode->fversion = 0;
pVnode->version = 0;
pVnode->tsdbCfg.tsdbId = pVnode->vgId;
pVnode->rootDir = strdup(rootDir);
pVnode->accessState = TSDB_VN_ALL_ACCCESS;
tsem_init(&pVnode->sem, 0, 0);
pthread_mutex_init(&pVnode->statusMutex, NULL);
vnodeSetInitStatus(pVnode);
tsdbIncCommitRef(pVnode->vgId);
int32_t code = vnodeReadCfg(pVnode);
if (code != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to read config file, set cfgVersion to 0", pVnode->vgId);
vnodeCleanUp(pVnode);
return 0;
}
code = vnodeReadVersion(pVnode);
if (code != TSDB_CODE_SUCCESS) {
pVnode->version = 0;
vError("vgId:%d, failed to read file version, generate it from data file", pVnode->vgId);
// Allow vnode start even when read file version fails, set file version as wal version or zero
// vnodeCleanUp(pVnode);
// return code;
}
pVnode->fversion = pVnode->version;
pVnode->pWriteQ = vnodeAllocWriteQueue(pVnode);
pVnode->pQueryQ = vnodeAllocQueryQueue(pVnode);
pVnode->pFetchQ = vnodeAllocFetchQueue(pVnode);
if (pVnode->pWriteQ == NULL || pVnode->pQueryQ == NULL || pVnode->pFetchQ == NULL) {
vnodeCleanUp(pVnode);
return terrno;
}
STsdbAppH appH = {0};
appH.appH = (void *)pVnode;
appH.notifyStatus = vnodeProcessTsdbStatus;
appH.cqH = pVnode->cq;
appH.cqCreateFunc = cqCreate;
appH.cqDropFunc = cqDrop;
terrno = 0;
pVnode->tsdb = tsdbOpenRepo(&(pVnode->tsdbCfg), &appH);
if (pVnode->tsdb == NULL) {
vnodeCleanUp(pVnode);
return terrno;
} else if (tsdbGetState(pVnode->tsdb) != TSDB_STATE_OK) {
vError("vgId:%d, failed to open tsdb(state: %d), replica:%d reason:%s", pVnode->vgId, tsdbGetState(pVnode->tsdb),
pVnode->syncCfg.replica, tstrerror(terrno));
if (pVnode->syncCfg.replica <= 1) {
vnodeCleanUp(pVnode);
return TSDB_CODE_VND_INVALID_TSDB_STATE;
} else {
pVnode->fversion = 0;
pVnode->version = 0;
}
}
// walRootDir for wal & syncInfo.path (not empty dir of /vnode/vnode{pVnode->vgId}/wal)
vnodeFindWalRootDir(pVnode->vgId, walRootDir);
if (walRootDir[0] == 0) {
int level = -1, id = -1;
tfsAllocDisk(TFS_PRIMARY_LEVEL, &level, &id);
if (level < 0 || id < 0) {
vnodeCleanUp(pVnode);
return terrno;
}
sprintf(walRootDir, "%s/vnode/vnode%d", TFS_DISK_PATH(level, id), vgId);
}
sprintf(temp, "%s/wal", walRootDir);
pVnode->walCfg.vgId = pVnode->vgId;
pVnode->wal = walOpen(temp, &pVnode->walCfg);
if (pVnode->wal == NULL) {
vnodeCleanUp(pVnode);
return terrno;
}
walRestore(pVnode->wal, pVnode, (FWalWrite)vnodeProcessWalMsg);
if (pVnode->version == 0) {
pVnode->fversion = 0;
pVnode->version = walGetVersion(pVnode->wal);
}
code = tsdbSyncCommit(pVnode->tsdb);
if (code != 0) {
vError("vgId:%d, failed to commit after restore from wal since %s", pVnode->vgId, tstrerror(code));
vnodeCleanUp(pVnode);
return code;
}
walRemoveAllOldFiles(pVnode->wal);
walRenew(pVnode->wal);
pVnode->qMgmt = qOpenQueryMgmt(pVnode->vgId);
if (pVnode->qMgmt == NULL) {
vnodeCleanUp(pVnode);
return terrno;
}
pVnode->events = NULL;
vDebug("vgId:%d, vnode is opened in %s - %s, pVnode:%p", pVnode->vgId, rootDir, walRootDir, pVnode);
taosHashPut(tsVnode.hash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnode *));
vnodeSetReadyStatus(pVnode);
pVnode->role = TAOS_SYNC_ROLE_MASTER;
#endif
return TSDB_CODE_SUCCESS;
}
int32_t vnodeClose(int32_t vgId) {
SVnode *pVnode = vnodeAcquireNotClose(vgId);
if (pVnode == NULL) return 0;
if (pVnode->dropped) {
vnodeRelease(pVnode);
return 0;
}
// pVnode->preClose = 1;
vDebug("vgId:%d, vnode will be closed, pVnode:%p", pVnode->vgId, pVnode);
vnodeRelease(pVnode);
vnodeCleanUp(pVnode);
return 0;
}
void vnodeDestroy(SVnode *pVnode) {
#if 0
int32_t code = 0;
int32_t vgId = pVnode->vgId;
if (pVnode->qMgmt) {
qCleanupQueryMgmt(pVnode->qMgmt);
pVnode->qMgmt = NULL;
}
if (pVnode->wal) {
walStop(pVnode->wal);
}
if (pVnode->tsdb) {
// the deleted vnode does not need to commit, so as to speed up the deletion
int toCommit = 1;
if (pVnode->dropped) toCommit = 0;
code = tsdbCloseRepo(pVnode->tsdb, toCommit);
pVnode->tsdb = NULL;
}
// stop continuous query
if (pVnode->cq) {
void *cq = pVnode->cq;
pVnode->cq = NULL;
cqClose(cq);
}
if (pVnode->wal) {
if (code != 0) {
vError("vgId:%d, failed to commit while close tsdb repo, keep wal", pVnode->vgId);
} else {
walRemoveAllOldFiles(pVnode->wal);
}
walClose(pVnode->wal);
pVnode->wal = NULL;
}
if (pVnode->pWriteQ) {
vnodeFreeWriteQueue(pVnode->pWriteQ);
pVnode->pWriteQ = NULL;
}
if (pVnode->pQueryQ) {
vnodeFreeQueryQueue(pVnode->pQueryQ);
pVnode->pQueryQ = NULL;
}
if (pVnode->pFetchQ) {
vnodeFreeFetchQueue(pVnode->pFetchQ);
pVnode->pFetchQ = NULL;
}
tfree(pVnode->rootDir);
if (pVnode->dropped) {
char rootDir[TSDB_FILENAME_LEN] = {0};
char stagingDir[TSDB_FILENAME_LEN] = {0};
sprintf(rootDir, "%s/vnode%d", "vnode", vgId);
sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
tfsRename(rootDir, stagingDir);
vnodeProcessBackupTask(pVnode);
// dnodeSendStatusMsgToMnode();
}
tsem_destroy(&pVnode->sem);
pthread_mutex_destroy(&pVnode->statusMutex);
free(pVnode);
tsdbDecCommitRef(vgId);
#endif
}
void vnodeCleanUp(SVnode *pVnode) {
#if 0
vDebug("vgId:%d, vnode will cleanup, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
vnodeSetClosingStatus(pVnode);
taosHashRemove(tsVnode.hash, &pVnode->vgId, sizeof(int32_t));
// stop replication module
if (pVnode->sync > 0) {
int64_t sync = pVnode->sync;
pVnode->sync = -1;
syncStop(sync);
}
vDebug("vgId:%d, vnode is cleaned, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
vnodeRelease(pVnode);
#endif
}
#if 0
static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) {
SVnode *pVnode = arg;
if (eno != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to commit since %s, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, tstrerror(eno),
pVnode->fversion, pVnode->version);
pVnode->isCommiting = 0;
pVnode->isFull = 1;
return 0;
}
if (status == TSDB_STATUS_COMMIT_START) {
pVnode->isCommiting = 1;
pVnode->cversion = pVnode->version;
vInfo("vgId:%d, start commit, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
if (!vnodeInInitStatus(pVnode)) {
return walRenew(pVnode->wal);
}
return 0;
}
if (status == TSDB_STATUS_COMMIT_OVER) {
pVnode->isCommiting = 0;
pVnode->isFull = 0;
pVnode->fversion = pVnode->cversion;
vInfo("vgId:%d, commit over, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version);
if (!vnodeInInitStatus(pVnode)) {
walRemoveOneOldFile(pVnode->wal);
}
return vnodeSaveVersion(pVnode);
}
// timer thread callback
if (status == TSDB_STATUS_COMMIT_NOBLOCK) {
qSolveCommitNoBlock(pVnode->tsdb, pVnode->qMgmt);
}
return 0;
}
#endif
static void *vnodeOpenVnode(void *param) {
SOpenVnodeThread *pThread = param;
vDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
setThreadName("vnodeOpenVnode");
for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
int32_t vgId = pThread->vnodeList[v];
char stepDesc[TSDB_STEP_DESC_LEN] = {0};
snprintf(stepDesc, TSDB_STEP_DESC_LEN, "vgId:%d, start to restore, %d of %d have been opened", vgId,
tsVnode.openVnodes, tsVnode.totalVnodes);
// (*vnodeInst()->fp.ReportStartup)("open-vnodes", stepDesc);
if (vnodeOpen(vgId) < 0) {
vError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
pThread->failed++;
} else {
vDebug("vgId:%d, is opened by thread:%d", vgId, pThread->threadIndex);
pThread->opened++;
}
atomic_add_fetch_32(&tsVnode.openVnodes, 1);
}
vDebug("thread:%d, total vnodes:%d, opened:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
pThread->failed);
return NULL;
}
static int32_t vnodeGetVnodeListFromDisk(int32_t vnodeList[], int32_t *numOfVnodes) {
#if 0
DIR *dir = opendir(tsVnodeDir);
if (dir == NULL) return TSDB_CODE_DND_NO_WRITE_ACCESS;
*numOfVnodes = 0;
struct dirent *de = NULL;
while ((de = readdir(dir)) != NULL) {
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
if (de->d_type & DT_DIR) {
if (strncmp("vnode", de->d_name, 5) != 0) continue;
int32_t vnode = atoi(de->d_name + 5);
if (vnode == 0) continue;
(*numOfVnodes)++;
if (*numOfVnodes >= TSDB_MAX_VNODES) {
vError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
closedir(dir);
return TSDB_CODE_DND_TOO_MANY_VNODES;
} else {
vnodeList[*numOfVnodes - 1] = vnode;
}
}
}
closedir(dir);
#endif
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeOpenVnodes() {
int32_t vnodeList[TSDB_MAX_VNODES] = {0};
int32_t numOfVnodes = 0;
int32_t status = vnodeGetVnodeListFromDisk(vnodeList, &numOfVnodes);
if (status != TSDB_CODE_SUCCESS) {
vInfo("failed to get vnode list from disk since code:%d", status);
return status;
}
tsVnode.totalVnodes = numOfVnodes;
int32_t threadNum = tsNumOfCores;
int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
for (int32_t t = 0; t < threadNum; ++t) {
threads[t].threadIndex = t;
threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
}
for (int32_t v = 0; v < numOfVnodes; ++v) {
int32_t t = v % threadNum;
SOpenVnodeThread *pThread = &threads[t];
pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
}
vInfo("start %d threads to open %d vnodes", threadNum, numOfVnodes);
for (int32_t t = 0; t < threadNum; ++t) {
SOpenVnodeThread *pThread = &threads[t];
if (pThread->vnodeNum == 0) continue;
pthread_attr_t thAttr;
pthread_attr_init(&thAttr);
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&pThread->thread, &thAttr, vnodeOpenVnode, pThread) != 0) {
vError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
}
pthread_attr_destroy(&thAttr);
}
int32_t openVnodes = 0;
int32_t failedVnodes = 0;
for (int32_t t = 0; t < threadNum; ++t) {
SOpenVnodeThread *pThread = &threads[t];
if (pThread->vnodeNum > 0 && taosCheckPthreadValid(pThread->thread)) {
pthread_join(pThread->thread, NULL);
}
openVnodes += pThread->opened;
failedVnodes += pThread->failed;
free(pThread->vnodeList);
}
free(threads);
vInfo("there are total vnodes:%d, opened:%d", numOfVnodes, openVnodes);
if (failedVnodes != 0) {
vError("there are total vnodes:%d, failed:%d", numOfVnodes, failedVnodes);
return -1;
}
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
void *pIter = taosHashIterate(tsVnode.hash, NULL);
while (pIter) {
SVnode **pVnode = pIter;
if (*pVnode) {
(*numOfVnodes)++;
if (*numOfVnodes >= TSDB_MAX_VNODES) {
vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
continue;
} else {
vnodeList[*numOfVnodes - 1] = (*pVnode)->vgId;
}
}
pIter = taosHashIterate(tsVnode.hash, pIter);
}
return TSDB_CODE_SUCCESS;
}
static void vnodeCleanupVnodes() {
int32_t vnodeList[TSDB_MAX_VNODES] = {0};
int32_t numOfVnodes = 0;
int32_t code = vnodeGetVnodeList(vnodeList, &numOfVnodes);
if (code != TSDB_CODE_SUCCESS) {
vInfo("failed to get dnode list since code %d", code);
return;
}
for (int32_t i = 0; i < numOfVnodes; ++i) {
vnodeClose(vnodeList[i]);
}
vInfo("total vnodes:%d are all closed", numOfVnodes);
}
static void vnodeInitMsgFp() {
tsVnode.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessMgmtMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_SUBMIT] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = vnodeProcessWriteMsg;
//mq related
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_ACK] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_RESET] = vnodeProcessWriteMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_QUERY] = vnodeProcessReadMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = vnodeProcessReadMsg;
//mq related end
tsVnode.msgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessReadMsg;
tsVnode.msgFp[TSDB_MSG_TYPE_FETCH] = vnodeProcessReadMsg;
}
void vnodeProcessMsg(SRpcMsg *pMsg) { void vnodeProcessMsg(SRpcMsg *pMsg) {
if (tsVnode.msgFp[pMsg->msgType]) { if (tsVint.msgFp[pMsg->msgType]) {
(*tsVnode.msgFp[pMsg->msgType])(pMsg); (*tsVint.msgFp[pMsg->msgType])(pMsg);
} else { } else {
assert(0); assert(0);
} }
} }
int32_t vnodeInitMain() { static void vnodeInitMsgFp() {
vnodeInitMsgFp(); tsVint.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessMgmtMsg;
tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessMgmtMsg;
tsVnode.timer = taosTmrInit(100, 200, 60000, "VND-TIMER"); tsVint.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessMgmtMsg;
if (tsVnode.timer == NULL) { tsVint.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessMgmtMsg;
vError("failed to init vnode timer"); tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessMgmtMsg;
return -1; tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessMgmtMsg;
} tsVint.msgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = vnodeProcessWriteMsg;
tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = vnodeProcessWriteMsg;
tsVnode.hash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); tsVint.msgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = vnodeProcessWriteMsg;
if (tsVnode.hash == NULL) { tsVint.msgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = vnodeProcessWriteMsg;
taosTmrCleanUp(tsVnode.timer); tsVint.msgFp[TSDB_MSG_TYPE_SUBMIT] = vnodeProcessWriteMsg;
vError("failed to init vnode mgmt"); tsVint.msgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = vnodeProcessWriteMsg;
return -1; // mq related
} tsVint.msgFp[TSDB_MSG_TYPE_MQ_CONNECT] = vnodeProcessWriteMsg;
tsVint.msgFp[TSDB_MSG_TYPE_MQ_DISCONNECT] = vnodeProcessWriteMsg;
vInfo("vnode main is initialized"); tsVint.msgFp[TSDB_MSG_TYPE_MQ_ACK] = vnodeProcessWriteMsg;
return vnodeOpenVnodes(); tsVint.msgFp[TSDB_MSG_TYPE_MQ_RESET] = vnodeProcessWriteMsg;
} tsVint.msgFp[TSDB_MSG_TYPE_MQ_QUERY] = vnodeProcessReadMsg;
tsVint.msgFp[TSDB_MSG_TYPE_MQ_CONSUME] = vnodeProcessReadMsg;
void vnodeCleanupMain() { // mq related end
taosTmrCleanUp(tsVnode.timer); tsVint.msgFp[TSDB_MSG_TYPE_QUERY] = vnodeProcessReadMsg;
tsVnode.timer = NULL; tsVint.msgFp[TSDB_MSG_TYPE_FETCH] = vnodeProcessReadMsg;
vnodeCleanupVnodes();
taosHashCleanup(tsVnode.hash);
tsVnode.hash = NULL;
}
static void vnodeBuildVloadMsg(SVnode *pVnode, SStatusMsg *pStatus) {
#if 0
int64_t totalStorage = 0;
int64_t compStorage = 0;
int64_t pointsWritten = 0;
if (vnodeInClosingStatus(pVnode)) return;
if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
if (pVnode->tsdb) {
tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
}
SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
pLoad->vgId = htonl(pVnode->vgId);
pLoad->dbCfgVersion = htonl(pVnode->dbCfgVersion);
pLoad->vgCfgVersion = htonl(pVnode->vgCfgVersion);
pLoad->totalStorage = htobe64(totalStorage);
pLoad->compStorage = htobe64(compStorage);
pLoad->pointsWritten = htobe64(pointsWritten);
pLoad->vnodeVersion = htobe64(pVnode->version);
pLoad->status = pVnode->status;
pLoad->role = pVnode->role;
pLoad->replica = pVnode->syncCfg.replica;
pLoad->compact = (pVnode->tsdb != NULL) ? tsdbGetCompactState(pVnode->tsdb) : 0;
#endif
}
void vnodeGetStatus(struct SStatusMsg *pStatus) {
void *pIter = taosHashIterate(tsVnode.hash, NULL);
while (pIter) {
SVnode **pVnode = pIter;
if (*pVnode) {
vnodeBuildVloadMsg(*pVnode, pStatus);
}
pIter = taosHashIterate(tsVnode.hash, pIter);
}
}
void vnodeSetAccess(struct SVgroupAccess *pAccess, int32_t numOfVnodes) {
for (int32_t i = 0; i < numOfVnodes; ++i) {
pAccess[i].vgId = htonl(pAccess[i].vgId);
SVnode *pVnode = vnodeAcquireNotClose(pAccess[i].vgId);
if (pVnode != NULL) {
pVnode->accessState = pAccess[i].accessState;
if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
}
vnodeRelease(pVnode);
}
}
}
void vnodeBackup(int32_t vgId) {
char newDir[TSDB_FILENAME_LEN] = {0};
char stagingDir[TSDB_FILENAME_LEN] = {0};
sprintf(newDir, "%s/vnode%d", "vnode_bak", vgId);
sprintf(stagingDir, "%s/.staging/vnode%d", "vnode_bak", vgId);
#if 0
if (tsEnableVnodeBak) {
tfsRmdir(newDir);
tfsRename(stagingDir, newDir);
} else {
vInfo("vgId:%d, vnode backup not enabled", vgId);
tfsRmdir(stagingDir);
}
#endif
} }
int32_t vnodeInit(SVnodePara para) { int32_t vnodeInit(SVnodePara para) {
tsVnode.fp = para.fp; vnodeInitMsgFp();
tsVint.fp = para.fp;
struct SSteps *steps = taosStepInit(8, NULL); struct SSteps *steps = taosStepInit(8, NULL);
if (steps == NULL) return -1; if (steps == NULL) return -1;
taosStepAdd(steps, "vnode-main", vnodeInitMain, vnodeCleanupMain); taosStepAdd(steps, "vnode-main", vnodeInitMain, vnodeCleanupMain);
taosStepAdd(steps, "vnode-worker", vnodeInitWorker, vnodeCleanupWorker);
taosStepAdd(steps, "vnode-read", vnodeInitRead, vnodeCleanupRead); taosStepAdd(steps, "vnode-read", vnodeInitRead, vnodeCleanupRead);
taosStepAdd(steps, "vnode-mgmt", vnodeInitMgmt, vnodeCleanupMgmt); taosStepAdd(steps, "vnode-mgmt", vnodeInitMgmt, vnodeCleanupMgmt);
taosStepAdd(steps, "vnode-write", vnodeInitWrite, vnodeCleanupWrite); taosStepAdd(steps, "vnode-write", vnodeInitWrite, vnodeCleanupWrite);
tsVnode.steps = steps; tsVint.steps = steps;
return taosStepExec(tsVnode.steps); return taosStepExec(tsVint.steps);
} }
void vnodeCleanup() { taosStepCleanup(tsVnode.steps); } void vnodeCleanup() { taosStepCleanup(tsVint.steps); }

View File

@ -0,0 +1,712 @@
/*
* 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 "thash.h"
#include "tthread.h"
#include "vnodeFile.h"
#include "vnodeMain.h"
#include "vnodeMgmt.h"
#include "vnodeRead.h"
#include "vnodeWrite.h"
typedef enum _VN_STATUS {
TAOS_VN_STATUS_INIT = 0,
TAOS_VN_STATUS_READY = 1,
TAOS_VN_STATUS_CLOSING = 2,
TAOS_VN_STATUS_UPDATING = 3
} EVnodeStatus;
char *vnodeStatus[] = {"init", "ready", "closing", "updating"};
typedef struct {
pthread_t *threadId;
int32_t threadIndex;
int32_t failed;
int32_t opened;
int32_t vnodeNum;
int32_t *vnodeList;
} SOpenVnodeThread;
static struct {
SHashObj *hash;
int32_t openVnodes;
int32_t totalVnodes;
} tsVnode;
static bool vnodeSetInitStatus(SVnode *pVnode) {
pthread_mutex_lock(&pVnode->statusMutex);
pVnode->status = TAOS_VN_STATUS_INIT;
pthread_mutex_unlock(&pVnode->statusMutex);
return true;
}
static bool vnodeSetReadyStatus(SVnode *pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_UPDATING) {
pVnode->status = TAOS_VN_STATUS_READY;
set = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
static bool vnodeSetUpdatingStatus(SVnode *pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_READY) {
pVnode->status = TAOS_VN_STATUS_UPDATING;
set = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
static bool vnodeSetClosingStatus(SVnode *pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_READY) {
pVnode->status = TAOS_VN_STATUS_CLOSING;
set = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
static bool vnodeInStatus(SVnode *pVnode, EVnodeStatus status) {
bool in = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == status) {
in = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return in;
}
static void vnodeDestroyVnode(SVnode *pVnode) {
int32_t code = 0;
int32_t vgId = pVnode->vgId;
if (pVnode->pSync != NULL) {
syncStop(pVnode->pSync);
pVnode->pSync = NULL;
}
if (pVnode->pQuery) {
// todo
}
if (pVnode->pMeta) {
// todo
}
if (pVnode->pTsdb) {
// todo
}
if (pVnode->pTQ) {
// todo
}
if (pVnode->pWal) {
walClose(pVnode->pWal);
pVnode->pWal = NULL;
}
if (pVnode->allocator) {
// todo
}
if (pVnode->pWriteQ) {
vnodeFreeWriteQueue(pVnode->pWriteQ);
pVnode->pWriteQ = NULL;
}
if (pVnode->pQueryQ) {
vnodeFreeQueryQueue(pVnode->pQueryQ);
pVnode->pQueryQ = NULL;
}
if (pVnode->pFetchQ) {
vnodeFreeFetchQueue(pVnode->pFetchQ);
pVnode->pFetchQ = NULL;
}
if (pVnode->dropped) {
// todo
}
pthread_mutex_destroy(&pVnode->statusMutex);
free(pVnode);
}
static void vnodeCleanupVnode(SVnode *pVnode) {
vnodeSetClosingStatus(pVnode);
taosHashRemove(tsVnode.hash, &pVnode->vgId, sizeof(int32_t));
vnodeRelease(pVnode);
}
static inline int32_t vnodeLogWrite(struct SSyncLogStore *logStore, SyncIndex index, SSyncBuffer *pBuf) {
SVnode *pVnode = logStore->pData; // vnode status can be checked here
return walWrite(pVnode->pWal, index, pBuf->data, (int32_t)pBuf->len);
}
static inline int32_t vnodeLogCommit(struct SSyncLogStore *logStore, SyncIndex index) {
SVnode *pVnode = logStore->pData; // vnode status can be checked here
return walCommit(pVnode->pWal, index);
}
static inline int32_t vnodeLogPrune(struct SSyncLogStore *logStore, SyncIndex index) {
SVnode *pVnode = logStore->pData; // vnode status can be checked here
return walPrune(pVnode->pWal, index);
}
static inline int32_t vnodeLogRollback(struct SSyncLogStore *logStore, SyncIndex index) {
SVnode *pVnode = logStore->pData; // vnode status can be checked here
return walRollback(pVnode->pWal, index);
}
static inline int32_t vnodeSaveServerState(struct SStateManager *stateMng, SSyncServerState *pState) {
SVnode *pVnode = stateMng->pData;
return vnodeSaveState(pVnode->vgId, pState);
}
static inline int32_t vnodeReadServerState(struct SStateManager *stateMng, SSyncServerState *pState) {
SVnode *pVnode = stateMng->pData;
return vnodeSaveState(pVnode->vgId, pState);
}
static inline int32_t vnodeApplyLog(struct SSyncFSM *fsm, SyncIndex index, const SSyncBuffer *buf, void *pData) {
return 0;
}
static inline int32_t vnodeOnClusterChanged(struct SSyncFSM *fsm, const SSyncCluster *cluster, void *pData) { return 0; }
static inline int32_t vnodeGetSnapshot(struct SSyncFSM *fsm, SSyncBuffer **ppBuf, int32_t *objId, bool *isLast) {
return 0;
}
static inline int32_t vnodeApplySnapshot(struct SSyncFSM *fsm, SSyncBuffer *pBuf, int32_t objId, bool isLast) {
return 0;
}
static inline int32_t vnodeOnRestoreDone(struct SSyncFSM *fsm) { return 0; }
static inline void vnodeOnRollback(struct SSyncFSM *fsm, SyncIndex index, const SSyncBuffer *buf) {}
static inline void vnodeOnRoleChanged(struct SSyncFSM *fsm, const SNodesRole *pRole) {}
static int32_t vnodeOpenVnode(int32_t vgId) {
int32_t code = 0;
SVnode *pVnode = calloc(sizeof(SVnode), 1);
if (pVnode == NULL) {
vError("vgId:%d, failed to open vnode since no enough memory", vgId);
return TAOS_SYSTEM_ERROR(errno);
}
pVnode->vgId = vgId;
pVnode->accessState = TAOS_VN_STATUS_INIT;
pVnode->status = TSDB_VN_ALL_ACCCESS;
pVnode->refCount = 1;
pVnode->role = TAOS_SYNC_ROLE_CANDIDATE;
pthread_mutex_init(&pVnode->statusMutex, NULL);
vDebug("vgId:%d, vnode is opened", pVnode->vgId);
taosHashPut(tsVnode.hash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnode *));
code = vnodeReadCfg(vgId, &pVnode->cfg);
if (code != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to read config file, set cfgVersion to 0", pVnode->vgId);
pVnode->cfg.dropped = 1;
vnodeCleanupVnode(pVnode);
return 0;
}
code = vnodeSaveState(vgId, &pVnode->term);
if (code != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to read term file since %s", pVnode->vgId, tstrerror(code));
pVnode->cfg.dropped = 1;
vnodeCleanupVnode(pVnode);
return code;
}
pVnode->pWriteQ = vnodeAllocWriteQueue(pVnode);
pVnode->pQueryQ = vnodeAllocQueryQueue(pVnode);
pVnode->pFetchQ = vnodeAllocFetchQueue(pVnode);
if (pVnode->pWriteQ == NULL || pVnode->pQueryQ == NULL || pVnode->pFetchQ == NULL) {
vnodeCleanupVnode(pVnode);
return terrno;
}
char path[PATH_MAX + 20];
snprintf(path, sizeof(path), "%s/vnode%d/wal", tsVnodeDir, vgId);
pVnode->pWal = walOpen(path, &pVnode->cfg.wal);
if (pVnode->pWal == NULL) {
vnodeCleanupVnode(pVnode);
return terrno;
}
// create sync node
SSyncInfo syncInfo = {0};
syncInfo.vgId = vgId;
syncInfo.snapshotIndex = 0; // todo, from tsdb
memcpy(&syncInfo.syncCfg, &pVnode->cfg.sync, sizeof(SSyncCluster));
syncInfo.fsm.pData = pVnode;
syncInfo.fsm.applyLog = vnodeApplyLog;
syncInfo.fsm.onClusterChanged = vnodeOnClusterChanged;
syncInfo.fsm.getSnapshot = vnodeGetSnapshot;
syncInfo.fsm.applySnapshot = vnodeApplySnapshot;
syncInfo.fsm.onRestoreDone = vnodeOnRestoreDone;
syncInfo.fsm.onRollback = vnodeOnRollback;
syncInfo.fsm.onRoleChanged = vnodeOnRoleChanged;
syncInfo.logStore.pData = pVnode;
syncInfo.logStore.logWrite = vnodeLogWrite;
syncInfo.logStore.logCommit = vnodeLogCommit;
syncInfo.logStore.logPrune = vnodeLogPrune;
syncInfo.logStore.logRollback = vnodeLogRollback;
syncInfo.stateManager.pData = pVnode;
syncInfo.stateManager.saveServerState = vnodeSaveServerState;
syncInfo.stateManager.readServerState = vnodeReadServerState;
pVnode->pSync = syncStart(&syncInfo);
if (pVnode->pSync == NULL) {
vnodeCleanupVnode(pVnode);
return terrno;
}
vnodeSetReadyStatus(pVnode);
return TSDB_CODE_SUCCESS;
}
int32_t vnodeCreateVnode(int32_t vgId, SVnodeCfg *pCfg) {
int32_t code = 0;
char path[PATH_MAX + 20] = {0};
snprintf(path, sizeof(path), "%s/vnode%d", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
snprintf(path, sizeof(path), "%s/vnode%d/cfg", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
snprintf(path, sizeof(path), "%s/vnode%d/wal", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
snprintf(path, sizeof(path), "%s/vnode%d/tq", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
snprintf(path, sizeof(path), "%s/vnode%d/tsdb", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
snprintf(path, sizeof(path), "%s/vnode%d/meta", tsVnodeDir, vgId);
if (taosMkDir(path) < 0) {
code = TAOS_SYSTEM_ERROR(errno);
vError("vgId:%d, failed to create since %s", vgId, tstrerror(code));
return code;
}
code = vnodeWriteCfg(vgId, pCfg);
if (code != 0) {
vError("vgId:%d, failed to save vnode cfg since %s", vgId, tstrerror(code));
return code;
}
return vnodeOpenVnode(vgId);
}
int32_t vnodeAlterVnode(SVnode * pVnode, SVnodeCfg *pCfg) {
int32_t code = 0;
int32_t vgId = pVnode->vgId;
bool walChanged = (memcmp(&pCfg->wal, &pVnode->cfg.wal, sizeof(SWalCfg)) != 0);
bool tsdbChanged = (memcmp(&pCfg->tsdb, &pVnode->cfg.tsdb, sizeof(STsdbCfg)) != 0);
bool metaChanged = (memcmp(&pCfg->meta, &pVnode->cfg.meta, sizeof(SMetaCfg)) != 0);
bool syncChanged = (memcmp(&pCfg->sync, &pVnode->cfg.sync, sizeof(SSyncCluster)) != 0);
if (!walChanged && !tsdbChanged && !metaChanged && !syncChanged) {
vDebug("vgId:%d, nothing changed", vgId);
vnodeRelease(pVnode);
return code;
}
code = vnodeWriteCfg(pVnode->vgId, pCfg);
if (code != 0) {
vError("vgId:%d, failed to write alter msg to file since %s", vgId, tstrerror(code));
vnodeRelease(pVnode);
return code;
}
pVnode->cfg = *pCfg;
if (walChanged) {
code = walAlter(pVnode->pWal, &pVnode->cfg.wal);
if (code != 0) {
vDebug("vgId:%d, failed to alter wal since %s", vgId, tstrerror(code));
vnodeRelease(pVnode);
return code;
}
}
if (tsdbChanged) {
// todo
}
if (metaChanged) {
// todo
}
if (syncChanged) {
syncReconfig(pVnode->pSync, &pVnode->cfg.sync);
}
vnodeRelease(pVnode);
return code;
}
int32_t vnodeDropVnode(SVnode *pVnode) {
if (pVnode->cfg.dropped) {
vInfo("vgId:%d, already set drop flag, ref:%d", pVnode->vgId, pVnode->refCount);
vnodeRelease(pVnode);
return TSDB_CODE_SUCCESS;
}
pVnode->cfg.dropped = 1;
int32_t code = vnodeWriteCfg(pVnode->vgId, &pVnode->cfg);
if (code == 0) {
vInfo("vgId:%d, set drop flag, ref:%d", pVnode->vgId, pVnode->refCount);
vnodeCleanupVnode(pVnode);
} else {
vError("vgId:%d, failed to set drop flag since %s", pVnode->vgId, tstrerror(code));
pVnode->cfg.dropped = 0;
}
vnodeRelease(pVnode);
return code;
}
int32_t vnodeSyncVnode(SVnode *pVnode) {
return TSDB_CODE_SUCCESS;
}
int32_t vnodeCompactVnode(SVnode *pVnode) {
return TSDB_CODE_SUCCESS;
}
static void *vnodeOpenVnodeFunc(void *param) {
SOpenVnodeThread *pThread = param;
vDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
setThreadName("vnodeOpenVnode");
for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
int32_t vgId = pThread->vnodeList[v];
char stepDesc[TSDB_STEP_DESC_LEN] = {0};
snprintf(stepDesc, TSDB_STEP_DESC_LEN, "vgId:%d, start to restore, %d of %d have been opened", vgId,
tsVnode.openVnodes, tsVnode.totalVnodes);
// (*vnodeInst()->fp.ReportStartup)("open-vnodes", stepDesc);
if (vnodeOpenVnode(vgId) < 0) {
vError("vgId:%d, failed to open vnode by thread:%d", vgId, pThread->threadIndex);
pThread->failed++;
} else {
vDebug("vgId:%d, is opened by thread:%d", vgId, pThread->threadIndex);
pThread->opened++;
}
atomic_add_fetch_32(&tsVnode.openVnodes, 1);
}
vDebug("thread:%d, total vnodes:%d, opened:%d failed:%d", pThread->threadIndex, pThread->vnodeNum, pThread->opened,
pThread->failed);
return NULL;
}
static int32_t vnodeGetVnodeListFromDisk(int32_t vnodeList[], int32_t *numOfVnodes) {
#if 0
DIR *dir = opendir(tsVnodeDir);
if (dir == NULL) return TSDB_CODE_DND_NO_WRITE_ACCESS;
*numOfVnodes = 0;
struct dirent *de = NULL;
while ((de = readdir(dir)) != NULL) {
if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue;
if (de->d_type & DT_DIR) {
if (strncmp("vnode", de->d_name, 5) != 0) continue;
int32_t vnode = atoi(de->d_name + 5);
if (vnode == 0) continue;
(*numOfVnodes)++;
if (*numOfVnodes >= TSDB_MAX_VNODES) {
vError("vgId:%d, too many vnode directory in disk, exist:%d max:%d", vnode, *numOfVnodes, TSDB_MAX_VNODES);
closedir(dir);
return TSDB_CODE_DND_TOO_MANY_VNODES;
} else {
vnodeList[*numOfVnodes - 1] = vnode;
}
}
}
closedir(dir);
#endif
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeOpenVnodes() {
int32_t vnodeList[TSDB_MAX_VNODES] = {0};
int32_t numOfVnodes = 0;
int32_t status = vnodeGetVnodeListFromDisk(vnodeList, &numOfVnodes);
if (status != TSDB_CODE_SUCCESS) {
vInfo("failed to get vnode list from disk since code:%d", status);
return status;
}
tsVnode.totalVnodes = numOfVnodes;
int32_t threadNum = tsNumOfCores;
int32_t vnodesPerThread = numOfVnodes / threadNum + 1;
SOpenVnodeThread *threads = calloc(threadNum, sizeof(SOpenVnodeThread));
for (int32_t t = 0; t < threadNum; ++t) {
threads[t].threadIndex = t;
threads[t].vnodeList = calloc(vnodesPerThread, sizeof(int32_t));
}
for (int32_t v = 0; v < numOfVnodes; ++v) {
int32_t t = v % threadNum;
SOpenVnodeThread *pThread = &threads[t];
pThread->vnodeList[pThread->vnodeNum++] = vnodeList[v];
}
vInfo("start %d threads to open %d vnodes", threadNum, numOfVnodes);
for (int32_t t = 0; t < threadNum; ++t) {
SOpenVnodeThread *pThread = &threads[t];
if (pThread->vnodeNum == 0) continue;
pThread->threadId = taosCreateThread(vnodeOpenVnodeFunc, pThread);
if (pThread->threadId == NULL) {
vError("thread:%d, failed to create thread to open vnode, reason:%s", pThread->threadIndex, strerror(errno));
}
}
int32_t openVnodes = 0;
int32_t failedVnodes = 0;
for (int32_t t = 0; t < threadNum; ++t) {
SOpenVnodeThread *pThread = &threads[t];
taosDestoryThread(pThread->threadId);
pThread->threadId = NULL;
openVnodes += pThread->opened;
failedVnodes += pThread->failed;
free(pThread->vnodeList);
}
free(threads);
vInfo("there are total vnodes:%d, opened:%d", numOfVnodes, openVnodes);
if (failedVnodes != 0) {
vError("there are total vnodes:%d, failed:%d", numOfVnodes, failedVnodes);
return -1;
}
return TSDB_CODE_SUCCESS;
}
static int32_t vnodeGetVnodeList(SVnode *vnodeList[], int32_t *numOfVnodes) {
void *pIter = taosHashIterate(tsVnode.hash, NULL);
while (pIter) {
SVnode **pVnode = pIter;
if (*pVnode) {
(*numOfVnodes)++;
if (*numOfVnodes >= TSDB_MAX_VNODES) {
vError("vgId:%d, too many open vnodes, exist:%d max:%d", (*pVnode)->vgId, *numOfVnodes, TSDB_MAX_VNODES);
continue;
} else {
vnodeList[*numOfVnodes - 1] = (*pVnode);
}
}
pIter = taosHashIterate(tsVnode.hash, pIter);
}
return TSDB_CODE_SUCCESS;
}
static void vnodeCleanupVnodes() {
SVnode* vnodeList[TSDB_MAX_VNODES] = {0};
int32_t numOfVnodes = 0;
int32_t code = vnodeGetVnodeList(vnodeList, &numOfVnodes);
if (code != TSDB_CODE_SUCCESS) {
vInfo("failed to get dnode list since code %d", code);
return;
}
for (int32_t i = 0; i < numOfVnodes; ++i) {
vnodeCleanupVnode(vnodeList[i]);
}
vInfo("total vnodes:%d are all closed", numOfVnodes);
}
static void vnodeIncRef(void *ptNode) {
assert(ptNode != NULL);
SVnode **ppVnode = (SVnode **)ptNode;
assert(ppVnode);
assert(*ppVnode);
SVnode *pVnode = *ppVnode;
atomic_add_fetch_32(&pVnode->refCount, 1);
vTrace("vgId:%d, get vnode, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode);
}
SVnode *vnodeAcquireInAllState(int32_t vgId) {
SVnode *pVnode = NULL;
// taosHashGetClone(tsVnode.hash, &vgId, sizeof(int32_t), vnodeIncRef, (void*)&pVnode);
if (pVnode == NULL) {
vDebug("vgId:%d, can't accquire since not exist", vgId);
terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
return NULL;
}
return pVnode;
}
SVnode *vnodeAcquire(int32_t vgId) {
SVnode *pVnode = vnodeAcquireInAllState(vgId);
if (pVnode == NULL) return NULL;
if (vnodeInStatus(pVnode, TAOS_VN_STATUS_READY)) {
return pVnode;
} else {
vDebug("vgId:%d, can't accquire since not in ready status", vgId);
vnodeRelease(pVnode);
terrno = TSDB_CODE_VND_INVALID_TSDB_STATE;
return NULL;
}
}
void vnodeRelease(SVnode *pVnode) {
if (pVnode == NULL) return;
int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
int32_t vgId = pVnode->vgId;
vTrace("vgId:%d, release vnode, refCount:%d pVnode:%p", vgId, refCount, pVnode);
assert(refCount >= 0);
if (refCount <= 0) {
vDebug("vgId:%d, vnode will be destroyed, refCount:%d pVnode:%p", vgId, refCount, pVnode);
vnodeDestroyVnode(pVnode);
int32_t count = taosHashGetSize(tsVnode.hash);
vDebug("vgId:%d, vnode is destroyed, vnodes:%d", vgId, count);
}
}
int32_t vnodeInitMain() {
tsVnode.hash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
if (tsVnode.hash == NULL) {
vError("failed to init vnode mgmt");
return -1;
}
vInfo("vnode main is initialized");
return vnodeOpenVnodes();
}
void vnodeCleanupMain() {
vnodeCleanupVnodes();
taosHashCleanup(tsVnode.hash);
tsVnode.hash = NULL;
}
static void vnodeBuildVloadMsg(SVnode *pVnode, SStatusMsg *pStatus) {
int64_t totalStorage = 0;
int64_t compStorage = 0;
int64_t pointsWritten = 0;
if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;
// if (pVnode->tsdb) {
// tsdbReportStat(pVnode->tsdb, &pointsWritten, &totalStorage, &compStorage);
// }
SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
pLoad->vgId = htonl(pVnode->vgId);
pLoad->totalStorage = htobe64(totalStorage);
pLoad->compStorage = htobe64(compStorage);
pLoad->pointsWritten = htobe64(pointsWritten);
pLoad->status = pVnode->status;
pLoad->role = pVnode->role;
}
void vnodeGetStatus(SStatusMsg *pStatus) {
void *pIter = taosHashIterate(tsVnode.hash, NULL);
while (pIter) {
SVnode **pVnode = pIter;
if (*pVnode) {
vnodeBuildVloadMsg(*pVnode, pStatus);
}
pIter = taosHashIterate(tsVnode.hash, pIter);
}
}
void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) {
for (int32_t i = 0; i < numOfVnodes; ++i) {
pAccess[i].vgId = htonl(pAccess[i].vgId);
SVnode *pVnode = vnodeAcquire(pAccess[i].vgId);
if (pVnode != NULL) {
pVnode->accessState = pAccess[i].accessState;
if (pVnode->accessState != TSDB_VN_ALL_ACCCESS) {
vDebug("vgId:%d, access state is set to %d", pAccess[i].vgId, pVnode->accessState);
}
vnodeRelease(pVnode);
}
}
}

View File

@ -15,21 +15,185 @@
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "os.h" #include "os.h"
#include "vnodeMain.h"
#include "vnodeMgmt.h" #include "vnodeMgmt.h"
#include "vnodeMgmtMsg.h"
typedef struct {
SRpcMsg rpcMsg;
char pCont[];
} SVnMgmtMsg;
static struct { static struct {
SWorkerPool pool; SWorkerPool createPool;
taos_queue pQueue; taos_queue createQueue;
SWorkerPool workerPool;
taos_queue workerQueue;
int32_t (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *); int32_t (*msgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
} tsVmgmt = {0}; } tsVmgmt = {0};
static int32_t vnodeParseCreateVnodeReq(SRpcMsg *rpcMsg, int32_t *vgId, SVnodeCfg *pCfg) {
SCreateVnodeMsg *pCreate = rpcMsg->pCont;
*vgId = htonl(pCreate->vgId);
pCfg->dropped = 0;
pCfg->quorum = pCreate->quorum;
tstrncpy(pCfg->db, pCreate->db, sizeof(pCfg->db));
pCfg->tsdb.cacheBlockSize = htonl(pCreate->cacheBlockSize);
pCfg->tsdb.totalBlocks = htonl(pCreate->totalBlocks);
pCfg->tsdb.daysPerFile = htonl(pCreate->daysPerFile);
pCfg->tsdb.daysToKeep1 = htonl(pCreate->daysToKeep1);
pCfg->tsdb.daysToKeep2 = htonl(pCreate->daysToKeep2);
pCfg->tsdb.daysToKeep0 = htonl(pCreate->daysToKeep0);
pCfg->tsdb.minRowsPerFileBlock = htonl(pCreate->minRowsPerFileBlock);
pCfg->tsdb.maxRowsPerFileBlock = htonl(pCreate->maxRowsPerFileBlock);
pCfg->tsdb.precision = pCreate->precision;
pCfg->tsdb.compression = pCreate->compression;
pCfg->tsdb.cacheLastRow = pCreate->cacheLastRow;
pCfg->tsdb.update = pCreate->update;
pCfg->wal.fsyncPeriod = htonl(pCreate->fsyncPeriod);
pCfg->wal.walLevel = pCreate->walLevel;
pCfg->sync.replica = pCreate->replica;
pCfg->sync.selfIndex = pCreate->selfIndex;
for (int32_t j = 0; j < pCreate->replica; ++j) {
pCfg->sync.nodeInfo[j].nodePort = htons(pCreate->nodes[j].port);
tstrncpy(pCfg->sync.nodeInfo[j].nodeFqdn, pCreate->nodes[j].fqdn, TSDB_FQDN_LEN);
}
return 0;
}
static int32_t vnodeProcessCreateVnodeReq(SRpcMsg *rpcMsg) {
SVnodeCfg vnodeCfg = {0};
int32_t vgId = 0;
int32_t code = vnodeParseCreateVnodeReq(rpcMsg, &vgId, &vnodeCfg);
if (code != 0) {
vError("failed to parse create vnode msg since %s", tstrerror(code));
}
vDebug("vgId:%d, create vnode req is received", vgId);
SVnode *pVnode = vnodeAcquireInAllState(vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, already exist, return success", vgId);
vnodeRelease(pVnode);
return code;
}
code = vnodeCreateVnode(vgId, &vnodeCfg);
if (code != 0) {
vError("vgId:%d, failed to create vnode since %s", vgId, tstrerror(code));
}
return code;
}
static int32_t vnodeProcessAlterVnodeReq(SRpcMsg *rpcMsg) {
SVnodeCfg vnodeCfg = {0};
int32_t vgId = 0;
int32_t code = vnodeParseCreateVnodeReq(rpcMsg, &vgId, &vnodeCfg);
if (code != 0) {
vError("failed to parse create vnode msg since %s", tstrerror(code));
}
vDebug("vgId:%d, alter vnode req is received", vgId);
SVnode *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
code = terrno;
vDebug("vgId:%d, failed to alter vnode since %s", vgId, tstrerror(code));
return code;
}
code = vnodeAlterVnode(pVnode, &vnodeCfg);
if (code != 0) {
vError("vgId:%d, failed to alter vnode since %s", vgId, tstrerror(code));
}
vnodeRelease(pVnode);
return code;
}
static SDropVnodeMsg *vnodeParseDropVnodeReq(SRpcMsg *rpcMsg) {
SDropVnodeMsg *pDrop = rpcMsg->pCont;
pDrop->vgId = htonl(pDrop->vgId);
return pDrop;
}
static int32_t vnodeProcessSyncVnodeReq(SRpcMsg *rpcMsg) {
SSyncVnodeMsg *pSync = (SSyncVnodeMsg *)vnodeParseDropVnodeReq(rpcMsg);
int32_t code = 0;
int32_t vgId = pSync->vgId;
vDebug("vgId:%d, sync vnode req is received", vgId);
SVnode *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
code = terrno;
vDebug("vgId:%d, failed to sync since %s", vgId, tstrerror(code));
return code;
}
code = vnodeSyncVnode(pVnode);
if (code != 0) {
vError("vgId:%d, failed to compact vnode since %s", vgId, tstrerror(code));
}
vnodeRelease(pVnode);
return code;
}
static int32_t vnodeProcessCompactVnodeReq(SRpcMsg *rpcMsg) {
SCompactVnodeMsg *pCompact = (SCompactVnodeMsg *)vnodeParseDropVnodeReq(rpcMsg);
int32_t code = 0;
int32_t vgId = pCompact->vgId;
vDebug("vgId:%d, compact vnode req is received", vgId);
SVnode *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
code = terrno;
vDebug("vgId:%d, failed to compact since %s", vgId, tstrerror(code));
return code;
}
code = vnodeCompactVnode(pVnode);
if (code != 0) {
vError("vgId:%d, failed to compact vnode since %s", vgId, tstrerror(code));
}
vnodeRelease(pVnode);
return code;
}
static int32_t vnodeProcessDropVnodeReq(SRpcMsg *rpcMsg) {
SDropVnodeMsg *pDrop = vnodeParseDropVnodeReq(rpcMsg);
int32_t code = 0;
int32_t vgId = pDrop->vgId;
vDebug("vgId:%d, drop vnode req is received", vgId);
SVnode *pVnode = vnodeAcquire(vgId);
if (pVnode == NULL) {
code = terrno;
vDebug("vgId:%d, failed to drop since %s", vgId, tstrerror(code));
return code;
}
code = vnodeDropVnode(pVnode);
if (code != 0) {
vError("vgId:%d, failed to drop vnode since %s", vgId, tstrerror(code));
}
vnodeRelease(pVnode);
return code;
}
static int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg) {
vError("alter stream msg not processed");
return TSDB_CODE_VND_MSG_NOT_PROCESSED;
}
static int32_t vnodeProcessMgmtStart(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype) { static int32_t vnodeProcessMgmtStart(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype) {
SRpcMsg *pMsg = &pMgmt->rpcMsg; SRpcMsg *pMsg = &pMgmt->rpcMsg;
int32_t msgType = pMsg->msgType; int32_t msgType = pMsg->msgType;
@ -43,27 +207,21 @@ static int32_t vnodeProcessMgmtStart(void *unused, SVnMgmtMsg *pMgmt, int32_t qt
} }
} }
static void vnodeSendMgmtEnd(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype, int32_t code) { static void vnodeProcessMgmtEnd(void *unused, SVnMgmtMsg *pMgmt, int32_t qtype, int32_t code) {
SRpcMsg *pMsg = &pMgmt->rpcMsg; SRpcMsg *pMsg = &pMgmt->rpcMsg;
SRpcMsg rsp = {0}; vTrace("msg:%p, is processed, result:%s", pMgmt, tstrerror(code));
rsp.code = code; SRpcMsg rsp = {.code = code, .handle = pMsg->handle};
vTrace("msg:%p, is processed, code:0x%x", pMgmt, rsp.code); rpcSendResponse(&rsp);
if (rsp.code != TSDB_CODE_DND_ACTION_IN_PROGRESS) { taosFreeQitem(pMgmt);
rsp.handle = pMsg->handle;
rsp.pCont = NULL;
rpcSendResponse(&rsp);
}
taosFreeQitem(pMsg);
} }
static void vnodeInitMgmtReqFp() { static void vnodeInitMgmtReqFp() {
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessCreateVnodeMsg; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = vnodeProcessCreateVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessAlterVnodeMsg; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = vnodeProcessAlterVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessSyncVnodeMsg; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_SYNC_VNODE] = vnodeProcessSyncVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE]= vnodeProcessCompactVnodeMsg; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_COMPACT_VNODE] = vnodeProcessCompactVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessDropVnodeMsg; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_DROP_VNODE] = vnodeProcessDropVnodeReq;
tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessAlterStreamReq; tsVmgmt.msgFp[TSDB_MSG_TYPE_MD_ALTER_STREAM] = vnodeProcessAlterStreamReq;
} }
@ -75,14 +233,18 @@ static int32_t vnodeWriteToMgmtQueue(SRpcMsg *pMsg) {
pMgmt->rpcMsg = *pMsg; pMgmt->rpcMsg = *pMsg;
pMgmt->rpcMsg.pCont = pMgmt->pCont; pMgmt->rpcMsg.pCont = pMgmt->pCont;
memcpy(pMgmt->pCont, pMsg->pCont, pMsg->contLen); memcpy(pMgmt->pCont, pMsg->pCont, pMsg->contLen);
taosWriteQitem(tsVmgmt.pQueue, TAOS_QTYPE_RPC, pMgmt);
return TSDB_CODE_SUCCESS; if (pMsg->msgType == TSDB_MSG_TYPE_MD_CREATE_VNODE) {
return taosWriteQitem(tsVmgmt.createQueue, TAOS_QTYPE_RPC, pMgmt);
} else {
return taosWriteQitem(tsVmgmt.workerQueue, TAOS_QTYPE_RPC, pMgmt);
}
} }
void vnodeProcessMgmtMsg(SRpcMsg *pMsg) { void vnodeProcessMgmtMsg(SRpcMsg *pMsg) {
int32_t code = vnodeWriteToMgmtQueue(pMsg); int32_t code = vnodeWriteToMgmtQueue(pMsg);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
vError("msg, ahandle:%p type:%s not processed since %s", pMsg->ahandle, taosMsg[pMsg->msgType], tstrerror(code));
SRpcMsg rsp = {.handle = pMsg->handle, .code = code}; SRpcMsg rsp = {.handle = pMsg->handle, .code = code};
rpcSendResponse(&rsp); rpcSendResponse(&rsp);
} }
@ -93,25 +255,41 @@ void vnodeProcessMgmtMsg(SRpcMsg *pMsg) {
int32_t vnodeInitMgmt() { int32_t vnodeInitMgmt() {
vnodeInitMgmtReqFp(); vnodeInitMgmtReqFp();
SWorkerPool *pPool = &tsVmgmt.pool; SWorkerPool *pPool = &tsVmgmt.createPool;
pPool->name = "vmgmt"; pPool->name = "vnode-mgmt-create";
pPool->startFp = (ProcessStartFp)vnodeProcessMgmtStart; pPool->startFp = (ProcessStartFp)vnodeProcessMgmtStart;
pPool->endFp = (ProcessEndFp)vnodeSendMgmtEnd; pPool->endFp = (ProcessEndFp)vnodeProcessMgmtEnd;
pPool->min = 1; pPool->min = 1;
pPool->max = 1; pPool->max = 1;
if (tWorkerInit(pPool) != 0) { if (tWorkerInit(pPool) != 0) {
return TSDB_CODE_VND_OUT_OF_MEMORY; return TSDB_CODE_VND_OUT_OF_MEMORY;
} }
tsVmgmt.pQueue = tWorkerAllocQueue(pPool, NULL); tsVmgmt.createQueue = tWorkerAllocQueue(pPool, NULL);
vInfo("vmgmt is initialized, max worker %d", pPool->max); pPool = &tsVmgmt.workerPool;
pPool->name = "vnode-mgmt-worker";
pPool->startFp = (ProcessStartFp)vnodeProcessMgmtStart;
pPool->endFp = (ProcessEndFp)vnodeProcessMgmtEnd;
pPool->min = 1;
pPool->max = 1;
if (tWorkerInit(pPool) != 0) {
return TSDB_CODE_VND_OUT_OF_MEMORY;
}
tsVmgmt.workerQueue = tWorkerAllocQueue(pPool, NULL);
vInfo("vmgmt is initialized");
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
void vnodeCleanupMgmt() { void vnodeCleanupMgmt() {
tWorkerFreeQueue(&tsVmgmt.pool, tsVmgmt.pQueue); tWorkerFreeQueue(&tsVmgmt.createPool, tsVmgmt.createQueue);
tWorkerCleanup(&tsVmgmt.pool); tWorkerCleanup(&tsVmgmt.createPool);
tsVmgmt.pQueue = NULL; tsVmgmt.createQueue = NULL;
tWorkerFreeQueue(&tsVmgmt.workerPool, tsVmgmt.workerQueue);
tWorkerCleanup(&tsVmgmt.workerPool);
tsVmgmt.createQueue = NULL;
vInfo("vmgmt is closed"); vInfo("vmgmt is closed");
} }

View File

@ -1,93 +0,0 @@
/*
* 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 "vnodeMgmtMsg.h"
static SCreateVnodeMsg* vnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
SCreateVnodeMsg *pCreate = rpcMsg->pCont;
pCreate->cfg.vgId = htonl(pCreate->cfg.vgId);
pCreate->cfg.dbCfgVersion = htonl(pCreate->cfg.dbCfgVersion);
pCreate->cfg.vgCfgVersion = htonl(pCreate->cfg.vgCfgVersion);
pCreate->cfg.maxTables = htonl(pCreate->cfg.maxTables);
pCreate->cfg.cacheBlockSize = htonl(pCreate->cfg.cacheBlockSize);
pCreate->cfg.totalBlocks = htonl(pCreate->cfg.totalBlocks);
pCreate->cfg.daysPerFile = htonl(pCreate->cfg.daysPerFile);
pCreate->cfg.daysToKeep1 = htonl(pCreate->cfg.daysToKeep1);
pCreate->cfg.daysToKeep2 = htonl(pCreate->cfg.daysToKeep2);
pCreate->cfg.daysToKeep = htonl(pCreate->cfg.daysToKeep);
pCreate->cfg.minRowsPerFileBlock = htonl(pCreate->cfg.minRowsPerFileBlock);
pCreate->cfg.maxRowsPerFileBlock = htonl(pCreate->cfg.maxRowsPerFileBlock);
pCreate->cfg.fsyncPeriod = htonl(pCreate->cfg.fsyncPeriod);
pCreate->cfg.commitTime = htonl(pCreate->cfg.commitTime);
for (int32_t j = 0; j < pCreate->cfg.vgReplica; ++j) {
pCreate->nodes[j].nodeId = htonl(pCreate->nodes[j].nodeId);
}
return pCreate;
}
int32_t vnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
SCreateVnodeMsg *pCreate = vnodeParseVnodeMsg(rpcMsg);
SVnode *pVnode = vnodeAcquire(pCreate->cfg.vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, already exist, return success", pCreate->cfg.vgId);
vnodeRelease(pVnode);
return TSDB_CODE_SUCCESS;
} else {
vDebug("vgId:%d, create vnode msg is received", pCreate->cfg.vgId);
return vnodeCreate(pCreate);
}
}
int32_t vnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
SAlterVnodeMsg *pAlter = vnodeParseVnodeMsg(rpcMsg);
void *pVnode = vnodeAcquireNotClose(pAlter->cfg.vgId);
if (pVnode != NULL) {
vDebug("vgId:%d, alter vnode msg is received", pAlter->cfg.vgId);
int32_t code = vnodeAlter(pVnode, pAlter);
vnodeRelease(pVnode);
return code;
} else {
vInfo("vgId:%d, vnode not exist, can't alter it", pAlter->cfg.vgId);
return TSDB_CODE_VND_INVALID_VGROUP_ID;
}
}
int32_t vnodeProcessSyncVnodeMsg(SRpcMsg *rpcMsg) {
SSyncVnodeMsg *pSyncVnode = rpcMsg->pCont;
pSyncVnode->vgId = htonl(pSyncVnode->vgId);
return vnodeSync(pSyncVnode->vgId);
}
int32_t vnodeProcessCompactVnodeMsg(SRpcMsg *rpcMsg) {
SCompactVnodeMsg *pCompactVnode = rpcMsg->pCont;
pCompactVnode->vgId = htonl(pCompactVnode->vgId);
return vnodeCompact(pCompactVnode->vgId);
}
int32_t vnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
SDropVnodeMsg *pDrop = rpcMsg->pCont;
pDrop->vgId = htonl(pDrop->vgId);
return vnodeDrop(pDrop->vgId);
}
int32_t vnodeProcessAlterStreamReq(SRpcMsg *pMsg) { return 0; }

View File

@ -14,14 +14,9 @@
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "os.h" #include "vnodeMain.h"
#include "taosmsg.h"
#include "tglobal.h"
// #include "query.h"
#include "vnodeRead.h" #include "vnodeRead.h"
#include "vnodeReadMsg.h" #include "vnodeReadMsg.h"
#include "vnodeStatus.h"
static struct { static struct {
SWorkerPool query; SWorkerPool query;
@ -50,11 +45,6 @@ static int32_t vnodeWriteToRQueue(SVnode *pVnode, void *pCont, int32_t contLen,
} }
#endif #endif
if (!vnodeInReadyStatus(pVnode)) {
vDebug("vgId:%d, failed to write into vread queue, vnode status is %s", pVnode->vgId, vnodeStatus[pVnode->status]);
return TSDB_CODE_APP_NOT_READY;
}
int32_t size = sizeof(SReadMsg) + contLen; int32_t size = sizeof(SReadMsg) + contLen;
SReadMsg *pRead = taosAllocateQitem(size); SReadMsg *pRead = taosAllocateQitem(size);
if (pRead == NULL) { if (pRead == NULL) {
@ -119,7 +109,7 @@ void vnodeProcessReadMsg(SRpcMsg *pMsg) {
pHead->contLen = htonl(pHead->contLen); pHead->contLen = htonl(pHead->contLen);
assert(pHead->contLen > 0); assert(pHead->contLen > 0);
SVnode *pVnode = vnodeAcquireNotClose(pHead->vgId); SVnode *pVnode = vnodeAcquire(pHead->vgId);
if (pVnode != NULL) { if (pVnode != NULL) {
code = vnodeWriteToRQueue(pVnode, pCont, pHead->contLen, TAOS_QTYPE_RPC, pMsg); code = vnodeWriteToRQueue(pVnode, pCont, pHead->contLen, TAOS_QTYPE_RPC, pMsg);
if (code == TSDB_CODE_SUCCESS) queuedMsgNum++; if (code == TSDB_CODE_SUCCESS) queuedMsgNum++;

View File

@ -14,11 +14,7 @@
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "os.h" #include "vnodeMain.h"
#include "taosmsg.h"
#include "tglobal.h"
// #include "query.h"
#include "vnodeStatus.h"
#include "vnodeRead.h" #include "vnodeRead.h"
#include "vnodeReadMsg.h" #include "vnodeReadMsg.h"

View File

@ -1,136 +0,0 @@
/*
* 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 "taosmsg.h"
// #include "query.h"
#include "vnodeRead.h"
#include "vnodeStatus.h"
#include "vnodeWrite.h"
char* vnodeStatus[] = {
"init",
"ready",
"closing",
"updating",
"reset"
};
bool vnodeSetInitStatus(SVnode* pVnode) {
pthread_mutex_lock(&pVnode->statusMutex);
pVnode->status = TAOS_VN_STATUS_INIT;
pthread_mutex_unlock(&pVnode->statusMutex);
return true;
}
bool vnodeSetReadyStatus(SVnode* pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_INIT || pVnode->status == TAOS_VN_STATUS_READY ||
pVnode->status == TAOS_VN_STATUS_UPDATING) {
pVnode->status = TAOS_VN_STATUS_READY;
set = true;
}
#if 0
qQueryMgmtReOpen(pVnode->qMgmt);
#endif
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
static bool vnodeSetClosingStatusImp(SVnode* pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_READY || pVnode->status == TAOS_VN_STATUS_INIT) {
pVnode->status = TAOS_VN_STATUS_CLOSING;
set = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
bool vnodeSetClosingStatus(SVnode* pVnode) {
if (pVnode->status == TAOS_VN_STATUS_CLOSING)
return true;
while (!vnodeSetClosingStatusImp(pVnode)) {
taosMsleep(1);
}
#if 0
// release local resources only after cutting off outside connections
qQueryMgmtNotifyClosed(pVnode->qMgmt);
#endif
vnodeWaitReadCompleted(pVnode);
vnodeWaitWriteCompleted(pVnode);
return true;
}
bool vnodeSetUpdatingStatus(SVnode* pVnode) {
bool set = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_READY) {
pVnode->status = TAOS_VN_STATUS_UPDATING;
set = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return set;
}
bool vnodeInInitStatus(SVnode* pVnode) {
bool in = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_INIT) {
in = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return in;
}
bool vnodeInReadyStatus(SVnode* pVnode) {
bool in = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_READY) {
in = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return in;
}
bool vnodeInClosingStatus(SVnode* pVnode) {
bool in = false;
pthread_mutex_lock(&pVnode->statusMutex);
if (pVnode->status == TAOS_VN_STATUS_CLOSING) {
in = true;
}
pthread_mutex_unlock(&pVnode->statusMutex);
return in;
}

View File

@ -1,103 +0,0 @@
/*
* 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 "cJSON.h"
#include "tglobal.h"
#include "vnodeVersion.h"
int32_t vnodeReadVersion(SVnode *pVnode) {
int32_t len = 0;
int32_t maxLen = 100;
char * content = calloc(1, maxLen + 1);
cJSON * root = NULL;
FILE * fp = NULL;
terrno = TSDB_CODE_VND_INVALID_VRESION_FILE;
char file[TSDB_FILENAME_LEN + 30] = {0};
sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
fp = fopen(file, "r");
if (!fp) {
if (errno != ENOENT) {
vError("vgId:%d, failed to read %s, error:%s", pVnode->vgId, file, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
} else {
terrno = TSDB_CODE_SUCCESS;
}
goto PARSE_VER_ERROR;
}
len = (int32_t)fread(content, 1, maxLen, fp);
if (len <= 0) {
vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
goto PARSE_VER_ERROR;
}
root = cJSON_Parse(content);
if (root == NULL) {
vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
goto PARSE_VER_ERROR;
}
cJSON *ver = cJSON_GetObjectItem(root, "version");
if (!ver || ver->type != cJSON_Number) {
vError("vgId:%d, failed to read %s, version not found", pVnode->vgId, file);
goto PARSE_VER_ERROR;
}
#if 0
pVnode->version = (uint64_t)ver->valueint;
terrno = TSDB_CODE_SUCCESS;
vInfo("vgId:%d, read %s successfully, fver:%" PRIu64, pVnode->vgId, file, pVnode->version);
#endif
PARSE_VER_ERROR:
if (content != NULL) free(content);
if (root != NULL) cJSON_Delete(root);
if (fp != NULL) fclose(fp);
return terrno;
}
int32_t vnodeSaveVersion(SVnode *pVnode) {
char file[TSDB_FILENAME_LEN + 30] = {0};
sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
FILE *fp = fopen(file, "w");
if (!fp) {
vError("vgId:%d, failed to write %s, reason:%s", pVnode->vgId, file, strerror(errno));
return -1;
}
int32_t len = 0;
int32_t maxLen = 100;
char * content = calloc(1, maxLen + 1);
#if 0
len += snprintf(content + len, maxLen - len, "{\n");
len += snprintf(content + len, maxLen - len, " \"version\": %" PRIu64 "\n", pVnode->fversion);
len += snprintf(content + len, maxLen - len, "}\n");
#endif
fwrite(content, 1, len, fp);
taosFsyncFile(fileno(fp));
fclose(fp);
free(content);
terrno = 0;
// vInfo("vgId:%d, successed to write %s, fver:%" PRIu64, pVnode->vgId, file, pVnode->fversion);
return TSDB_CODE_SUCCESS;
}

View File

@ -1,110 +0,0 @@
/*
* 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 "vnodeWorker.h"
enum { CLEANUP_TASK = 0, DESTROY_TASK = 1, BACKUP_TASK = 2 };
typedef struct {
int32_t vgId;
int32_t code;
int32_t type;
void * rpcHandle;
SVnode *pVnode;
} SVnTask;
static struct {
SWorkerPool pool;
taos_queue pQueue;
} tsVworker = {0};
static void vnodeProcessTaskStart(void *unused, SVnTask *pTask, int32_t qtype) {
pTask->code = 0;
switch (pTask->type) {
case CLEANUP_TASK:
vnodeCleanUp(pTask->pVnode);
break;
case DESTROY_TASK:
vnodeDestroy(pTask->pVnode);
break;
case BACKUP_TASK:
vnodeBackup(pTask->vgId);
break;
default:
break;
}
}
static void vnodeProcessTaskEnd(void *unused, SVnTask *pTask, int32_t qtype, int32_t code) {
if (pTask->rpcHandle != NULL) {
SRpcMsg rpcRsp = {.handle = pTask->rpcHandle, .code = pTask->code};
rpcSendResponse(&rpcRsp);
}
taosFreeQitem(pTask);
}
static int32_t vnodeWriteIntoTaskQueue(SVnode *pVnode, int32_t type, void *rpcHandle) {
SVnTask *pTask = taosAllocateQitem(sizeof(SVnTask));
if (pTask == NULL) return TSDB_CODE_VND_OUT_OF_MEMORY;
pTask->vgId = pVnode->vgId;
pTask->pVnode = pVnode;
pTask->rpcHandle = rpcHandle;
pTask->type = type;
return taosWriteQitem(tsVworker.pQueue, TAOS_QTYPE_RPC, pTask);
}
void vnodeProcessCleanupTask(SVnode *pVnode) {
vnodeWriteIntoTaskQueue(pVnode, CLEANUP_TASK, NULL);
}
void vnodeProcessDestroyTask(SVnode *pVnode) {
vnodeWriteIntoTaskQueue(pVnode, DESTROY_TASK, NULL);
}
void vnodeProcessBackupTask(SVnode *pVnode) {
vnodeWriteIntoTaskQueue(pVnode, BACKUP_TASK, NULL);
}
int32_t vnodeInitWorker() {
SWorkerPool *pPool = &tsVworker.pool;
pPool->name = "vworker";
pPool->startFp = (ProcessStartFp)vnodeProcessTaskStart;
pPool->endFp = (ProcessEndFp)vnodeProcessTaskEnd;
pPool->min = 0;
pPool->max = 1;
if (tWorkerInit(pPool) != 0) {
return TSDB_CODE_VND_OUT_OF_MEMORY;
}
tsVworker.pQueue = tWorkerAllocQueue(pPool, NULL);
vInfo("vworker is initialized, max worker %d", pPool->max);
return TSDB_CODE_SUCCESS;
}
void vnodeCleanupWorker() {
tWorkerFreeQueue(&tsVworker.pool, tsVworker.pQueue);
tWorkerCleanup(&tsVworker.pool);
tsVworker.pQueue = NULL;
vInfo("vworker is closed");
}

View File

@ -15,12 +15,7 @@
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include "os.h" #include "os.h"
#include "tglobal.h" #include "vnodeMain.h"
#include "tqueue.h"
#include "tworker.h"
#include "taosmsg.h"
#include "vnodeStatus.h"
#include "vnodeWrite.h" #include "vnodeWrite.h"
#include "vnodeWriteMsg.h" #include "vnodeWriteMsg.h"
@ -68,11 +63,6 @@ static int32_t vnodeWriteToWQueue(SVnode *pVnode, SWalHead *pHead, int32_t qtype
return TSDB_CODE_WAL_SIZE_LIMIT; return TSDB_CODE_WAL_SIZE_LIMIT;
} }
if (!vnodeInReadyStatus(pVnode)) {
vError("vgId:%d, failed to write into vwqueue, vstatus is %s", pVnode->vgId, vnodeStatus[pVnode->status]);
return TSDB_CODE_APP_NOT_READY;
}
if (tsVwrite.queuedBytes > tsMaxVnodeQueuedBytes) { if (tsVwrite.queuedBytes > tsMaxVnodeQueuedBytes) {
vDebug("vgId:%d, too many bytes:%" PRId64 " in vwqueue, flow control", pVnode->vgId, tsVwrite.queuedBytes); vDebug("vgId:%d, too many bytes:%" PRId64 " in vwqueue, flow control", pVnode->vgId, tsVwrite.queuedBytes);
return TSDB_CODE_VND_IS_FLOWCTRL; return TSDB_CODE_VND_IS_FLOWCTRL;
@ -122,7 +112,7 @@ void vnodeProcessWriteMsg(SRpcMsg *pRpcMsg) {
pMsg->vgId = htonl(pMsg->vgId); pMsg->vgId = htonl(pMsg->vgId);
pMsg->contLen = htonl(pMsg->contLen); pMsg->contLen = htonl(pMsg->contLen);
SVnode *pVnode = vnodeAcquireNotClose(pMsg->vgId); SVnode *pVnode = vnodeAcquire(pMsg->vgId);
if (pVnode == NULL) { if (pVnode == NULL) {
code = TSDB_CODE_VND_INVALID_VGROUP_ID; code = TSDB_CODE_VND_INVALID_VGROUP_ID;
} else { } else {

View File

@ -245,11 +245,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_DISK_PERMISSIONS, "No write permission f
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, "Missing data file") TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, "Missing data file")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, "Out of memory") TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, "Out of memory")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, "Unexpected generic error in vnode") TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, "Unexpected generic error in vnode")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_VRESION_FILE, "Invalid version file") TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_CFG_FILE, "Invalid config file")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FULL, "Database memory is full for commit failed") TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_TERM_FILE, "Invalid term file")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full for waiting commit") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_UPDATING, "Database is updating")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_CLOSING, "Database is closing") TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_CLOSING, "Database is closing")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended") TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended")
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied") TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied")