Merge branch '3.0' into feature/tq
This commit is contained in:
commit
4e902908fa
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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*/
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -7,6 +7,6 @@ target_include_directories(
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
function
|
function
|
||||||
PRIVATE os util common
|
PRIVATE os util common
|
||||||
)
|
)
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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);
|
||||||
|
//}
|
|
@ -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);
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
|
@ -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; }
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_*/
|
|
@ -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);
|
||||||
|
|
|
@ -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_*/
|
|
|
@ -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_*/
|
|
|
@ -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_*/
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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); }
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
|
|
@ -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++;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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");
|
|
||||||
}
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue