diff --git a/include/common/taosmsg.h b/include/common/taosmsg.h index b76f82d0a2..9f5dc0c666 100644 --- a/include/common/taosmsg.h +++ b/include/common/taosmsg.h @@ -77,7 +77,7 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_FUNCTION, "drop-function" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CREATE_STB, "create-stb" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_ALTER_STB, "alter-stb" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DROP_STB, "drop-stb" ) -TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_STB_VGROUP, "stb-vgroup" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_VGROUP_LIST, "vgroup-list" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_KILL_QUERY, "kill-query" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_KILL_STREAM, "kill-stream" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_KILL_CONN, "kill-conn" ) @@ -168,8 +168,8 @@ typedef enum _mgmt_table { TSDB_MGMT_TABLE_SCORES, TSDB_MGMT_TABLE_GRANTS, TSDB_MGMT_TABLE_VNODES, - TSDB_MGMT_TABLE_STREAMTABLES, TSDB_MGMT_TABLE_CLUSTER, + TSDB_MGMT_TABLE_STREAMTABLES, TSDB_MGMT_TABLE_TP, TSDB_MGMT_TABLE_FUNCTION, TSDB_MGMT_TABLE_MAX, @@ -214,6 +214,17 @@ typedef enum _mgmt_table { extern char *taosMsg[]; +typedef struct SBuildTableMetaInput { + int32_t vgId; + char *tableFullName; +} SBuildTableMetaInput; + +typedef struct SBuildUseDBInput { + char db[TSDB_TABLE_FNAME_LEN]; + int32_t vgVersion; +} SBuildUseDBInput; + + #pragma pack(push, 1) // null-terminated string instead of char array to avoid too many memory consumption in case of more than 1M tableMeta @@ -384,19 +395,22 @@ typedef struct { int32_t maxDbs; int32_t maxTimeSeries; int32_t maxStreams; - int64_t maxStorage; // In unit of GB int32_t accessState; // Configured only by command + int64_t maxStorage; // In unit of GB + int32_t reserve[8]; } SCreateAcctMsg, SAlterAcctMsg; typedef struct { - char user[TSDB_USER_LEN]; + char user[TSDB_USER_LEN]; + int32_t reserve[8]; } SDropUserMsg, SDropAcctMsg; typedef struct { - int8_t type; - char user[TSDB_USER_LEN]; - char pass[TSDB_PASSWORD_LEN]; - int8_t superUser; // denote if it is a super user or not + int8_t type; + char user[TSDB_USER_LEN]; + char pass[TSDB_PASSWORD_LEN]; + int8_t superUser; // denote if it is a super user or not + int32_t reserve[8]; } SCreateUserMsg, SAlterUserMsg; typedef struct { @@ -614,6 +628,7 @@ typedef struct { typedef struct { char db[TSDB_TABLE_FNAME_LEN]; int8_t ignoreNotExists; + int32_t vgVersion; int32_t reserve[8]; } SUseDbMsg; @@ -775,9 +790,8 @@ typedef struct { } SStbInfoMsg; typedef struct { + SMsgHead msgHead; char tableFname[TSDB_TABLE_FNAME_LEN]; - int8_t createFlag; - char tags[]; } STableInfoMsg; typedef struct { @@ -792,6 +806,21 @@ typedef struct SSTableVgroupMsg { int32_t numOfTables; } SSTableVgroupMsg, SSTableVgroupRspMsg; +typedef struct SVgroupInfo { + int32_t vgId; + int32_t hashBegin; + int32_t hashEnd; + int8_t inUse; + int8_t numOfEps; + SEpAddrMsg epAddr[TSDB_MAX_REPLICA]; +} SVgroupInfo; + +typedef struct SVgroupListRspMsg { + int32_t vgroupNum; + int32_t vgroupVersion; + SVgroupInfo vgroupInfo[]; +} SVgroupListRspMsg; + typedef struct { int32_t vgId; int8_t numOfEps; @@ -815,7 +844,7 @@ typedef struct { int32_t tversion; uint64_t tuid; uint64_t suid; - SVgroupMsg vgroup; + int32_t vgId; SSchema pSchema[]; } STableMetaMsg; @@ -836,6 +865,16 @@ typedef struct { char *data; } STagData; +typedef struct { + char db[TSDB_FULL_DB_NAME_LEN]; + int32_t vgVersion; + int32_t vgNum; + int8_t hashMethod; + SVgroupInfo vgroupInfo[]; +} SUseDbRsp; + + + /* * sql: show tables like '%a_%' * payload is the query condition, e.g., '%a_%' @@ -860,16 +899,19 @@ typedef struct SShowRsp { } SShowRsp; typedef struct { - char ep[TSDB_EP_LEN]; // end point, hostname:port + char ep[TSDB_EP_LEN]; // end point, hostname:port + int32_t reserve[8]; } SCreateDnodeMsg; typedef struct { int32_t dnodeId; + int32_t reserve[8]; } SDropDnodeMsg; typedef struct { int32_t dnodeId; char config[TSDB_DNODE_CONFIG_LEN]; + int32_t reserve[8]; } SCfgDnodeMsg; typedef struct { diff --git a/include/common/tglobal.h b/include/common/tglobal.h index a9b0e60761..42956b6bdd 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -29,12 +29,7 @@ extern char tsLocalFqdn[]; extern char tsLocalEp[]; extern uint16_t tsServerPort; extern int32_t tsStatusInterval; -extern int32_t tsNumOfMnodes; -extern int8_t tsEnableVnodeBak; extern int8_t tsEnableTelemetryReporting; -extern char tsArbitrator[]; -extern int8_t tsArbOnline; -extern int64_t tsArbOnlineTimestamp; // common extern int tsRpcTimer; @@ -60,7 +55,6 @@ extern int tsCompatibleModel; // 2.0 compatible model extern int32_t tsQueryBufferSize; // maximum allowed usage buffer size in MB for each data node during query processing extern int64_t tsQueryBufferSizeBytes; // maximum allowed usage buffer size in byte for each data node during query processing extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked - extern int8_t tsKeepOriginalColumnName; // client @@ -78,66 +72,15 @@ extern float tsStreamComputDelayRatio; // the delayed computing ration of the extern int32_t tsProjectExecInterval; extern int64_t tsMaxRetentWindow; -// db parameters in client -extern int32_t tsCacheBlockSize; -extern int32_t tsBlocksPerVnode; -extern int32_t tsTableIncStepPerVnode; -extern int32_t tsMaxVgroupsPerDb; -extern int16_t tsDaysPerFile; -extern int32_t tsDaysToKeep; -extern int32_t tsMinRowsInFileBlock; -extern int32_t tsMaxRowsInFileBlock; -extern int16_t tsCommitTime; // seconds -extern int32_t tsTimePrecision; -extern int8_t tsCompression; -extern int8_t tsWAL; -extern int32_t tsFsyncPeriod; -extern int32_t tsReplications; -extern int16_t tsPartitons; -extern int32_t tsQuorum; -extern int8_t tsUpdate; -extern int8_t tsCacheLastRow; - -//tsdb -extern bool tsdbForceKeepFile; - // balance -extern int8_t tsEnableBalance; -extern int8_t tsAlternativeRole; -extern int32_t tsBalanceInterval; -extern int32_t tsOfflineThreshold; -extern int8_t tsEnableFlowCtrl; extern int8_t tsEnableSlaveQuery; -extern int8_t tsEnableAdjustMaster; -// restful -extern int32_t tsRestRowLimit; -extern int8_t tsTelegrafUseFieldNum; -// mqtt -extern int8_t tsEnableMqttModule; -extern char tsMqttHostName[]; -extern char tsMqttPort[]; -extern char tsMqttUser[]; -extern char tsMqttPass[]; -extern char tsMqttClientId[]; -extern char tsMqttTopic[]; - -// monitor -extern int8_t tsEnableMonitorModule; -extern char tsMonitorDbName[]; -extern char tsInternalPass[]; -extern int32_t tsMonitorInterval; - -// stream -extern int8_t tsEnableStream; - -// internal +// interna extern int8_t tsPrintAuth; extern char tsVnodeDir[]; extern char tsMnodeDir[]; extern int64_t tsTickPerDay[3]; -extern int32_t tsTopicBianryLen; // system info extern float tsTotalLogDirGB; diff --git a/include/dnode/mnode/sdb/sdb.h b/include/dnode/mnode/sdb/sdb.h index 7e7afc9774..51d7ca7202 100644 --- a/include/dnode/mnode/sdb/sdb.h +++ b/include/dnode/mnode/sdb/sdb.h @@ -99,7 +99,7 @@ extern "C" { sdbFreeRaw(pRaw); \ return NULL; \ } \ - dataPos += sizeof(int16_t); \ + dataPos += sizeof(int16_t); \ } #define SDB_SET_INT8(pRaw, dataPos, val) \ @@ -144,9 +144,10 @@ typedef struct SSdbRow SSdbRow; typedef enum { SDB_KEY_BINARY = 1, SDB_KEY_INT32 = 2, SDB_KEY_INT64 = 3 } EKeyType; typedef enum { SDB_STATUS_CREATING = 1, - SDB_STATUS_READY = 2, + SDB_STATUS_UPDATING = 2, SDB_STATUS_DROPPING = 3, - SDB_STATUS_DROPPED = 4 + SDB_STATUS_READY = 4, + SDB_STATUS_DROPPED = 5 } ESdbStatus; typedef enum { @@ -174,67 +175,19 @@ typedef SSdbRow *(*SdbDecodeFp)(SSdbRaw *pRaw); typedef SSdbRaw *(*SdbEncodeFp)(void *pObj); typedef struct { - /** - * @brief The sdb type of the table. - * - */ - ESdbType sdbType; - - /** - * @brief The key type of the table. - * - */ - EKeyType keyType; - - /** - * @brief The callback function when the table is first deployed. - * - */ + ESdbType sdbType; + EKeyType keyType; SdbDeployFp deployFp; - - /** - * @brief Encode one row of the table into rawdata. - * - */ SdbEncodeFp encodeFp; - - /** - * @brief Decode one row of the table from rawdata. - * - */ SdbDecodeFp decodeFp; - - /** - * @brief The callback function when insert a row to sdb. - * - */ SdbInsertFp insertFp; - - /** - * @brief The callback function when undate a row in sdb. - * - */ SdbUpdateFp updateFp; - - /** - * @brief The callback function when delete a row from sdb. - * - */ SdbDeleteFp deleteFp; } SSdbTable; typedef struct SSdbOpt { - /** - * @brief The path of the sdb file. - * - */ const char *path; - - /** - * @brief The mnode object. - * - */ - SMnode *pMnode; + SMnode *pMnode; } SSdbOpt; /** @@ -342,6 +295,15 @@ void sdbCancelFetch(SSdb *pSdb, void *pIter); */ int32_t sdbGetSize(SSdb *pSdb, ESdbType type); +/** + * @brief Get the max id of the table, keyType of table should be INT32 + * + * @param pSdb The sdb object. + * @param pIter The type of the table. + * @record int32_t The max id of the table + */ +int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type); + SSdbRaw *sdbAllocRaw(ESdbType type, int8_t sver, int32_t dataLen); void sdbFreeRaw(SSdbRaw *pRaw); int32_t sdbSetRawInt8(SSdbRaw *pRaw, int32_t dataPos, int8_t val); diff --git a/include/dnode/vnode/tq/tq.h b/include/dnode/vnode/tq/tq.h index 7359df92cc..d6f7b46870 100644 --- a/include/dnode/vnode/tq/tq.h +++ b/include/dnode/vnode/tq/tq.h @@ -16,9 +16,9 @@ #ifndef _TD_TQ_H_ #define _TD_TQ_H_ +#include "mallocator.h" #include "os.h" #include "tutil.h" -#include "mallocator.h" #ifdef __cplusplus extern "C" { @@ -97,128 +97,125 @@ typedef struct TmqHeartbeatReq { typedef struct TmqHeartbeatRsp { } TmqHeartbeatRsp; -typedef struct TqTopicVhandle { +typedef struct STqTopicVhandle { int64_t topicId; // executor for filter void* filterExec; // callback for mnode // trigger when vnode list associated topic change void* (*mCallback)(void*, void*); -} TqTopicVhandle; - +} STqTopicVhandle; #define TQ_BUFFER_SIZE 8 -typedef struct TqBufferItem { +typedef struct STqBufferItem { int64_t offset; // executors are identical but not concurrent // so there must be a copy in each item void* executor; int64_t size; void* content; -} TqBufferItem; +} STqBufferItem; -typedef struct TqBufferHandle { +typedef struct STqBufferHandle { // char* topic; //c style, end with '\0' // int64_t cgId; // void* ahandle; - int64_t nextConsumeOffset; - int64_t topicId; - int32_t head; - int32_t tail; - TqBufferItem buffer[TQ_BUFFER_SIZE]; -} TqBufferHandle; + int64_t nextConsumeOffset; + int64_t floatingCursor; + int64_t topicId; + int32_t head; + int32_t tail; + STqBufferItem buffer[TQ_BUFFER_SIZE]; +} STqBufferHandle; -typedef struct TqListHandle { - TqBufferHandle bufHandle; - struct TqListHandle* next; -} TqListHandle; +typedef struct STqListHandle { + STqBufferHandle bufHandle; + struct STqListHandle* next; +} STqListHandle; -typedef struct TqGroupHandle { - int64_t cId; - int64_t cgId; - void* ahandle; - int32_t topicNum; - TqListHandle* head; -} TqGroupHandle; +typedef struct STqGroupHandle { + int64_t cId; + int64_t cgId; + void* ahandle; + int32_t topicNum; + STqListHandle* head; +} STqGroupHandle; -typedef struct TqQueryExec { - void* src; - TqBufferItem* dest; - void* executor; -} TqQueryExec; +typedef struct STqQueryExec { + void* src; + STqBufferItem* dest; + void* executor; +} STqQueryExec; -typedef struct TqQueryMsg { - TqQueryExec* exec; - struct TqQueryMsg* next; -} TqQueryMsg; +typedef struct STqQueryMsg { + STqQueryExec* exec; + struct STqQueryMsg* next; +} STqQueryMsg; -typedef struct TqLogReader { +typedef struct STqLogReader { void* logHandle; int32_t (*logRead)(void* logHandle, void** data, int64_t ver); int64_t (*logGetFirstVer)(void* logHandle); int64_t (*logGetSnapshotVer)(void* logHandle); int64_t (*logGetLastVer)(void* logHandle); -} TqLogReader; +} STqLogReader; typedef struct STqCfg { // TODO } STqCfg; -typedef struct TqMemRef { - SMemAllocatorFactory *pAlloctorFactory; - SMemAllocator *pAllocator; -} TqMemRef; +typedef struct STqMemRef { + SMemAllocatorFactory* pAlloctorFactory; + SMemAllocator* pAllocator; +} STqMemRef; -typedef struct TqSerializedHead { +typedef struct STqSerializedHead { int16_t ver; int16_t action; int32_t checksum; int64_t ssize; char content[]; -} TqSerializedHead; +} STqSerializedHead; -typedef int (*TqSerializeFun)(const void* pObj, TqSerializedHead** ppHead); -typedef const void* (*TqDeserializeFun)(const TqSerializedHead* pHead, void** ppObj); -typedef void (*TqDeleteFun)(void*); +typedef int (*FTqSerialize)(const void* pObj, STqSerializedHead** ppHead); +typedef const void* (*FTqDeserialize)(const STqSerializedHead* pHead, void** ppObj); +typedef void (*FTqDelete)(void*); #define TQ_BUCKET_MASK 0xFF #define TQ_BUCKET_SIZE 256 #define TQ_PAGE_SIZE 4096 -//key + offset + size +// key + offset + size #define TQ_IDX_SIZE 24 -//4096 / 24 +// 4096 / 24 #define TQ_MAX_IDX_ONE_PAGE 170 -//24 * 170 +// 24 * 170 #define TQ_IDX_PAGE_BODY_SIZE 4080 -//4096 - 4080 +// 4096 - 4080 #define TQ_IDX_PAGE_HEAD_SIZE 16 -#define TQ_ACTION_CONST 0 -#define TQ_ACTION_INUSE 1 +#define TQ_ACTION_CONST 0 +#define TQ_ACTION_INUSE 1 #define TQ_ACTION_INUSE_CONT 2 -#define TQ_ACTION_INTXN 3 +#define TQ_ACTION_INTXN 3 -#define TQ_SVER 0 +#define TQ_SVER 0 -//TODO: inplace mode is not implemented -#define TQ_UPDATE_INPLACE 0 -#define TQ_UPDATE_APPEND 1 +// TODO: inplace mode is not implemented +#define TQ_UPDATE_INPLACE 0 +#define TQ_UPDATE_APPEND 1 #define TQ_DUP_INTXN_REWRITE 0 -#define TQ_DUP_INTXN_REJECT 2 +#define TQ_DUP_INTXN_REJECT 2 -static inline bool TqUpdateAppend(int32_t tqConfigFlag) { - return tqConfigFlag & TQ_UPDATE_APPEND; -} +static inline bool TqUpdateAppend(int32_t tqConfigFlag) { return tqConfigFlag & TQ_UPDATE_APPEND; } -static inline bool TqDupIntxnReject(int32_t tqConfigFlag) { - return tqConfigFlag & TQ_DUP_INTXN_REJECT; -} +static inline bool TqDupIntxnReject(int32_t tqConfigFlag) { return tqConfigFlag & TQ_DUP_INTXN_REJECT; } static const int8_t TQ_CONST_DELETE = TQ_ACTION_CONST; -#define TQ_DELETE_TOKEN (void*)&TQ_CONST_DELETE + +#define TQ_DELETE_TOKEN (void*)&TQ_CONST_DELETE typedef struct TqMetaHandle { int64_t key; @@ -226,44 +223,44 @@ typedef struct TqMetaHandle { int64_t serializedSize; void* valueInUse; void* valueInTxn; -} TqMetaHandle; +} STqMetaHandle; typedef struct TqMetaList { - TqMetaHandle handle; + STqMetaHandle handle; struct TqMetaList* next; - //struct TqMetaList* inTxnPrev; - //struct TqMetaList* inTxnNext; + // struct TqMetaList* inTxnPrev; + // struct TqMetaList* inTxnNext; struct TqMetaList* unpersistPrev; struct TqMetaList* unpersistNext; -} TqMetaList; +} STqMetaList; typedef struct TqMetaStore { - TqMetaList* bucket[TQ_BUCKET_SIZE]; - //a table head - TqMetaList* unpersistHead; - //TODO:temporaral use, to be replaced by unified tfile - int fileFd; - //TODO:temporaral use, to be replaced by unified tfile - int idxFd; - char* dirPath; - int32_t tqConfigFlag; - TqSerializeFun pSerializer; - TqDeserializeFun pDeserializer; - TqDeleteFun pDeleter; -} TqMetaStore; + STqMetaList* bucket[TQ_BUCKET_SIZE]; + // a table head + STqMetaList* unpersistHead; + // TODO:temporaral use, to be replaced by unified tfile + int fileFd; + // TODO:temporaral use, to be replaced by unified tfile + int idxFd; + char* dirPath; + int32_t tqConfigFlag; + FTqSerialize pSerializer; + FTqDeserialize pDeserializer; + FTqDelete pDeleter; +} STqMetaStore; typedef struct STQ { // the collection of group handle // the handle of kvstore - char* path; - STqCfg* tqConfig; - TqLogReader* tqLogReader; - TqMemRef tqMemRef; - TqMetaStore* tqMeta; + char* path; + STqCfg* tqConfig; + STqLogReader* tqLogReader; + STqMemRef tqMemRef; + STqMetaStore* tqMeta; } STQ; // open in each vnode -STQ* tqOpen(const char* path, STqCfg* tqConfig, TqLogReader* tqLogReader, SMemAllocatorFactory *allocFac); +STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemAllocatorFactory* allocFac); void tqDestroy(STQ*); // void* will be replace by a msg type @@ -272,19 +269,19 @@ int tqCommit(STQ*); int tqConsume(STQ*, TmqConsumeReq*); -TqGroupHandle* tqGetGroupHandle(STQ*, int64_t cId); +STqGroupHandle* tqGetGroupHandle(STQ*, int64_t cId); -TqGroupHandle* tqOpenTCGroup(STQ*, int64_t topicId, int64_t cgId, int64_t cId); -int tqCloseTCGroup(STQ*, int64_t topicId, int64_t cgId, int64_t cId); -int tqMoveOffsetToNext(TqGroupHandle*); -int tqResetOffset(STQ*, int64_t topicId, int64_t cgId, int64_t offset); -int tqRegisterContext(TqGroupHandle*, void* ahandle); -int tqLaunchQuery(TqGroupHandle*); -int tqSendLaunchQuery(TqGroupHandle*); +STqGroupHandle* tqOpenTCGroup(STQ*, int64_t topicId, int64_t cgId, int64_t cId); +int tqCloseTCGroup(STQ*, int64_t topicId, int64_t cgId, int64_t cId); +int tqMoveOffsetToNext(STqGroupHandle*); +int tqResetOffset(STQ*, int64_t topicId, int64_t cgId, int64_t offset); +int tqRegisterContext(STqGroupHandle*, void* ahandle); +int tqLaunchQuery(STqGroupHandle*); +int tqSendLaunchQuery(STqGroupHandle*); -int tqSerializeGroupHandle(const TqGroupHandle* gHandle, TqSerializedHead** ppHead); +int tqSerializeGroupHandle(const STqGroupHandle* gHandle, STqSerializedHead** ppHead); -const void* tqDeserializeGroupHandle(const TqSerializedHead* pHead, TqGroupHandle** gHandle); +const void* tqDeserializeGroupHandle(const STqSerializedHead* pHead, STqGroupHandle** gHandle); #ifdef __cplusplus } diff --git a/include/dnode/vnode/tsdb/tsdb.h b/include/dnode/vnode/tsdb/tsdb.h index 26efce5d43..f8eac9768f 100644 --- a/include/dnode/vnode/tsdb/tsdb.h +++ b/include/dnode/vnode/tsdb/tsdb.h @@ -21,15 +21,14 @@ extern "C" { #endif // TYPES EXPOSED -typedef struct STsdb STsdb; -typedef struct STsdbCfg STsdbCfg; -typedef struct STsdbMemAllocator STsdbMemAllocator; +typedef struct STsdb STsdb; +typedef struct STsdbCfg STsdbCfg; // STsdb -STsdb *tsdbOpen(const char *path, const STsdbCfg *); +STsdb *tsdbOpen(const char *path, const STsdbCfg *pTsdbCfg); void tsdbClose(STsdb *); void tsdbRemove(const char *path); -int tsdbInsertData(STsdb *pTsdb, void *pData, int len); +int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg); // STsdbCfg int tsdbOptionsInit(STsdbCfg *); @@ -41,7 +40,6 @@ struct STsdbCfg { uint32_t keep0; uint32_t keep1; uint32_t keep2; - /* TODO */ }; #ifdef __cplusplus diff --git a/include/dnode/vnode/vnode.h b/include/dnode/vnode/vnode.h index 007ce83812..8458ad9da3 100644 --- a/include/dnode/vnode/vnode.h +++ b/include/dnode/vnode/vnode.h @@ -68,9 +68,11 @@ typedef struct SVnodeCfg { /** * @brief Initialize the vnode module * + * @param nthreads number of commit threads. 0 for no threads and + * a schedule queue should be given (TODO) * @return int 0 for success and -1 for failure */ -int vnodeInit(); +int vnodeInit(uint16_t nthreads); /** * @brief clear a vnode diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h index 050b9c904f..1f2452291b 100644 --- a/include/libs/catalog/catalog.h +++ b/include/libs/catalog/catalog.h @@ -27,83 +27,83 @@ extern "C" { #include "transport.h" #include "common.h" #include "taosmsg.h" +#include "query.h" struct SCatalog; -typedef struct SMetaReq { - char clusterId[TSDB_CLUSTER_ID_LEN]; +typedef struct SCatalogReq { + char dbName[TSDB_DB_NAME_LEN]; SArray *pTableName; // table full name SArray *pUdf; // udf name - bool qNodeEpset; // valid qnode -} SMetaReq; + bool qNodeRequired; // valid qnode +} SCatalogReq; typedef struct SMetaData { - SArray *pTableMeta; // tableMeta - SArray *pVgroupInfo; // vgroupInfo list + SArray *pTableMeta; // STableMeta array + SArray *pVgroupInfo; // SVgroupInfo list SArray *pUdfList; // udf info list SEpSet *pEpSet; // qnode epset list } SMetaData; -typedef struct STableComInfo { - uint8_t numOfTags; // the number of tags in schema - uint8_t precision; // the number of precision - int16_t numOfColumns; // the number of columns - int32_t rowSize; // row size of the schema -} STableComInfo; +typedef struct SCatalogCfg { + bool enableVgroupCache; + uint32_t maxTblCacheNum; + uint32_t maxDBCacheNum; +} SCatalogCfg; -/* - * ASSERT(sizeof(SCTableMeta) == 24) - * ASSERT(tableType == TSDB_CHILD_TABLE) - * The cached child table meta info. For each child table, 24 bytes are required to keep the essential table info. - */ -typedef struct SCTableMeta { - int32_t vgId:24; - int8_t tableType; - uint64_t uid; - uint64_t suid; -} SCTableMeta; - -/* - * Note that the first 24 bytes of STableMeta are identical to SCTableMeta, it is safe to cast a STableMeta to be a SCTableMeta. - */ -typedef struct STableMeta { - int32_t vgId:24; - int8_t tableType; - uint64_t uid; - uint64_t suid; - // if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta info - int16_t sversion; - int16_t tversion; - STableComInfo tableInfo; - SSchema schema[]; -} STableMeta; +int32_t catalogInit(SCatalogCfg *cfg); /** * Catalog service object, which is utilized to hold tableMeta (meta/vgroupInfo/udfInfo) at the client-side. * There is ONLY one SCatalog object for one process space, and this function returns a singleton. - * @param pMgmtEps + * @param clusterId * @return */ -struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps); +int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle); + +int32_t catalogGetDBVgroupVersion(struct SCatalog* pCatalog, const char* dbName, int32_t* version); +int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, int32_t forceUpdate, SDBVgroupInfo* dbInfo); +int32_t catalogUpdateDBVgroupCache(struct SCatalog* pCatalog, const char* dbName, SDBVgroupInfo* dbInfo); + + +int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta); +int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName); +int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta); + + +/** + * get table's vgroup list. + * @param clusterId + * @pVgroupList - array of SVgroupInfo + * @return + */ +int32_t catalogGetTableVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, SArray* pVgroupList); + /** * Get the required meta data from mnode. * Note that this is a synchronized API and is also thread-safety. * @param pCatalog + * @param pMgmtEps * @param pMetaReq * @param pMetaData * @return */ -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData); +int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp); + + +int32_t catalogGetQnodeList(struct SCatalog* pCatalog, const SEpSet* pMgmtEps, SEpSet* pQnodeEpSet); + + /** - * Destroy catalog service handle + * Destroy catalog and relase all resources * @param pCatalog */ -void destroyCatalog(struct SCatalog* pCatalog); +void catalogDestroy(void); #ifdef __cplusplus } #endif -#endif /*_TD_CATALOG_H_*/ \ No newline at end of file +#endif /*_TD_CATALOG_H_*/ diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 32d0d03d80..49adaecfdd 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -132,13 +132,15 @@ struct SInsertStmtInfo; bool qIsInsertSql(const char* pStr, size_t length); typedef struct SParseContext { + const char* pAcctId; + const char* pDbname; + void *pRpc; + const char* pClusterId; + const SEpSet* pEpSet; + int64_t id; // query id, generated by uuid generator + int8_t schemaAttached; // denote if submit block is built with table schema or not const char* pSql; // sql string size_t sqlLen; // length of the sql string - int64_t id; // operator id, generated by uuid generator - const char* pDbname; - const SEpSet* pEpSet; - int8_t schemaAttached; // denote if submit block is built with table schema or not - char* pMsg; // extended error message if exists to help avoid the problem in sql statement. int32_t msgLen; // max length of the msg } SParseContext; diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index 1ff3f02da5..a7d418d45e 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -20,124 +20,115 @@ extern "C" { #endif +#include "taosmsg.h" + #define QUERY_TYPE_MERGE 1 #define QUERY_TYPE_PARTIAL 2 +#define QUERY_TYPE_SCAN 3 enum OPERATOR_TYPE_E { - OP_TableScan = 1, - OP_DataBlocksOptScan = 2, - OP_TableSeqScan = 3, - OP_TagScan = 4, - OP_TableBlockInfoScan= 5, - OP_Aggregate = 6, - OP_Project = 7, - OP_Groupby = 8, - OP_Limit = 9, - OP_SLimit = 10, - OP_TimeWindow = 11, - OP_SessionWindow = 12, - OP_StateWindow = 22, - OP_Fill = 13, - OP_MultiTableAggregate = 14, - OP_MultiTableTimeInterval = 15, -// OP_DummyInput = 16, //TODO remove it after fully refactor. -// OP_MultiwayMergeSort = 17, // multi-way data merge into one input stream. -// OP_GlobalAggregate = 18, // global merge for the multi-way data sources. - OP_Filter = 19, - OP_Distinct = 20, - OP_Join = 21, - OP_AllTimeWindow = 23, - OP_AllMultiTableTimeInterval = 24, - OP_Order = 25, - OP_Exchange = 26, + OP_Unknown, +#define INCLUDE_AS_ENUM +#include "plannerOp.h" +#undef INCLUDE_AS_ENUM + OP_TotalNum }; struct SEpSet; -struct SQueryPlanNode; -struct SQueryDistPlanNode; struct SQueryStmtInfo; -typedef struct SSubquery { - int64_t queryId; // the subquery id created by qnode - int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL - int32_t level; // the execution level of current subquery, starting from 0. - SArray *pUpstream; // the upstream,from which to fetch the result - struct SQueryDistPlanNode *pNode; // physical plan of current subquery -} SSubquery; +typedef SSchema SSlotSchema; -typedef struct SQueryJob { - SArray **pSubqueries; - int32_t numOfLevels; - int32_t currentLevel; -} SQueryJob; +typedef struct SDataBlockSchema { + SSlotSchema *pSchema; + int32_t numOfCols; // number of columns +} SDataBlockSchema; + +typedef struct SQueryNodeBasicInfo { + int32_t type; // operator type + const char *name; // operator name +} SQueryNodeBasicInfo; + +typedef struct SPhyNode { + SQueryNodeBasicInfo info; + SArray *pTargets; // target list to be computed or scanned at this node + SArray *pConditions; // implicitly-ANDed qual conditions + SDataBlockSchema targetSchema; + // children plan to generated result for current node to process + // in case of join, multiple plan nodes exist. + SArray *pChildren; + struct SPhyNode *pParent; +} SPhyNode; + +typedef struct SScanPhyNode { + SPhyNode node; + uint64_t uid; // unique id of the table + int8_t tableType; +} SScanPhyNode; + +typedef SScanPhyNode SSystemTableScanPhyNode; +typedef SScanPhyNode STagScanPhyNode; + +typedef struct STableScanPhyNode { + SScanPhyNode scan; + uint8_t scanFlag; // denotes reversed scan of data or not + STimeWindow window; + SArray *pTagsConditions; // implicitly-ANDed tag qual conditions +} STableScanPhyNode; + +typedef STableScanPhyNode STableSeqScanPhyNode; + +typedef struct SProjectPhyNode { + SPhyNode node; +} SProjectPhyNode; + +typedef struct SExchangePhyNode { + SPhyNode node; + uint64_t srcTemplateId; // template id of datasource suplans + SArray *pSourceEpSet; // SEpSet, scheduler fill by calling qSetSuplanExecutionNode +} SExchangePhyNode; + +typedef struct SSubplanId { + uint64_t queryId; + uint64_t templateId; + uint64_t subplanId; +} SSubplanId; + +typedef struct SSubplan { + SSubplanId id; // unique id of the subplan + int32_t type; // QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN + int32_t level; // the execution level of current subplan, starting from 0. + SEpSet execEpSet; // for the scan sub plan, the optional execution node + SArray *pChildern; // the datasource subplan,from which to fetch the result + SArray *pParents; // the data destination subplan, get data from current subplan + SPhyNode *pNode; // physical plan of current subplan +} SSubplan; + +typedef struct SQueryDag { + SArray *pSubplans; // Element is SArray*, and nested element is SSubplan. The execution level of subplan, starting from 0. +} SQueryDag; + +/** + * Create the physical plan for the query, according to the AST. + */ +int32_t qCreateQueryDag(const struct SQueryStmtInfo* pQueryInfo, struct SEpSet* pQnode, struct SQueryDag** pDag); + +int32_t qSetSuplanExecutionNode(SArray* subplans, SArray* nodes); + +int32_t qExplainQuery(const struct SQueryStmtInfo* pQueryInfo, struct SEpSet* pQnode, char** str); /** - * Optimize the query execution plan, currently not implement yet. - * @param pQueryNode - * @return + * Convert to subplan to string for the scheduler to send to the executor */ -int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode); - -/** - * Create the query plan according to the bound AST, which is in the form of pQueryInfo - * @param pQueryInfo - * @param pQueryNode - * @return - */ -int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode); - -/** - * Convert the query plan to string, in order to display it in the shell. - * @param pQueryNode - * @return - */ -int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str); - -/** - * Restore the SQL statement according to the logic query plan. - * @param pQueryNode - * @param sql - * @return - */ -int32_t qQueryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql); - -/** - * Create the physical plan for the query, according to the logic plan. - * @param pQueryNode - * @param pPhyNode - * @return - */ -int32_t qCreatePhysicalPlan(struct SQueryPlanNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode); - -/** - * Convert to physical plan to string to enable to print it out in the shell. - * @param pPhyNode - * @param str - * @return - */ -int32_t qPhyPlanToString(struct SQueryDistPlanNode *pPhyNode, char** str); - -/** - * Destroy the query plan object. - * @return - */ -void* qDestroyQueryPlan(struct SQueryPlanNode* pQueryNode); +int32_t qSubPlanToString(struct SSubplan *pPhyNode, char** str); /** * Destroy the physical plan. * @param pQueryPhyNode * @return */ -void* qDestroyQueryPhyPlan(struct SQueryDistPlanNode* pQueryPhyNode); - -/** - * Create the query job from the physical execution plan - * @param pPhyNode - * @param pJob - * @return - */ -int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQueryJob** pJob); +void qDestroyQueryDag(struct SQueryDag* pDag); #ifdef __cplusplus } diff --git a/include/libs/planner/plannerOp.h b/include/libs/planner/plannerOp.h new file mode 100644 index 0000000000..9f51969dc1 --- /dev/null +++ b/include/libs/planner/plannerOp.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#if defined(INCLUDE_AS_ENUM) // enum define mode + #undef OP_ENUM_MACRO + #define OP_ENUM_MACRO(op) OP_##op, +#elif defined(INCLUDE_AS_NAME) // comment define mode + #undef OP_ENUM_MACRO + #define OP_ENUM_MACRO(op) #op, +#else + #error To use this include file, first define either INCLUDE_AS_ENUM or INCLUDE_AS_NAME +#endif + +OP_ENUM_MACRO(TableScan) +OP_ENUM_MACRO(DataBlocksOptScan) +OP_ENUM_MACRO(TableSeqScan) +OP_ENUM_MACRO(TagScan) +OP_ENUM_MACRO(SystemTableScan) +OP_ENUM_MACRO(Aggregate) +OP_ENUM_MACRO(Project) +OP_ENUM_MACRO(Groupby) +OP_ENUM_MACRO(Limit) +OP_ENUM_MACRO(SLimit) +OP_ENUM_MACRO(TimeWindow) +OP_ENUM_MACRO(SessionWindow) +OP_ENUM_MACRO(StateWindow) +OP_ENUM_MACRO(Fill) +OP_ENUM_MACRO(MultiTableAggregate) +OP_ENUM_MACRO(MultiTableTimeInterval) +OP_ENUM_MACRO(Filter) +OP_ENUM_MACRO(Distinct) +OP_ENUM_MACRO(Join) +OP_ENUM_MACRO(AllTimeWindow) +OP_ENUM_MACRO(AllMultiTableTimeInterval) +OP_ENUM_MACRO(Order) +OP_ENUM_MACRO(Exchange) diff --git a/include/libs/query/query.h b/include/libs/query/query.h new file mode 100644 index 0000000000..8720fd085c --- /dev/null +++ b/include/libs/query/query.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_QUERY_H_ +#define _TD_QUERY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tarray.h" +#include "thash.h" + +typedef SVgroupListRspMsg SVgroupListInfo; + +typedef struct STableComInfo { + uint8_t numOfTags; // the number of tags in schema + uint8_t precision; // the number of precision + int16_t numOfColumns; // the number of columns + int32_t rowSize; // row size of the schema +} STableComInfo; + +/* + * ASSERT(sizeof(SCTableMeta) == 24) + * ASSERT(tableType == TSDB_CHILD_TABLE) + * The cached child table meta info. For each child table, 24 bytes are required to keep the essential table info. + */ +typedef struct SCTableMeta { + int32_t vgId:24; + int8_t tableType; + uint64_t uid; + uint64_t suid; +} SCTableMeta; + +/* + * Note that the first 24 bytes of STableMeta are identical to SCTableMeta, it is safe to cast a STableMeta to be a SCTableMeta. + */ +typedef struct STableMeta { + //BEGIN: KEEP THIS PART SAME WITH SCTableMeta + int32_t vgId:24; + int8_t tableType; + uint64_t uid; + uint64_t suid; + //END: KEEP THIS PART SAME WITH SCTableMeta + + // if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta info + int16_t sversion; + int16_t tversion; + STableComInfo tableInfo; + SSchema schema[]; +} STableMeta; + + +typedef struct SDBVgroupInfo { + int32_t vgVersion; + int8_t hashMethod; + SHashObj *vgInfo; //key:vgId, value:SVgroupInfo +} SDBVgroupInfo; + +typedef struct SUseDbOutput { + char db[TSDB_FULL_DB_NAME_LEN]; + SDBVgroupInfo dbVgroup; +} SUseDbOutput; + +typedef struct STableMetaOutput { + int32_t metaNum; + char ctbFname[TSDB_TABLE_FNAME_LEN]; + char tbFname[TSDB_TABLE_FNAME_LEN]; + SCTableMeta ctbMeta; + STableMeta *tbMeta; +} STableMetaOutput; + +extern int32_t (*queryBuildMsg[TSDB_MSG_TYPE_MAX])(void* input, char **msg, int32_t msgSize, int32_t *msgLen); +extern int32_t (*queryProcessMsgRsp[TSDB_MSG_TYPE_MAX])(void* output, char *msg, int32_t msgSize); + + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_QUERY_H_*/ diff --git a/include/libs/scheduler/scheduler.h b/include/libs/scheduler/scheduler.h index d9653046cf..6b3c9ed021 100644 --- a/include/libs/scheduler/scheduler.h +++ b/include/libs/scheduler/scheduler.h @@ -20,7 +20,42 @@ extern "C" { #endif -struct SQueryJob; +typedef struct SQueryProfileSummary { + int64_t startTs; // Object created and added into the message queue + int64_t endTs; // the timestamp when the task is completed + int64_t cputime; // total cpu cost, not execute elapsed time + + int64_t loadRemoteDataDuration; // remote io time + int64_t loadNativeDataDuration; // native disk io time + + uint64_t loadNativeData; // blocks + SMA + header files + uint64_t loadRemoteData; // remote data acquired by exchange operator. + + uint64_t waitDuration; // the time to waiting to be scheduled in queue does matter, so we need to record it + int64_t addQTs; // the time to be added into the message queue, used to calculate the waiting duration in queue. + + uint64_t totalRows; + uint64_t loadRows; + uint32_t totalBlocks; + uint32_t loadBlocks; + uint32_t loadBlockAgg; + uint32_t skipBlocks; + uint64_t resultSize; // generated result size in Kb. +} SQueryProfileSummary; + +typedef struct SQueryTask { + uint64_t queryId; // query id + uint64_t taskId; // task id + char *pSubplan; // operator tree + uint64_t status; // task status + SQueryProfileSummary summary; // task execution summary + void *pOutputHandle; // result buffer handle, to temporarily keep the output result for next stage +} SQueryTask; + +typedef struct SQueryJob { + SArray **pSubtasks; + // todo +} SQueryJob; /** * Process the query job, generated according to the query physical plan. diff --git a/include/libs/wal/wal.h b/include/libs/wal/wal.h index 744275e6ff..89f24cf3a4 100644 --- a/include/libs/wal/wal.h +++ b/include/libs/wal/wal.h @@ -16,53 +16,75 @@ #define _TD_WAL_H_ #include "os.h" +#include "tarray.h" #include "tdef.h" #include "tlog.h" -#include "tarray.h" #ifdef __cplusplus extern "C" { #endif extern int32_t wDebugFlag; -#define wFatal(...) { if (wDebugFlag & DEBUG_FATAL) { taosPrintLog("WAL FATAL ", 255, __VA_ARGS__); }} -#define wError(...) { if (wDebugFlag & DEBUG_ERROR) { taosPrintLog("WAL ERROR ", 255, __VA_ARGS__); }} -#define wWarn(...) { if (wDebugFlag & DEBUG_WARN) { taosPrintLog("WAL WARN ", 255, __VA_ARGS__); }} -#define wInfo(...) { if (wDebugFlag & DEBUG_INFO) { taosPrintLog("WAL ", 255, __VA_ARGS__); }} -#define wDebug(...) { if (wDebugFlag & DEBUG_DEBUG) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }} -#define wTrace(...) { if (wDebugFlag & DEBUG_TRACE) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }} +#define wFatal(...) \ + { \ + if (wDebugFlag & DEBUG_FATAL) { \ + taosPrintLog("WAL FATAL ", 255, __VA_ARGS__); \ + } \ + } +#define wError(...) \ + { \ + if (wDebugFlag & DEBUG_ERROR) { \ + taosPrintLog("WAL ERROR ", 255, __VA_ARGS__); \ + } \ + } +#define wWarn(...) \ + { \ + if (wDebugFlag & DEBUG_WARN) { \ + taosPrintLog("WAL WARN ", 255, __VA_ARGS__); \ + } \ + } +#define wInfo(...) \ + { \ + if (wDebugFlag & DEBUG_INFO) { \ + taosPrintLog("WAL ", 255, __VA_ARGS__); \ + } \ + } +#define wDebug(...) \ + { \ + if (wDebugFlag & DEBUG_DEBUG) { \ + taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); \ + } \ + } +#define wTrace(...) \ + { \ + if (wDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); \ + } \ + } -#define WAL_PREFIX "wal" -#define WAL_PREFIX_LEN 3 +#define WAL_HEAD_VER 0 #define WAL_NOSUFFIX_LEN 20 -#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN+1) -#define WAL_LOG_SUFFIX "log" +#define WAL_SUFFIX_AT (WAL_NOSUFFIX_LEN + 1) +#define WAL_LOG_SUFFIX "log" #define WAL_INDEX_SUFFIX "idx" -#define WAL_REFRESH_MS 1000 -#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + 16) -#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12) -#define WAL_FILE_LEN (WAL_PATH_LEN + 32) +#define WAL_REFRESH_MS 1000 +#define WAL_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead)) +#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12) +#define WAL_FILE_LEN (WAL_PATH_LEN + 32) -#define WAL_IDX_ENTRY_SIZE (sizeof(int64_t)*2) -#define WAL_CUR_POS_WRITABLE 1 -#define WAL_CUR_FILE_WRITABLE 2 -#define WAL_CUR_FAILED 4 +#define WAL_CUR_FAILED 1 -#pragma pack(push,1) -typedef enum { - TAOS_WAL_NOLOG = 0, - TAOS_WAL_WRITE = 1, - TAOS_WAL_FSYNC = 2 -} EWalType; +#pragma pack(push, 1) +typedef enum { TAOS_WAL_NOLOG = 0, TAOS_WAL_WRITE = 1, TAOS_WAL_FSYNC = 2 } EWalType; typedef struct SWalReadHead { - int8_t sver; - uint8_t msgType; - int8_t reserved[2]; - int32_t len; - //int64_t ingestTs; //not implemented - int64_t version; - char body[]; + int8_t headVer; + uint8_t msgType; + int8_t reserved[2]; + int32_t len; + int64_t ingestTs; // not implemented + int64_t version; + char body[]; } SWalReadHead; typedef struct { @@ -72,20 +94,12 @@ typedef struct { int32_t rollPeriod; // secs int64_t retentionSize; int64_t segSize; - EWalType level; // wal level + EWalType level; // wal level } SWalCfg; typedef struct { - //union { - //uint32_t info; - //struct { - //uint32_t sver:3; - //uint32_t msgtype: 5; - //uint32_t reserved : 24; - //}; - //}; - uint32_t cksumHead; - uint32_t cksumBody; + uint32_t cksumHead; + uint32_t cksumBody; SWalReadHead head; } SWalHead; @@ -100,38 +114,38 @@ typedef struct SWalVer { typedef struct SWal { // cfg SWalCfg cfg; + int32_t fsyncSeq; + // meta SWalVer vers; - //file set - int32_t writeCur; int64_t writeLogTfd; int64_t writeIdxTfd; - SArray* fileInfoSet; - //ctl - int32_t curStatus; - int32_t fsyncSeq; + int32_t writeCur; + SArray *fileInfoSet; + // status int64_t totSize; - int64_t refId; int64_t lastRollSeq; + // ctl + int64_t refId; pthread_mutex_t mutex; - //path + // path char path[WAL_PATH_LEN]; - //reusable write head + // reusable write head SWalHead writeHead; } SWal; // WAL HANDLE typedef struct SWalReadHandle { - SWal* pWal; - int64_t readLogTfd; - int64_t readIdxTfd; - int64_t curFileFirstVer; - int64_t curVersion; - int64_t capacity; - int64_t status; //if cursor valid - SWalHead* pHead; + SWal *pWal; + int64_t readLogTfd; + int64_t readIdxTfd; + int64_t curFileFirstVer; + int64_t curVersion; + int64_t capacity; + int64_t status; // if cursor valid + SWalHead *pHead; } SWalReadHandle; #pragma pack(pop) -typedef int32_t (*FWalWrite)(void *ahandle, void *pHead); +// typedef int32_t (*FWalWrite)(void *ahandle, void *pHead); // module initialization int32_t walInit(); @@ -151,17 +165,17 @@ int32_t walCommit(SWal *, int64_t ver); // truncate after int32_t walRollback(SWal *, int64_t ver); // notify that previous logs can be pruned safely -int32_t walBeginTakeSnapshot(SWal *, int64_t ver); -int32_t walEndTakeSnapshot(SWal *); -//int32_t walDataCorrupted(SWal*); +int32_t walBeginSnapshot(SWal *, int64_t ver); +int32_t walEndSnapshot(SWal *); +// int32_t walDataCorrupted(SWal*); // read -SWalReadHandle* walOpenReadHandle(SWal *); -void walCloseReadHandle(SWalReadHandle *); -int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver); +SWalReadHandle *walOpenReadHandle(SWal *); +void walCloseReadHandle(SWalReadHandle *); +int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver); int32_t walRead(SWal *, SWalHead **, int64_t ver); -int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum); +// int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum); // lifecycle check int64_t walGetFirstVer(SWal *); diff --git a/include/os/osMemory.h b/include/os/osMemory.h index 10c90cd9aa..5f1d5a9a8a 100644 --- a/include/os/osMemory.h +++ b/include/os/osMemory.h @@ -23,8 +23,8 @@ extern "C" { #define tfree(x) \ do { \ if (x) { \ - free((void *)x); \ - x = 0; \ + free((void *)(x)); \ + (x) = 0; \ } \ } while (0) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 64a1fa84ad..4f1ef7da7b 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -117,72 +117,93 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_INVALID_JSON TAOS_DEF_ERROR_CODE(0, 0x0221) //"Invalid JSON format") #define TSDB_CODE_TSC_INVALID_JSON_TYPE TAOS_DEF_ERROR_CODE(0, 0x0222) //"Invalid JSON data type") #define TSDB_CODE_TSC_VALUE_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x0223) //"Value out of range") +#define TSDB_CODE_TSC_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0X0224) //"Invalid tsc input") -// mnode -#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) -#define TSDB_CODE_MND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0301) -#define TSDB_CODE_MND_ACTION_NEED_REPROCESSED TAOS_DEF_ERROR_CODE(0, 0x0302) -#define TSDB_CODE_MND_NO_RIGHTS TAOS_DEF_ERROR_CODE(0, 0x0303) -#define TSDB_CODE_MND_INVALID_OPTIONS TAOS_DEF_ERROR_CODE(0, 0x0304) -#define TSDB_CODE_MND_INVALID_CONNECTION TAOS_DEF_ERROR_CODE(0, 0x0305) -#define TSDB_CODE_MND_INVALID_MSG_VERSION TAOS_DEF_ERROR_CODE(0, 0x0306) -#define TSDB_CODE_MND_INVALID_MSG_LEN TAOS_DEF_ERROR_CODE(0, 0x0307) -#define TSDB_CODE_MND_INVALID_MSG_TYPE TAOS_DEF_ERROR_CODE(0, 0x0308) -#define TSDB_CODE_MND_TOO_MANY_SHELL_CONNS TAOS_DEF_ERROR_CODE(0, 0x0309) -#define TSDB_CODE_MND_INVALID_SHOWOBJ TAOS_DEF_ERROR_CODE(0, 0x030B) -#define TSDB_CODE_MND_INVALID_QUERY_ID TAOS_DEF_ERROR_CODE(0, 0x030C) -#define TSDB_CODE_MND_INVALID_STREAM_ID TAOS_DEF_ERROR_CODE(0, 0x030D) -#define TSDB_CODE_MND_INVALID_CONN_ID TAOS_DEF_ERROR_CODE(0, 0x030E) -#define TSDB_CODE_MND_MNODE_IS_RUNNING TAOS_DEF_ERROR_CODE(0, 0x0310) -#define TSDB_CODE_MND_FAILED_TO_CONFIG_SYNC TAOS_DEF_ERROR_CODE(0, 0x0311) -#define TSDB_CODE_MND_FAILED_TO_START_SYNC TAOS_DEF_ERROR_CODE(0, 0x0312) -#define TSDB_CODE_MND_FAILED_TO_CREATE_DIR TAOS_DEF_ERROR_CODE(0, 0x0313) -#define TSDB_CODE_MND_FAILED_TO_INIT_STEP TAOS_DEF_ERROR_CODE(0, 0x0314) +// mnode-common +#define TSDB_CODE_MND_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0300) +#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0301) +#define TSDB_CODE_MND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0302) +#define TSDB_CODE_MND_ACTION_NEED_REPROCESSED TAOS_DEF_ERROR_CODE(0, 0x0303) +#define TSDB_CODE_MND_NO_RIGHTS TAOS_DEF_ERROR_CODE(0, 0x0304) +#define TSDB_CODE_MND_INVALID_OPTIONS TAOS_DEF_ERROR_CODE(0, 0x0305) +#define TSDB_CODE_MND_INVALID_CONNECTION TAOS_DEF_ERROR_CODE(0, 0x0306) +#define TSDB_CODE_MND_INVALID_MSG_VERSION TAOS_DEF_ERROR_CODE(0, 0x0307) +#define TSDB_CODE_MND_INVALID_MSG_LEN TAOS_DEF_ERROR_CODE(0, 0x0308) +#define TSDB_CODE_MND_INVALID_MSG_TYPE TAOS_DEF_ERROR_CODE(0, 0x0309) +#define TSDB_CODE_MND_TOO_MANY_SHELL_CONNS TAOS_DEF_ERROR_CODE(0, 0x030A) -#define TSDB_CODE_SDB_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0320) -#define TSDB_CODE_SDB_OBJ_ALREADY_THERE TAOS_DEF_ERROR_CODE(0, 0x0321) -#define TSDB_CODE_SDB_OBJ_NOT_THERE TAOS_DEF_ERROR_CODE(0, 0x0322) -#define TSDB_CODE_SDB_OBJ_CREATING TAOS_DEF_ERROR_CODE(0, 0x0323) -#define TSDB_CODE_SDB_OBJ_DROPPING TAOS_DEF_ERROR_CODE(0, 0x0324) -#define TSDB_CODE_SDB_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0325) -#define TSDB_CODE_SDB_INVALID_KEY_TYPE TAOS_DEF_ERROR_CODE(0, 0x0326) -#define TSDB_CODE_SDB_INVALID_ACTION_TYPE TAOS_DEF_ERROR_CODE(0, 0x0327) -#define TSDB_CODE_SDB_INVALID_STATUS_TYPE TAOS_DEF_ERROR_CODE(0, 0x0328) -#define TSDB_CODE_SDB_INVALID_DATA_VER TAOS_DEF_ERROR_CODE(0, 0x0329) -#define TSDB_CODE_SDB_INVALID_DATA_LEN TAOS_DEF_ERROR_CODE(0, 0x032A) -#define TSDB_CODE_SDB_INVALID_DATA_CONTENT TAOS_DEF_ERROR_CODE(0, 0x032B) +// mnode-show +#define TSDB_CODE_MND_INVALID_SHOWOBJ TAOS_DEF_ERROR_CODE(0, 0x0310) + +// mnode-profile +#define TSDB_CODE_MND_INVALID_QUERY_ID TAOS_DEF_ERROR_CODE(0, 0x0320) +#define TSDB_CODE_MND_INVALID_STREAM_ID TAOS_DEF_ERROR_CODE(0, 0x0321) +#define TSDB_CODE_MND_INVALID_CONN_ID TAOS_DEF_ERROR_CODE(0, 0x0322) +#define TSDB_CODE_MND_MNODE_IS_RUNNING TAOS_DEF_ERROR_CODE(0, 0x0323) +#define TSDB_CODE_MND_FAILED_TO_CONFIG_SYNC TAOS_DEF_ERROR_CODE(0, 0x0324) +#define TSDB_CODE_MND_FAILED_TO_START_SYNC TAOS_DEF_ERROR_CODE(0, 0x0325) +#define TSDB_CODE_MND_FAILED_TO_CREATE_DIR TAOS_DEF_ERROR_CODE(0, 0x0326) +#define TSDB_CODE_MND_FAILED_TO_INIT_STEP TAOS_DEF_ERROR_CODE(0, 0x0327) + +// mnode-sdb +#define TSDB_CODE_SDB_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x0330) +#define TSDB_CODE_SDB_OBJ_ALREADY_THERE TAOS_DEF_ERROR_CODE(0, 0x0331) +#define TSDB_CODE_SDB_OBJ_NOT_THERE TAOS_DEF_ERROR_CODE(0, 0x0332) +#define TSDB_CODE_SDB_OBJ_CREATING TAOS_DEF_ERROR_CODE(0, 0x0333) +#define TSDB_CODE_SDB_OBJ_DROPPING TAOS_DEF_ERROR_CODE(0, 0x0334) +#define TSDB_CODE_SDB_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x0335) +#define TSDB_CODE_SDB_INVALID_KEY_TYPE TAOS_DEF_ERROR_CODE(0, 0x0336) +#define TSDB_CODE_SDB_INVALID_ACTION_TYPE TAOS_DEF_ERROR_CODE(0, 0x0337) +#define TSDB_CODE_SDB_INVALID_STATUS_TYPE TAOS_DEF_ERROR_CODE(0, 0x0338) +#define TSDB_CODE_SDB_INVALID_DATA_VER TAOS_DEF_ERROR_CODE(0, 0x0339) +#define TSDB_CODE_SDB_INVALID_DATA_LEN TAOS_DEF_ERROR_CODE(0, 0x033A) +#define TSDB_CODE_SDB_INVALID_DATA_CONTENT TAOS_DEF_ERROR_CODE(0, 0x033B) // mnode-dnode -#define TSDB_CODE_MND_DNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0330) -#define TSDB_CODE_MND_DNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0331) -#define TSDB_CODE_MND_NO_ENOUGH_DNODES TAOS_DEF_ERROR_CODE(0, 0x0332) -#define TSDB_CODE_MND_INVALID_CLUSTER_CFG TAOS_DEF_ERROR_CODE(0, 0x0333) -#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x0334) -#define TSDB_CODE_MND_INVALID_DNODE_CFG TAOS_DEF_ERROR_CODE(0, 0x0335) -#define TSDB_CODE_MND_INVALID_DNODE_EP TAOS_DEF_ERROR_CODE(0, 0x0336) -#define TSDB_CODE_MND_INVALID_DNODE_ID TAOS_DEF_ERROR_CODE(0, 0x0337) +#define TSDB_CODE_MND_DNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0340) +#define TSDB_CODE_MND_DNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0341) +#define TSDB_CODE_MND_TOO_MANY_DNODES TAOS_DEF_ERROR_CODE(0, 0x0342) +#define TSDB_CODE_MND_NO_ENOUGH_DNODES TAOS_DEF_ERROR_CODE(0, 0x0343) +#define TSDB_CODE_MND_INVALID_CLUSTER_CFG TAOS_DEF_ERROR_CODE(0, 0x0344) +#define TSDB_CODE_MND_INVALID_CLUSTER_ID TAOS_DEF_ERROR_CODE(0, 0x0345) +#define TSDB_CODE_MND_INVALID_DNODE_CFG TAOS_DEF_ERROR_CODE(0, 0x0346) +#define TSDB_CODE_MND_INVALID_DNODE_EP TAOS_DEF_ERROR_CODE(0, 0x0347) +#define TSDB_CODE_MND_INVALID_DNODE_ID TAOS_DEF_ERROR_CODE(0, 0x0348) -// mnode-vgroup -#define TSDB_CODE_MND_VGROUP_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0332) //"VGroup does not exist") -#define TSDB_CODE_MND_VGROUP_NOT_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0338) //"Vgroup not in dnode") -#define TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0339) //"Vgroup already in dnode") -#define TSDB_CODE_MND_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x033C) //"Cluster not ready") +// mnode-mnode +#define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0350) +#define TSDB_CODE_MND_MNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0351) +#define TSDB_CODE_MND_TOO_MANY_MNODES TAOS_DEF_ERROR_CODE(0, 0x0352) // mnode-acct -#define TSDB_CODE_MND_ACCT_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0340) //"Account already exists") -#define TSDB_CODE_MND_ACCT_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0341) //"Invalid account") -#define TSDB_CODE_MND_INVALID_ACCT_OPTION TAOS_DEF_ERROR_CODE(0, 0x0342) //"Invalid account options") -#define TSDB_CODE_MND_ACCT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0343) //"Account authorization has expired") +#define TSDB_CODE_MND_ACCT_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0360) +#define TSDB_CODE_MND_ACCT_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0361) +#define TSDB_CODE_MND_TOO_MANY_ACCTS TAOS_DEF_ERROR_CODE(0, 0x0362) +#define TSDB_CODE_MND_INVALID_ACCT_OPTION TAOS_DEF_ERROR_CODE(0, 0x0363) +#define TSDB_CODE_MND_ACCT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x0364) -#define TSDB_CODE_MND_USER_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0350) //"User already exists") -#define TSDB_CODE_MND_USER_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0351) //"Invalid user") -#define TSDB_CODE_MND_INVALID_USER_FORMAT TAOS_DEF_ERROR_CODE(0, 0x0352) //"Invalid user format") -#define TSDB_CODE_MND_INVALID_PASS_FORMAT TAOS_DEF_ERROR_CODE(0, 0x0353) //"Invalid password format") -#define TSDB_CODE_MND_NO_USER_FROM_CONN TAOS_DEF_ERROR_CODE(0, 0x0354) //"Can not get user from conn") -#define TSDB_CODE_MND_TOO_MANY_USERS TAOS_DEF_ERROR_CODE(0, 0x0355) //"Too many users") +// mnode-user +#define TSDB_CODE_MND_USER_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0370) +#define TSDB_CODE_MND_USER_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0371) +#define TSDB_CODE_MND_TOO_MANY_USERS TAOS_DEF_ERROR_CODE(0, 0x0372) +#define TSDB_CODE_MND_INVALID_USER_FORMAT TAOS_DEF_ERROR_CODE(0, 0x0373) +#define TSDB_CODE_MND_INVALID_PASS_FORMAT TAOS_DEF_ERROR_CODE(0, 0x0374) +#define TSDB_CODE_MND_NO_USER_FROM_CONN TAOS_DEF_ERROR_CODE(0, 0x0375) -#define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0348) //"Mnode already exists") -#define TSDB_CODE_MND_MNODE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0349) //"Mnode not there") +// mnode-db +#define TSDB_CODE_MND_DB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0380) +#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0381) +#define TSDB_CODE_MND_TOO_MANY_DATABASES TAOS_DEF_ERROR_CODE(0, 0x0382) +#define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0383) +#define TSDB_CODE_MND_INVALID_DB TAOS_DEF_ERROR_CODE(0, 0x0384) +#define TSDB_CODE_MND_INVALID_DB_OPTION TAOS_DEF_ERROR_CODE(0, 0x0385) +#define TSDB_CODE_MND_INVALID_DB_ACCT TAOS_DEF_ERROR_CODE(0, 0x0386) +#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x0387) + +// mnode-vgroup +#define TSDB_CODE_MND_VGROUP_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0390) +#define TSDB_CODE_MND_VGROUP_NOT_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0391) +#define TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE TAOS_DEF_ERROR_CODE(0, 0x0392) // mnode-stable #define TSDB_CODE_MND_STB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0360) @@ -223,30 +244,6 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_INVALID_TAG_LENGTH TAOS_DEF_ERROR_CODE(0, 0x0376) //"invalid tag length") #define TSDB_CODE_MND_INVALID_COLUMN_LENGTH TAOS_DEF_ERROR_CODE(0, 0x0377) //"invalid column length") -#define TSDB_CODE_MND_DB_NOT_SELECTED TAOS_DEF_ERROR_CODE(0, 0x0380) -#define TSDB_CODE_MND_DB_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x0381) -#define TSDB_CODE_MND_DB_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x0381) -#define TSDB_CODE_MND_INVALID_DB TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_OPTION TAOS_DEF_ERROR_CODE(0, 0x0382) -#define TSDB_CODE_MND_INVALID_DB_CACHE_SIZE TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_TOTAL_BLOCKS TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_DAYS TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_KEEP0 TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_KEEP1 TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_KEEP2 TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_MIN_ROWS TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_MAX_ROWS TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_COMMIT_TIME TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_FSYNC_PERIOD TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_WAL_LEVEL TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_PRECISION TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_COMP TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_REPLICA TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_QUORUM TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_UPDATE TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_INVALID_DB_CACHE_LAST TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_DB_OPTION_UNCHANGED TAOS_DEF_ERROR_CODE(0, 0x0383) -#define TSDB_CODE_MND_TOO_MANY_DATABASES TAOS_DEF_ERROR_CODE(0, 0x0385) //"Too many databases for account") // dnode #define TSDB_CODE_DND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0400) @@ -501,6 +498,13 @@ int32_t* taosGetErrno(); // monitor #define TSDB_CODE_MON_CONNECTION_INVALID TAOS_DEF_ERROR_CODE(0, 0x2300) //"monitor invalid monitor db connection") +// catalog +#define TSDB_CODE_CTG_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2400) //catalog interval error +#define TSDB_CODE_CTG_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2401) //invalid catalog input parameters +#define TSDB_CODE_CTG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x2402) //catalog is not ready +#define TSDB_CODE_CTG_MEM_ERROR TAOS_DEF_ERROR_CODE(0, 0x2403) //catalog memory error +#define TSDB_CODE_CTG_SYS_ERROR TAOS_DEF_ERROR_CODE(0, 0x2404) //catalog system error + #ifdef __cplusplus } #endif diff --git a/include/util/tarray.h b/include/util/tarray.h index e0f14dcd25..f7c72add01 100644 --- a/include/util/tarray.h +++ b/include/util/tarray.h @@ -41,7 +41,7 @@ typedef struct SArray { * @param elemSize * @return */ -void* taosArrayInit(size_t size, size_t elemSize); +SArray* taosArrayInit(size_t size, size_t elemSize); /** * diff --git a/include/util/tdef.h b/include/util/tdef.h index 7f5ebaee57..6fcb7e3325 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -25,7 +25,9 @@ extern "C" { #define TSDB__packed #define TSKEY int64_t -#define TSKEY_INITIAL_VAL INT64_MIN +#define TSKEY_MIN INT64_MIN +#define TSKEY_MAX (INT64_MAX - 1) +#define TSKEY_INITIAL_VAL TSKEY_MIN // Bytes for each type. extern const int32_t TYPE_BYTES[15]; @@ -210,6 +212,7 @@ do { \ #define TSDB_STEP_NAME_LEN 32 #define TSDB_STEP_DESC_LEN 128 +#define TSDB_ERROR_MSG_LEN 1024 #define TSDB_DNODE_CONFIG_LEN 128 #define TSDB_MQTT_HOSTNAME_LEN 64 diff --git a/include/util/tdlist.h b/include/util/tdlist.h index a19f3bebec..d047a57770 100644 --- a/include/util/tdlist.h +++ b/include/util/tdlist.h @@ -58,8 +58,8 @@ extern "C" { // Double linked list #define TD_DLIST_NODE(TYPE) \ struct { \ - TYPE *dl_prev_; \ - TYPE *dl_next_; \ + struct TYPE *dl_prev_; \ + struct TYPE *dl_next_; \ } #define TD_DLIST(TYPE) \ diff --git a/include/util/tlog.h b/include/util/tlog.h index 2ee60e4324..5e6604598d 100644 --- a/include/util/tlog.h +++ b/include/util/tlog.h @@ -32,7 +32,6 @@ extern int32_t mDebugFlag; extern int32_t cDebugFlag; extern int32_t jniDebugFlag; extern int32_t tmrDebugFlag; -extern int32_t sdbDebugFlag; extern int32_t httpDebugFlag; extern int32_t mqttDebugFlag; extern int32_t monDebugFlag; @@ -45,6 +44,8 @@ extern int32_t sDebugFlag; extern int32_t tsdbDebugFlag; extern int32_t cqDebugFlag; extern int32_t debugFlag; +extern int32_t ctgDebugFlag; + #define DEBUG_FATAL 1U #define DEBUG_ERROR DEBUG_FATAL diff --git a/include/util/tmacro.h b/include/util/tmacro.h index 74056cfe07..5cca8a1062 100644 --- a/include/util/tmacro.h +++ b/include/util/tmacro.h @@ -29,13 +29,11 @@ extern "C" { #define TD_MOD_UNCLEARD 0 #define TD_MOD_CLEARD 1 -#define TD_DEF_MOD_INIT_FLAG(MOD) static int8_t MOD##InitFlag = TD_MOD_UNINITIALIZED -#define TD_DEF_MOD_CLEAR_FLAG(MOD) static int8_t MOD##ClearFlag = TD_MOD_UNCLEARD +typedef int8_t td_mode_flag_t; -#define TD_CHECK_AND_SET_MODE_INIT(MOD) \ - atomic_val_compare_exchange_8(&(MOD##InitFlag), TD_MOD_UNINITIALIZED, TD_MOD_INITIALIZED) +#define TD_CHECK_AND_SET_MODE_INIT(FLAG) atomic_val_compare_exchange_8((FLAG), TD_MOD_UNINITIALIZED, TD_MOD_INITIALIZED) -#define TD_CHECK_AND_SET_MOD_CLEAR(MOD) atomic_val_compare_exchange_8(&(MOD##ClearFlag), TD_MOD_UNCLEARD, TD_MOD_CLEARD) +#define TD_CHECK_AND_SET_MOD_CLEAR(FLAG) atomic_val_compare_exchange_8((FLAG), TD_MOD_UNCLEARD, TD_MOD_CLEARD) #ifdef __cplusplus } diff --git a/include/util/tref.h b/include/util/tref.h index cc7d075f52..6680204d63 100644 --- a/include/util/tref.h +++ b/include/util/tref.h @@ -17,6 +17,8 @@ #ifndef _TD_UTIL_REF_H #define _TD_UTIL_REF_H +#include "os.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/source/client/CMakeLists.txt b/source/client/CMakeLists.txt index b916d26dd2..b11146a03f 100644 --- a/source/client/CMakeLists.txt +++ b/source/client/CMakeLists.txt @@ -7,6 +7,7 @@ target_include_directories( ) target_link_libraries( taos + PRIVATE common INTERFACE api PRIVATE os util common transport parser catalog function ) diff --git a/source/client/src/client.c b/source/client/src/client.c new file mode 100644 index 0000000000..e69de29bb2 diff --git a/source/common/inc/commonInt.h b/source/common/inc/commonInt.h index b8be8899f3..5b71f83faf 100644 --- a/source/common/inc/commonInt.h +++ b/source/common/inc/commonInt.h @@ -20,8 +20,12 @@ extern "C" { #endif +extern bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTags); + + + #ifdef __cplusplus } #endif -#endif /*_TD_COMMON_INT_H_*/ \ No newline at end of file +#endif /*_TD_COMMON_INT_H_*/ diff --git a/source/common/src/tmessage.c b/source/common/src/taosmsg.c similarity index 99% rename from source/common/src/tmessage.c rename to source/common/src/taosmsg.c index 0b6dbfdb51..b35e3f1478 100644 --- a/source/common/src/tmessage.c +++ b/source/common/src/taosmsg.c @@ -16,3 +16,5 @@ #define TAOS_MESSAGE_C #include "taosmsg.h" + + diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 4896251a79..910d05e9a3 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -30,19 +30,12 @@ // cluster char tsFirst[TSDB_EP_LEN] = {0}; char tsSecond[TSDB_EP_LEN] = {0}; -char tsArbitrator[TSDB_EP_LEN] = {0}; char tsLocalFqdn[TSDB_FQDN_LEN] = {0}; char tsLocalEp[TSDB_EP_LEN] = {0}; // Local End Point, hostname:port uint16_t tsServerPort = 6030; int32_t tsStatusInterval = 1; // second -int32_t tsNumOfMnodes = 1; -int8_t tsEnableVnodeBak = 1; int8_t tsEnableTelemetryReporting = 0; -int8_t tsArbOnline = 0; -int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME; char tsEmail[TSDB_FQDN_LEN] = {0}; -int32_t tsDnodeId = 0; -int64_t tsDnodeStartTime = 0; // common int32_t tsRpcTimer = 300; @@ -129,59 +122,19 @@ int32_t tsRetrieveBlockingModel = 0; // last_row(*), first(*), last_row(ts, col1, col2) query, the result fields will be the original column name int8_t tsKeepOriginalColumnName = 0; -// db parameters -int32_t tsCacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE; -int32_t tsBlocksPerVnode = TSDB_DEFAULT_TOTAL_BLOCKS; -int16_t tsDaysPerFile = TSDB_DEFAULT_DAYS_PER_FILE; -int32_t tsDaysToKeep = TSDB_DEFAULT_KEEP; -int32_t tsMinRowsInFileBlock = TSDB_DEFAULT_MIN_ROW_FBLOCK; -int32_t tsMaxRowsInFileBlock = TSDB_DEFAULT_MAX_ROW_FBLOCK; -int16_t tsCommitTime = TSDB_DEFAULT_COMMIT_TIME; // seconds -int32_t tsTimePrecision = TSDB_DEFAULT_PRECISION; -int8_t tsCompression = TSDB_DEFAULT_COMP_LEVEL; -int8_t tsWAL = TSDB_DEFAULT_WAL_LEVEL; -int32_t tsFsyncPeriod = TSDB_DEFAULT_FSYNC_PERIOD; -int32_t tsReplications = TSDB_DEFAULT_DB_REPLICA_OPTION; -int32_t tsQuorum = TSDB_DEFAULT_DB_QUORUM_OPTION; -int8_t tsUpdate = TSDB_DEFAULT_DB_UPDATE_OPTION; -int8_t tsCacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW; -int32_t tsMaxVgroupsPerDb = 0; -int32_t tsTsdbMetaCompactRatio = TSDB_META_COMPACT_RATIO; - // tsdb config // For backward compatibility bool tsdbForceKeepFile = false; // balance -int8_t tsEnableBalance = 1; -int8_t tsAlternativeRole = 0; -int32_t tsBalanceInterval = 300; // seconds -int32_t tsOfflineThreshold = 86400 * 10; // seconds of 10 days int8_t tsEnableFlowCtrl = 1; int8_t tsEnableSlaveQuery = 1; int8_t tsEnableAdjustMaster = 1; -// restful -int32_t tsRestRowLimit = 10240; -int8_t tsTelegrafUseFieldNum = 0; - -// mqtt -int8_t tsEnableMqttModule = 0; // not finished yet, not started it by default -char tsMqttHostName[TSDB_MQTT_HOSTNAME_LEN] = "test.mosquitto.org"; -char tsMqttPort[TSDB_MQTT_PORT_LEN] = "1883"; -char tsMqttUser[TSDB_MQTT_USER_LEN] = {0}; -char tsMqttPass[TSDB_MQTT_PASS_LEN] = {0}; -char tsMqttClientId[TSDB_MQTT_CLIENT_ID_LEN] = "TDengineMqttSubscriber"; -char tsMqttTopic[TSDB_MQTT_TOPIC_LEN] = "/test"; // # // monitor -int8_t tsEnableMonitorModule = 1; char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log"; char tsInternalPass[] = "secretkey"; -int32_t tsMonitorInterval = 30; // seconds - -// stream -int8_t tsEnableStream = 1; // internal int8_t tsCompactMnodeWal = 0; @@ -191,7 +144,6 @@ char tsDnodeDir[PATH_MAX] = {0}; char tsMnodeDir[PATH_MAX] = {0}; int32_t tsDiskCfgNum = 0; -int32_t tsTopicBianryLen = 16000; #ifndef _STORAGE SDiskCfg tsDiskCfg[1]; @@ -245,14 +197,10 @@ static pthread_once_t tsInitGlobalCfgOnce = PTHREAD_ONCE_INIT; void taosSetAllDebugFlag() { if (debugFlag != 0) { mDebugFlag = debugFlag; - sdbDebugFlag = debugFlag; dDebugFlag = debugFlag; vDebugFlag = debugFlag; jniDebugFlag = debugFlag; odbcDebugFlag = debugFlag; - httpDebugFlag = debugFlag; - mqttDebugFlag = debugFlag; - monDebugFlag = debugFlag; qDebugFlag = debugFlag; rpcDebugFlag = debugFlag; uDebugFlag = debugFlag; @@ -459,16 +407,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "arbitrator"; - cfg.ptr = tsArbitrator; - cfg.valType = TAOS_CFG_VTYPE_STRING; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; - cfg.minValue = 0; - cfg.maxValue = 0; - cfg.ptrLength = TSDB_EP_LEN; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - // dnode configs cfg.option = "numOfThreadsPerCore"; cfg.ptr = &tsNumOfThreadsPerCore; @@ -509,26 +447,6 @@ static void doInitGlobalConfig(void) { cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - - cfg.option = "numOfMnodes"; - cfg.ptr = &tsNumOfMnodes; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 1; - cfg.maxValue = 3; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "vnodeBak"; - cfg.ptr = &tsEnableVnodeBak; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); cfg.option = "telemetryReporting"; cfg.ptr = &tsEnableTelemetryReporting; @@ -540,37 +458,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "balance"; - cfg.ptr = &tsEnableBalance; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "balanceInterval"; - cfg.ptr = &tsBalanceInterval; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 1; - cfg.maxValue = 30000; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - // 0-any; 1-mnode; 2-vnode - cfg.option = "role"; - cfg.ptr = &tsAlternativeRole; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; - cfg.minValue = 0; - cfg.maxValue = 2; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - // timer cfg.option = "maxTmrCtrl"; cfg.ptr = &tsMaxTmrCtrl; @@ -582,26 +469,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "monitorInterval"; - cfg.ptr = &tsMonitorInterval; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; - cfg.minValue = 1; - cfg.maxValue = 600; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_SECOND; - taosAddConfigOption(cfg); - - cfg.option = "offlineThreshold"; - cfg.ptr = &tsOfflineThreshold; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 3; - cfg.maxValue = 86400 * 365; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_SECOND; - taosAddConfigOption(cfg); - cfg.option = "rpcTimer"; cfg.ptr = &tsRpcTimer; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -712,186 +579,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "maxVgroupsPerDb"; - cfg.ptr = &tsMaxVgroupsPerDb; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 8192; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "cache"; - cfg.ptr = &tsCacheBlockSize; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_CACHE_BLOCK_SIZE; - cfg.maxValue = TSDB_MAX_CACHE_BLOCK_SIZE; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_MB; - taosAddConfigOption(cfg); - - cfg.option = "blocks"; - cfg.ptr = &tsBlocksPerVnode; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_TOTAL_BLOCKS; - cfg.maxValue = TSDB_MAX_TOTAL_BLOCKS; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "days"; - cfg.ptr = &tsDaysPerFile; - cfg.valType = TAOS_CFG_VTYPE_INT16; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DAYS_PER_FILE; - cfg.maxValue = TSDB_MAX_DAYS_PER_FILE; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "keep"; - cfg.ptr = &tsDaysToKeep; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_KEEP; - cfg.maxValue = TSDB_MAX_KEEP; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "minRows"; - cfg.ptr = &tsMinRowsInFileBlock; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_MIN_ROW_FBLOCK; - cfg.maxValue = TSDB_MAX_MIN_ROW_FBLOCK; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "maxRows"; - cfg.ptr = &tsMaxRowsInFileBlock; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_MAX_ROW_FBLOCK; - cfg.maxValue = TSDB_MAX_MAX_ROW_FBLOCK; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "precision"; - cfg.ptr = &tsTimePrecision; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_PRECISION; - cfg.maxValue = TSDB_MAX_PRECISION; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "comp"; - cfg.ptr = &tsCompression; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_COMP_LEVEL; - cfg.maxValue = TSDB_MAX_COMP_LEVEL; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "walLevel"; - cfg.ptr = &tsWAL; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_WAL_LEVEL; - cfg.maxValue = TSDB_MAX_WAL_LEVEL; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "fsync"; - cfg.ptr = &tsFsyncPeriod; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_FSYNC_PERIOD; - cfg.maxValue = TSDB_MAX_FSYNC_PERIOD; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "replica"; - cfg.ptr = &tsReplications; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DB_REPLICA_OPTION; - cfg.maxValue = TSDB_MAX_DB_REPLICA_OPTION; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "quorum"; - cfg.ptr = &tsQuorum; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DB_QUORUM_OPTION; - cfg.maxValue = TSDB_MAX_DB_QUORUM_OPTION; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "update"; - cfg.ptr = &tsUpdate; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DB_UPDATE; - cfg.maxValue = TSDB_MAX_DB_UPDATE; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "cachelast"; - cfg.ptr = &tsCacheLastRow; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DB_CACHE_LAST_ROW; - cfg.maxValue = TSDB_MAX_DB_CACHE_LAST_ROW; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "mqttHostName"; - cfg.ptr = tsMqttHostName; - cfg.valType = TAOS_CFG_VTYPE_STRING; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_NOT_PRINT; - cfg.minValue = 0; - cfg.maxValue = 0; - cfg.ptrLength = TSDB_MQTT_HOSTNAME_LEN; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "mqttPort"; - cfg.ptr = tsMqttPort; - cfg.valType = TAOS_CFG_VTYPE_STRING; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_NOT_PRINT; - cfg.minValue = 0; - cfg.maxValue = 0; - cfg.ptrLength = TSDB_MQTT_PORT_LEN; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "mqttTopic"; - cfg.ptr = tsMqttTopic; - cfg.valType = TAOS_CFG_VTYPE_STRING; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_NOT_PRINT; - cfg.minValue = 0; - cfg.maxValue = 0; - cfg.ptrLength = TSDB_MQTT_TOPIC_LEN; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - cfg.option = "compressMsgSize"; cfg.ptr = &tsCompressMsgSize; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -1085,76 +772,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "adjustMaster"; - cfg.ptr = &tsEnableAdjustMaster; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "mqtt"; - cfg.ptr = &tsEnableMqttModule; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "monitor"; - cfg.ptr = &tsEnableMonitorModule; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "stream"; - cfg.ptr = &tsEnableStream; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "topicBianryLen"; - cfg.ptr = &tsTopicBianryLen; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; - cfg.minValue = 16; - cfg.maxValue = 16000; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "telegrafUseFieldNum"; - cfg.ptr = &tsTelegrafUseFieldNum; - cfg.valType = TAOS_CFG_VTYPE_INT8; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = 0; - cfg.maxValue = 1; - cfg.ptrLength = 1; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "restfulRowLimit"; - cfg.ptr = &tsRestRowLimit; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; - cfg.minValue = 1; - cfg.maxValue = 10000000; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - // debug flag cfg.option = "numOfLogLines"; cfg.ptr = &tsNumOfLogLines; @@ -1236,17 +853,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - - cfg.option = "sdbDebugFlag"; - cfg.ptr = &sdbDebugFlag; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG; - cfg.minValue = 0; - cfg.maxValue = 255; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - cfg.option = "rpcDebugFlag"; cfg.ptr = &rpcDebugFlag; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -1307,36 +913,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); - cfg.option = "httpDebugFlag"; - cfg.ptr = &httpDebugFlag; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG; - cfg.minValue = 0; - cfg.maxValue = 255; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "mqttDebugFlag"; - cfg.ptr = &mqttDebugFlag; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG; - cfg.minValue = 0; - cfg.maxValue = 255; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "monDebugFlag"; - cfg.ptr = &monDebugFlag; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG; - cfg.minValue = 0; - cfg.maxValue = 255; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - cfg.option = "qDebugFlag"; cfg.ptr = &qDebugFlag; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -1456,16 +1032,6 @@ static void doInitGlobalConfig(void) { cfg.maxValue = 0; cfg.ptrLength = PATH_MAX; cfg.unitType = TAOS_CFG_UTYPE_NONE; - taosAddConfigOption(cfg); - - cfg.option = "tsdbMetaCompactRatio"; - cfg.ptr = &tsTsdbMetaCompactRatio; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG; - cfg.minValue = 0; - cfg.maxValue = 100; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_NONE; taosAddConfigOption(cfg); // enable kill long query diff --git a/source/dnode/mgmt/impl/src/dndTransport.c b/source/dnode/mgmt/impl/src/dndTransport.c index 0c4eca569d..6dc46cefcd 100644 --- a/source/dnode/mgmt/impl/src/dndTransport.c +++ b/source/dnode/mgmt/impl/src/dndTransport.c @@ -72,7 +72,7 @@ static void dndInitMsgFp(STransMgmt *pMgmt) { pMgmt->msgFp[TSDB_MSG_TYPE_CREATE_STB] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_ALTER_STB] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_DROP_STB] = dndProcessMnodeWriteMsg; - pMgmt->msgFp[TSDB_MSG_TYPE_STB_VGROUP] = dndProcessMnodeReadMsg; + pMgmt->msgFp[TSDB_MSG_TYPE_VGROUP_LIST] = dndProcessMnodeReadMsg; pMgmt->msgFp[TSDB_MSG_TYPE_KILL_QUERY] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_KILL_STREAM] = dndProcessMnodeWriteMsg; pMgmt->msgFp[TSDB_MSG_TYPE_KILL_CONN] = dndProcessMnodeWriteMsg; @@ -368,4 +368,4 @@ void dndSendMsgToMnode(SDnode *pDnode, SRpcMsg *pMsg) { SEpSet epSet = {0}; dndGetMnodeEpSet(pDnode, &epSet); dndSendMsgToDnode(pDnode, &epSet, pMsg); -} \ No newline at end of file +} diff --git a/source/dnode/mgmt/impl/test/CMakeLists.txt b/source/dnode/mgmt/impl/test/CMakeLists.txt index b340029044..86186f77de 100644 --- a/source/dnode/mgmt/impl/test/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/CMakeLists.txt @@ -1,6 +1,19 @@ -# add_subdirectory(acct) + +add_subdirectory(acct) +# add_subdirectory(auth) +# add_subdirectory(balance) # add_subdirectory(cluster) +add_subdirectory(db) add_subdirectory(dnode) +# add_subdirectory(func) +# add_subdirectory(mnode) # add_subdirectory(profile) # add_subdirectory(show) +# add_subdirectory(stb) +# add_subdirectory(sync) +# add_subdirectory(telem) +# add_subdirectory(trans) add_subdirectory(user) +# add_subdirectory(vgroup) + +# add_subdirectory(common) diff --git a/source/dnode/mgmt/impl/test/acct/CMakeLists.txt b/source/dnode/mgmt/impl/test/acct/CMakeLists.txt index 3e963df2e6..a548c2adc2 100644 --- a/source/dnode/mgmt/impl/test/acct/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/acct/CMakeLists.txt @@ -1,20 +1,20 @@ -add_executable(dndTestAcct "") +add_executable(dnode_test_acct "") -target_sources(dndTestAcct +target_sources(dnode_test_acct PRIVATE "acct.cpp" "../sut/deploy.cpp" ) target_link_libraries( - dndTestAcct + dnode_test_acct PUBLIC dnode PUBLIC util PUBLIC os PUBLIC gtest_main ) -target_include_directories(dndTestAcct +target_include_directories(dnode_test_acct PUBLIC "${CMAKE_SOURCE_DIR}/include/server/dnode/mgmt" "${CMAKE_CURRENT_SOURCE_DIR}/../../inc" @@ -24,6 +24,6 @@ target_include_directories(dndTestAcct enable_testing() add_test( - NAME dndTestAcct - COMMAND dndTestAcct + NAME dnode_test_acct + COMMAND dnode_test_acct ) diff --git a/source/dnode/mgmt/impl/test/acct/acct.cpp b/source/dnode/mgmt/impl/test/acct/acct.cpp index 9050a938fa..e1a71c5c9d 100644 --- a/source/dnode/mgmt/impl/test/acct/acct.cpp +++ b/source/dnode/mgmt/impl/test/acct/acct.cpp @@ -17,24 +17,27 @@ class DndTestAcct : public ::testing::Test { protected: - void SetUp() override {} - void TearDown() override {} + static SServer* CreateServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) { + SServer* pServer = createServer(path, fqdn, port, firstEp); + ASSERT(pServer); + return pServer; + } static void SetUpTestSuite() { - const char* user = "root"; - const char* pass = "taosdata"; - const char* path = "/tmp/dndTestAcct"; - const char* fqdn = "localhost"; - uint16_t port = 9520; + initLog("/tmp/tdlog"); - pServer = createServer(path, fqdn, port); - ASSERT(pServer); - pClient = createClient(user, pass, fqdn, port); + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9012"; + pServer = CreateServer("/tmp/dnode_test_user", fqdn, 9012, firstEp); + pClient = createClient("root", "taosdata", fqdn, 9012); + taosMsleep(300); } static void TearDownTestSuite() { stopServer(pServer); dropClient(pClient); + pServer = NULL; + pClient = NULL; } static SServer* pServer; diff --git a/source/dnode/mgmt/impl/test/db/CMakeLists.txt b/source/dnode/mgmt/impl/test/db/CMakeLists.txt new file mode 100644 index 0000000000..b778e3854f --- /dev/null +++ b/source/dnode/mgmt/impl/test/db/CMakeLists.txt @@ -0,0 +1,29 @@ +add_executable(dnode_test_db "") + +target_sources(dnode_test_db + PRIVATE + "db.cpp" + "../sut/deploy.cpp" +) + +target_link_libraries( + dnode_test_db + PUBLIC dnode + PUBLIC util + PUBLIC os + PUBLIC gtest_main +) + +target_include_directories(dnode_test_db + PUBLIC + "${CMAKE_SOURCE_DIR}/include/server/dnode/mgmt" + "${CMAKE_CURRENT_SOURCE_DIR}/../../inc" + "${CMAKE_CURRENT_SOURCE_DIR}/../sut" +) + +enable_testing() + +add_test( + NAME dnode_test_db + COMMAND dnode_test_db +) diff --git a/source/dnode/mgmt/impl/test/db/db.cpp b/source/dnode/mgmt/impl/test/db/db.cpp new file mode 100644 index 0000000000..b0ee00cb64 --- /dev/null +++ b/source/dnode/mgmt/impl/test/db/db.cpp @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "deploy.h" + +class DndTestDb : public ::testing::Test { + protected: + static SServer* CreateServer(const char* path, const char* fqdn, uint16_t port, const char* firstEp) { + SServer* pServer = createServer(path, fqdn, port, firstEp); + ASSERT(pServer); + return pServer; + } + + static void SetUpTestSuite() { + initLog("/tmp/tdlog"); + + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9040"; + pServer = CreateServer("/tmp/dnode_test_db", fqdn, 9040, firstEp); + pClient = createClient("root", "taosdata", fqdn, 9040); + taosMsleep(300); + } + + static void TearDownTestSuite() { + stopServer(pServer); + dropClient(pClient); + pServer = NULL; + pClient = NULL; + } + + static SServer* pServer; + static SClient* pClient; + static int32_t connId; + + public: + void SetUp() override {} + void TearDown() override {} + + void SendTheCheckShowMetaMsg(int8_t showType, const char* showName, int32_t columns) { + SShowMsg* pShow = (SShowMsg*)rpcMallocCont(sizeof(SShowMsg)); + pShow->type = showType; + strcpy(pShow->db, ""); + + SRpcMsg showRpcMsg = {0}; + showRpcMsg.pCont = pShow; + showRpcMsg.contLen = sizeof(SShowMsg); + showRpcMsg.msgType = TSDB_MSG_TYPE_SHOW; + + sendMsg(pClient, &showRpcMsg); + ASSERT_NE(pClient->pRsp, nullptr); + ASSERT_EQ(pClient->pRsp->code, 0); + ASSERT_NE(pClient->pRsp->pCont, nullptr); + + SShowRsp* pShowRsp = (SShowRsp*)pClient->pRsp->pCont; + ASSERT_NE(pShowRsp, nullptr); + pShowRsp->showId = htonl(pShowRsp->showId); + pMeta = &pShowRsp->tableMeta; + pMeta->numOfTags = htons(pMeta->numOfTags); + pMeta->numOfColumns = htons(pMeta->numOfColumns); + pMeta->sversion = htons(pMeta->sversion); + pMeta->tversion = htons(pMeta->tversion); + pMeta->tuid = htobe64(pMeta->tuid); + pMeta->suid = htobe64(pMeta->suid); + + showId = pShowRsp->showId; + + EXPECT_NE(pShowRsp->showId, 0); + EXPECT_STREQ(pMeta->tbFname, showName); + EXPECT_EQ(pMeta->numOfTags, 0); + EXPECT_EQ(pMeta->numOfColumns, columns); + EXPECT_EQ(pMeta->precision, 0); + EXPECT_EQ(pMeta->tableType, 0); + EXPECT_EQ(pMeta->update, 0); + EXPECT_EQ(pMeta->sversion, 0); + EXPECT_EQ(pMeta->tversion, 0); + EXPECT_EQ(pMeta->tuid, 0); + EXPECT_EQ(pMeta->suid, 0); + } + + void CheckSchema(int32_t index, int8_t type, int32_t bytes, const char* name) { + SSchema* pSchema = &pMeta->pSchema[index]; + pSchema->bytes = htons(pSchema->bytes); + EXPECT_EQ(pSchema->colId, 0); + EXPECT_EQ(pSchema->type, type); + EXPECT_EQ(pSchema->bytes, bytes); + EXPECT_STREQ(pSchema->name, name); + } + + void SendThenCheckShowRetrieveMsg(int32_t rows) { + SRetrieveTableMsg* pRetrieve = (SRetrieveTableMsg*)rpcMallocCont(sizeof(SRetrieveTableMsg)); + pRetrieve->showId = htonl(showId); + pRetrieve->free = 0; + + SRpcMsg retrieveRpcMsg = {0}; + retrieveRpcMsg.pCont = pRetrieve; + retrieveRpcMsg.contLen = sizeof(SRetrieveTableMsg); + retrieveRpcMsg.msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE; + + sendMsg(pClient, &retrieveRpcMsg); + + ASSERT_NE(pClient->pRsp, nullptr); + ASSERT_EQ(pClient->pRsp->code, 0); + ASSERT_NE(pClient->pRsp->pCont, nullptr); + + pRetrieveRsp = (SRetrieveTableRsp*)pClient->pRsp->pCont; + ASSERT_NE(pRetrieveRsp, nullptr); + pRetrieveRsp->numOfRows = htonl(pRetrieveRsp->numOfRows); + pRetrieveRsp->offset = htobe64(pRetrieveRsp->offset); + pRetrieveRsp->useconds = htobe64(pRetrieveRsp->useconds); + pRetrieveRsp->compLen = htonl(pRetrieveRsp->compLen); + + EXPECT_EQ(pRetrieveRsp->numOfRows, rows); + EXPECT_EQ(pRetrieveRsp->offset, 0); + EXPECT_EQ(pRetrieveRsp->useconds, 0); + // EXPECT_EQ(pRetrieveRsp->completed, completed); + EXPECT_EQ(pRetrieveRsp->precision, TSDB_TIME_PRECISION_MILLI); + EXPECT_EQ(pRetrieveRsp->compressed, 0); + EXPECT_EQ(pRetrieveRsp->reserved, 0); + EXPECT_EQ(pRetrieveRsp->compLen, 0); + + pData = pRetrieveRsp->data; + pos = 0; + } + + void CheckInt8(int8_t val) { + int8_t data = *((int8_t*)(pData + pos)); + pos += sizeof(int8_t); + EXPECT_EQ(data, val); + } + + void CheckInt16(int16_t val) { + int16_t data = *((int16_t*)(pData + pos)); + pos += sizeof(int16_t); + EXPECT_EQ(data, val); + } + + void CheckInt32(int32_t val) { + int32_t data = *((int32_t*)(pData + pos)); + pos += sizeof(int32_t); + EXPECT_EQ(data, val); + } + + void CheckInt64(int64_t val) { + int64_t data = *((int64_t*)(pData + pos)); + pos += sizeof(int64_t); + EXPECT_EQ(data, val); + } + + void CheckTimestamp() { + int64_t data = *((int64_t*)(pData + pos)); + pos += sizeof(int64_t); + EXPECT_GT(data, 0); + } + + void CheckBinary(const char* val, int32_t len) { + pos += sizeof(VarDataLenT); + char* data = (char*)(pData + pos); + pos += len; + EXPECT_STREQ(data, val); + } + + int32_t showId; + STableMetaMsg* pMeta; + SRetrieveTableRsp* pRetrieveRsp; + char* pData; + int32_t pos; +}; + +SServer* DndTestDb::pServer; +SClient* DndTestDb::pClient; +int32_t DndTestDb::connId; + +TEST_F(DndTestDb, 01_ShowDb) { + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DB, "show databases", 16); + CheckSchema(0, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN - 1 + VARSTR_HEADER_SIZE, "name"); + CheckSchema(1, TSDB_DATA_TYPE_TIMESTAMP, 8, "create time"); + CheckSchema(2, TSDB_DATA_TYPE_SMALLINT, 2, "replica"); + CheckSchema(3, TSDB_DATA_TYPE_SMALLINT, 2, "quorum"); + CheckSchema(4, TSDB_DATA_TYPE_SMALLINT, 2, "days"); + CheckSchema(5, TSDB_DATA_TYPE_BINARY, 24 + VARSTR_HEADER_SIZE, "keep0,keep1,keep2"); + CheckSchema(6, TSDB_DATA_TYPE_INT, 4, "cache(MB)"); + CheckSchema(7, TSDB_DATA_TYPE_INT, 4, "blocks"); + CheckSchema(8, TSDB_DATA_TYPE_INT, 4, "minrows"); + CheckSchema(9, TSDB_DATA_TYPE_INT, 4, "maxrows"); + CheckSchema(10, TSDB_DATA_TYPE_TINYINT, 1, "wallevel"); + CheckSchema(11, TSDB_DATA_TYPE_INT, 4, "fsync"); + CheckSchema(12, TSDB_DATA_TYPE_TINYINT, 1, "comp"); + CheckSchema(13, TSDB_DATA_TYPE_TINYINT, 1, "cachelast"); + CheckSchema(14, TSDB_DATA_TYPE_BINARY, 3 + VARSTR_HEADER_SIZE, "precision"); + CheckSchema(15, TSDB_DATA_TYPE_TINYINT, 1, "update"); + + SendThenCheckShowRetrieveMsg(0); +} + +TEST_F(DndTestDb, 02_CreateDb) { + { + SCreateDbMsg* pReq = (SCreateDbMsg*)rpcMallocCont(sizeof(SCreateDbMsg)); + strcpy(pReq->db, "1.d1"); + pReq->cacheBlockSize = htonl(16); + pReq->totalBlocks = htonl(10); + pReq->daysPerFile = htonl(10); + pReq->daysToKeep0 = htonl(3650); + pReq->daysToKeep1 = htonl(3650); + pReq->daysToKeep2 = htonl(3650); + pReq->minRowsPerFileBlock = htonl(100); + pReq->maxRowsPerFileBlock = htonl(4096); + pReq->commitTime = htonl(3600); + pReq->fsyncPeriod = htonl(3000); + pReq->walLevel = 1; + pReq->precision = 0; + pReq->compression = 2; + pReq->replications = 1; + pReq->quorum = 1; + pReq->update = 0; + pReq->cacheLastRow = 0; + pReq->ignoreExist = 1; + + SRpcMsg rpcMsg = {0}; + rpcMsg.pCont = pReq; + rpcMsg.contLen = sizeof(SCreateDbMsg); + rpcMsg.msgType = TSDB_MSG_TYPE_CREATE_DB; + + sendMsg(pClient, &rpcMsg); + SRpcMsg* pMsg = pClient->pRsp; + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DB, "show databases", 16); + SendThenCheckShowRetrieveMsg(1); + CheckBinary("d1", TSDB_DB_NAME_LEN - 1); + CheckTimestamp(); + CheckInt16(1); // replica + CheckInt16(1); // quorum + CheckInt16(10); // days + CheckBinary("3650,3650,3650", 24); // days + CheckInt32(16); // cache + CheckInt32(10); // blocks + CheckInt32(100); // minrows + CheckInt32(4096); // maxrows + CheckInt8(1); // wallevel + CheckInt32(3000); // fsync + CheckInt8(2); // comp + CheckInt8(0); // cachelast + CheckBinary("ms", 3); // precision + CheckInt8(0); // update +} + +TEST_F(DndTestDb, 03_AlterDb) { + { + SAlterDbMsg* pReq = (SAlterDbMsg*)rpcMallocCont(sizeof(SAlterDbMsg)); + strcpy(pReq->db, "1.d1"); + pReq->totalBlocks = htonl(12); + pReq->daysToKeep0 = htonl(300); + pReq->daysToKeep1 = htonl(400); + pReq->daysToKeep2 = htonl(500); + pReq->fsyncPeriod = htonl(4000); + pReq->walLevel = 2; + pReq->quorum = 2; + pReq->cacheLastRow = 1; + + SRpcMsg rpcMsg = {0}; + rpcMsg.pCont = pReq; + rpcMsg.contLen = sizeof(SAlterDbMsg); + rpcMsg.msgType = TSDB_MSG_TYPE_ALTER_DB; + + sendMsg(pClient, &rpcMsg); + SRpcMsg* pMsg = pClient->pRsp; + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DB, "show databases", 16); + SendThenCheckShowRetrieveMsg(1); + CheckBinary("d1", TSDB_DB_NAME_LEN - 1); + CheckTimestamp(); + CheckInt16(1); // replica + CheckInt16(2); // quorum + CheckInt16(10); // days + CheckBinary("300,400,500", 24); // days + CheckInt32(16); // cache + CheckInt32(12); // blocks + CheckInt32(100); // minrows + CheckInt32(4096); // maxrows + CheckInt8(2); // wallevel + CheckInt32(4000); // fsync + CheckInt8(2); // comp + CheckInt8(1); // cachelast + CheckBinary("ms", 3); // precision + CheckInt8(0); // update +} + +TEST_F(DndTestDb, 04_RestartDnode) { + stopServer(pServer); + pServer = NULL; + + uInfo("start all server"); + + const char* fqdn = "localhost"; + const char* firstEp = "localhost:9040"; + pServer = startServer("/tmp/dnode_test_db", fqdn, 9040, firstEp); + + uInfo("all server is running"); + + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DB, "show databases", 16); + SendThenCheckShowRetrieveMsg(1); + CheckBinary("d1", TSDB_DB_NAME_LEN - 1); + CheckTimestamp(); + CheckInt16(1); // replica + CheckInt16(2); // quorum + CheckInt16(10); // days + CheckBinary("300,400,500", 24); // days + CheckInt32(16); // cache + CheckInt32(12); // blocks + CheckInt32(100); // minrows + CheckInt32(4096); // maxrows + CheckInt8(2); // wallevel + CheckInt32(4000); // fsync + CheckInt8(2); // comp + CheckInt8(1); // cachelast + CheckBinary("ms", 3); // precision + CheckInt8(0); // update +} + +TEST_F(DndTestDb, 05_DropDb) { + { + SDropDbMsg* pReq = (SDropDbMsg*)rpcMallocCont(sizeof(SAlterDbMsg)); + strcpy(pReq->db, "1.d1"); + + SRpcMsg rpcMsg = {0}; + rpcMsg.pCont = pReq; + rpcMsg.contLen = sizeof(SDropDbMsg); + rpcMsg.msgType = TSDB_MSG_TYPE_DROP_DB; + + sendMsg(pClient, &rpcMsg); + SRpcMsg* pMsg = pClient->pRsp; + ASSERT_NE(pMsg, nullptr); + ASSERT_EQ(pMsg->code, 0); + } + + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DB, "show databases", 16); + SendThenCheckShowRetrieveMsg(0); +} \ No newline at end of file diff --git a/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt b/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt index e118cb8725..ebe2f3c5eb 100644 --- a/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/dnode/CMakeLists.txt @@ -1,20 +1,20 @@ -add_executable(dndTestDnode "") +add_executable(dnode_test_dnode "") -target_sources(dndTestDnode +target_sources(dnode_test_dnode PRIVATE "dnode.cpp" "../sut/deploy.cpp" ) target_link_libraries( - dndTestDnode + dnode_test_dnode PUBLIC dnode PUBLIC util PUBLIC os PUBLIC gtest_main ) -target_include_directories(dndTestDnode +target_include_directories(dnode_test_dnode PUBLIC "${CMAKE_SOURCE_DIR}/include/server/dnode/mgmt" "${CMAKE_CURRENT_SOURCE_DIR}/../../inc" @@ -24,6 +24,6 @@ target_include_directories(dndTestDnode enable_testing() add_test( - NAME dndTestDnode - COMMAND dndTestDnode + NAME dnode_test_dnode + COMMAND dnode_test_dnode ) diff --git a/source/dnode/mgmt/impl/test/dnode/dnode.cpp b/source/dnode/mgmt/impl/test/dnode/dnode.cpp index fba3794f6a..5a4512e16c 100644 --- a/source/dnode/mgmt/impl/test/dnode/dnode.cpp +++ b/source/dnode/mgmt/impl/test/dnode/dnode.cpp @@ -24,16 +24,16 @@ class DndTestDnode : public ::testing::Test { } static void SetUpTestSuite() { - initLog("/tmp/dndTestDnode"); + initLog("/tmp/tdlog"); const char* fqdn = "localhost"; - const char* firstEp = "localhost:9521"; - pServer1 = CreateServer("/tmp/dndTestDnode1", fqdn, 9521, firstEp); - pServer2 = CreateServer("/tmp/dndTestDnode2", fqdn, 9522, firstEp); - pServer3 = CreateServer("/tmp/dndTestDnode3", fqdn, 9523, firstEp); - pServer4 = CreateServer("/tmp/dndTestDnode4", fqdn, 9524, firstEp); - pServer5 = CreateServer("/tmp/dndTestDnode5", fqdn, 9525, firstEp); - pClient = createClient("root", "taosdata", fqdn, 9521); + const char* firstEp = "localhost:9041"; + pServer1 = CreateServer("/tmp/dnode_test_dnode1", fqdn, 9041, firstEp); + pServer2 = CreateServer("/tmp/dnode_test_dnode2", fqdn, 9042, firstEp); + pServer3 = CreateServer("/tmp/dnode_test_dnode3", fqdn, 9043, firstEp); + pServer4 = CreateServer("/tmp/dnode_test_dnode4", fqdn, 9044, firstEp); + pServer5 = CreateServer("/tmp/dnode_test_dnode5", fqdn, 9045, firstEp); + pClient = createClient("root", "taosdata", fqdn, 9041); taosMsleep(300); } @@ -188,7 +188,7 @@ SServer* DndTestDnode::pServer4; SServer* DndTestDnode::pServer5; SClient* DndTestDnode::pClient; -TEST_F(DndTestDnode, ShowDnode) { +TEST_F(DndTestDnode, 01_ShowDnode) { SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7); CheckSchema(0, TSDB_DATA_TYPE_SMALLINT, 2, "id"); CheckSchema(1, TSDB_DATA_TYPE_BINARY, TSDB_EP_LEN + VARSTR_HEADER_SIZE, "end point"); @@ -200,7 +200,7 @@ TEST_F(DndTestDnode, ShowDnode) { SendThenCheckShowRetrieveMsg(1); CheckInt16(1); - CheckBinary("localhost:9521", TSDB_EP_LEN); + CheckBinary("localhost:9041", TSDB_EP_LEN); CheckInt16(0); CheckInt16(1); CheckBinary("ready", 10); @@ -208,7 +208,7 @@ TEST_F(DndTestDnode, ShowDnode) { CheckBinary("", 24); } -TEST_F(DndTestDnode, ConfigDnode_01) { +TEST_F(DndTestDnode, 02_ConfigDnode) { SCfgDnodeMsg* pReq = (SCfgDnodeMsg*)rpcMallocCont(sizeof(SCfgDnodeMsg)); pReq->dnodeId = htonl(1); strcpy(pReq->config, "ddebugflag 131"); @@ -224,9 +224,9 @@ TEST_F(DndTestDnode, ConfigDnode_01) { ASSERT_EQ(pMsg->code, 0); } -TEST_F(DndTestDnode, CreateDnode_01) { +TEST_F(DndTestDnode, 03_CreateDnode) { SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg)); - strcpy(pReq->ep, "localhost:9522"); + strcpy(pReq->ep, "localhost:9042"); SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; @@ -243,8 +243,8 @@ TEST_F(DndTestDnode, CreateDnode_01) { SendThenCheckShowRetrieveMsg(2); CheckInt16(1); CheckInt16(2); - CheckBinary("localhost:9521", TSDB_EP_LEN); - CheckBinary("localhost:9522", TSDB_EP_LEN); + CheckBinary("localhost:9041", TSDB_EP_LEN); + CheckBinary("localhost:9042", TSDB_EP_LEN); CheckInt16(0); CheckInt16(0); CheckInt16(1); @@ -257,7 +257,7 @@ TEST_F(DndTestDnode, CreateDnode_01) { CheckBinary("", 24); } -TEST_F(DndTestDnode, DropDnode_01) { +TEST_F(DndTestDnode, 04_DropDnode) { SDropDnodeMsg* pReq = (SDropDnodeMsg*)rpcMallocCont(sizeof(SDropDnodeMsg)); pReq->dnodeId = htonl(2); @@ -274,7 +274,7 @@ TEST_F(DndTestDnode, DropDnode_01) { SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7); SendThenCheckShowRetrieveMsg(1); CheckInt16(1); - CheckBinary("localhost:9521", TSDB_EP_LEN); + CheckBinary("localhost:9041", TSDB_EP_LEN); CheckInt16(0); CheckInt16(1); CheckBinary("ready", 10); @@ -282,10 +282,10 @@ TEST_F(DndTestDnode, DropDnode_01) { CheckBinary("", 24); } -TEST_F(DndTestDnode, CreateDnode_02) { +TEST_F(DndTestDnode, 05_CreateDnode) { { SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg)); - strcpy(pReq->ep, "localhost:9523"); + strcpy(pReq->ep, "localhost:9043"); SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; @@ -300,7 +300,7 @@ TEST_F(DndTestDnode, CreateDnode_02) { { SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg)); - strcpy(pReq->ep, "localhost:9524"); + strcpy(pReq->ep, "localhost:9044"); SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; @@ -315,7 +315,7 @@ TEST_F(DndTestDnode, CreateDnode_02) { { SCreateDnodeMsg* pReq = (SCreateDnodeMsg*)rpcMallocCont(sizeof(SCreateDnodeMsg)); - strcpy(pReq->ep, "localhost:9525"); + strcpy(pReq->ep, "localhost:9045"); SRpcMsg rpcMsg = {0}; rpcMsg.pCont = pReq; @@ -335,10 +335,10 @@ TEST_F(DndTestDnode, CreateDnode_02) { CheckInt16(3); CheckInt16(4); CheckInt16(5); - CheckBinary("localhost:9521", TSDB_EP_LEN); - CheckBinary("localhost:9523", TSDB_EP_LEN); - CheckBinary("localhost:9524", TSDB_EP_LEN); - CheckBinary("localhost:9525", TSDB_EP_LEN); + CheckBinary("localhost:9041", TSDB_EP_LEN); + CheckBinary("localhost:9043", TSDB_EP_LEN); + CheckBinary("localhost:9044", TSDB_EP_LEN); + CheckBinary("localhost:9045", TSDB_EP_LEN); CheckInt16(0); CheckInt16(0); CheckInt16(0); @@ -361,7 +361,7 @@ TEST_F(DndTestDnode, CreateDnode_02) { CheckBinary("", 24); } -TEST_F(DndTestDnode, RestartDnode_01) { +TEST_F(DndTestDnode, 06_RestartDnode) { uInfo("stop all server"); stopServer(pServer1); stopServer(pServer2); @@ -377,43 +377,43 @@ TEST_F(DndTestDnode, RestartDnode_01) { uInfo("start all server"); const char* fqdn = "localhost"; - const char* firstEp = "localhost:9521"; - pServer1 = startServer("/tmp/dndTestDnode1", fqdn, 9521, firstEp); - // pServer1 = startServer("/tmp/dndTestDnode3", fqdn, 9523, firstEp); - // pServer1 = startServer("/tmp/dndTestDnode4", fqdn, 9524, firstEp); - // pServer1 = startServer("/tmp/dndTestDnode5", fqdn, 9525, firstEp); + const char* firstEp = "localhost:9041"; + pServer1 = startServer("/tmp/dnode_test_dnode1", fqdn, 9041, firstEp); + pServer3 = startServer("/tmp/dnode_test_dnode3", fqdn, 9043, firstEp); + pServer4 = startServer("/tmp/dnode_test_dnode4", fqdn, 9044, firstEp); + pServer5 = startServer("/tmp/dnode_test_dnode5", fqdn, 9045, firstEp); uInfo("all server is running"); - // taosMsleep(1300); - // SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7); - // SendThenCheckShowRetrieveMsg(4); - // CheckInt16(1); - // CheckInt16(3); - // CheckInt16(4); - // CheckInt16(5); - // CheckBinary("localhost:9521", TSDB_EP_LEN); - // CheckBinary("localhost:9523", TSDB_EP_LEN); - // CheckBinary("localhost:9524", TSDB_EP_LEN); - // CheckBinary("localhost:9525", TSDB_EP_LEN); - // CheckInt16(0); - // CheckInt16(0); - // CheckInt16(0); - // CheckInt16(0); - // CheckInt16(1); - // CheckInt16(1); - // CheckInt16(1); - // CheckInt16(1); - // CheckBinary("ready", 10); - // CheckBinary("ready", 10); - // CheckBinary("ready", 10); - // CheckBinary("ready", 10); - // CheckTimestamp(); - // CheckTimestamp(); - // CheckTimestamp(); - // CheckTimestamp(); - // CheckBinary("", 24); - // CheckBinary("", 24); - // CheckBinary("", 24); - // CheckBinary("", 24); + taosMsleep(1300); + SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_DNODE, "show dnodes", 7); + SendThenCheckShowRetrieveMsg(4); + CheckInt16(1); + CheckInt16(3); + CheckInt16(4); + CheckInt16(5); + CheckBinary("localhost:9041", TSDB_EP_LEN); + CheckBinary("localhost:9043", TSDB_EP_LEN); + CheckBinary("localhost:9044", TSDB_EP_LEN); + CheckBinary("localhost:9045", TSDB_EP_LEN); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(0); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckInt16(1); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckBinary("ready", 10); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckTimestamp(); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); + CheckBinary("", 24); } diff --git a/source/dnode/mgmt/impl/test/sut/deploy.cpp b/source/dnode/mgmt/impl/test/sut/deploy.cpp index de50899c2d..f2010b5813 100644 --- a/source/dnode/mgmt/impl/test/sut/deploy.cpp +++ b/source/dnode/mgmt/impl/test/sut/deploy.cpp @@ -18,14 +18,10 @@ void initLog(const char* path) { dDebugFlag = 143; vDebugFlag = 0; - mDebugFlag = 143; + mDebugFlag = 207; cDebugFlag = 0; jniDebugFlag = 0; tmrDebugFlag = 0; - sdbDebugFlag = 0; - httpDebugFlag = 0; - mqttDebugFlag = 0; - monDebugFlag = 0; uDebugFlag = 143; rpcDebugFlag = 0; odbcDebugFlag = 0; diff --git a/source/dnode/mgmt/impl/test/user/CMakeLists.txt b/source/dnode/mgmt/impl/test/user/CMakeLists.txt index b5f02e41f4..ca8f2ec6db 100644 --- a/source/dnode/mgmt/impl/test/user/CMakeLists.txt +++ b/source/dnode/mgmt/impl/test/user/CMakeLists.txt @@ -1,20 +1,20 @@ -add_executable(dndTestUser "") +add_executable(dnode_test_user "") -target_sources(dndTestUser +target_sources(dnode_test_user PRIVATE "user.cpp" "../sut/deploy.cpp" ) target_link_libraries( - dndTestUser + dnode_test_user PUBLIC dnode PUBLIC util PUBLIC os PUBLIC gtest_main ) -target_include_directories(dndTestUser +target_include_directories(dnode_test_user PUBLIC "${CMAKE_SOURCE_DIR}/include/server/dnode/mgmt" "${CMAKE_CURRENT_SOURCE_DIR}/../../inc" @@ -24,6 +24,6 @@ target_include_directories(dndTestUser enable_testing() add_test( - NAME dndTestUser - COMMAND dndTestUser + NAME dnode_test_user + COMMAND dnode_test_user ) diff --git a/source/dnode/mgmt/impl/test/user/user.cpp b/source/dnode/mgmt/impl/test/user/user.cpp index 48be2635cd..2b30dcbb1b 100644 --- a/source/dnode/mgmt/impl/test/user/user.cpp +++ b/source/dnode/mgmt/impl/test/user/user.cpp @@ -24,12 +24,12 @@ class DndTestUser : public ::testing::Test { } static void SetUpTestSuite() { - initLog("/tmp/dndTestUser"); + initLog("/tmp/tdlog"); const char* fqdn = "localhost"; - const char* firstEp = "localhost:9530"; - pServer = CreateServer("/tmp/dndTestUser", fqdn, 9530, firstEp); - pClient = createClient("root", "taosdata", fqdn, 9530); + const char* firstEp = "localhost:9140"; + pServer = CreateServer("/tmp/dnode_test_user", fqdn, 9140, firstEp); + pClient = createClient("root", "taosdata", fqdn, 9140); taosMsleep(300); } @@ -170,7 +170,7 @@ SServer* DndTestUser::pServer; SClient* DndTestUser::pClient; int32_t DndTestUser::connId; -TEST_F(DndTestUser, ShowUser) { +TEST_F(DndTestUser, 01_ShowUser) { SendTheCheckShowMetaMsg(TSDB_MGMT_TABLE_USER, "show users", 4); CheckSchema(0, TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN + VARSTR_HEADER_SIZE, "name"); CheckSchema(1, TSDB_DATA_TYPE_BINARY, 10 + VARSTR_HEADER_SIZE, "privilege"); @@ -184,7 +184,7 @@ TEST_F(DndTestUser, ShowUser) { CheckBinary("root", TSDB_USER_LEN); } -TEST_F(DndTestUser, CreateUser_01) { +TEST_F(DndTestUser, 02_CreateUser) { { SCreateUserMsg* pReq = (SCreateUserMsg*)rpcMallocCont(sizeof(SCreateUserMsg)); strcpy(pReq->user, "u1"); @@ -233,7 +233,7 @@ TEST_F(DndTestUser, CreateUser_01) { CheckBinary("root", TSDB_USER_LEN); } -TEST_F(DndTestUser, AlterUser_01) { +TEST_F(DndTestUser, 03_AlterUser) { SAlterUserMsg* pReq = (SAlterUserMsg*)rpcMallocCont(sizeof(SAlterUserMsg)); strcpy(pReq->user, "u1"); strcpy(pReq->pass, "p2"); @@ -264,7 +264,7 @@ TEST_F(DndTestUser, AlterUser_01) { CheckBinary("root", TSDB_USER_LEN); } -TEST_F(DndTestUser, DropUser_01) { +TEST_F(DndTestUser, 04_DropUser) { SDropUserMsg* pReq = (SDropUserMsg*)rpcMallocCont(sizeof(SDropUserMsg)); strcpy(pReq->user, "u1"); @@ -290,15 +290,15 @@ TEST_F(DndTestUser, DropUser_01) { CheckBinary("root", TSDB_USER_LEN); } -TEST_F(DndTestUser, RestartDnode) { +TEST_F(DndTestUser, 05_RestartDnode) { stopServer(pServer); pServer = NULL; uInfo("start all server"); const char* fqdn = "localhost"; - const char* firstEp = "localhost:9530"; - pServer = startServer("/tmp/dndTestUser", fqdn, 9530, firstEp); + const char* firstEp = "localhost:9140"; + pServer = startServer("/tmp/dnode_test_user", fqdn, 9140, firstEp); uInfo("all server is running"); diff --git a/source/dnode/mnode/impl/inc/mndDef.h b/source/dnode/mnode/impl/inc/mndDef.h index 5ddde3181e..115d896da2 100644 --- a/source/dnode/mnode/impl/inc/mndDef.h +++ b/source/dnode/mnode/impl/inc/mndDef.h @@ -17,14 +17,16 @@ #define _TD_MND_DEF_H_ #include "os.h" + +#include "cJSON.h" +#include "sync.h" #include "taosmsg.h" +#include "thash.h" #include "tlog.h" #include "trpc.h" #include "ttimer.h" -#include "thash.h" -#include "cJSON.h" + #include "mnode.h" -#include "sync.h" #ifdef __cplusplus extern "C" { @@ -41,11 +43,8 @@ extern int32_t mDebugFlag; #define mTrace(...) { if (mDebugFlag & DEBUG_TRACE) { taosPrintLog("MND ", mDebugFlag, __VA_ARGS__); }} typedef struct SClusterObj SClusterObj; -typedef struct SDnodeObj SDnodeObj; typedef struct SMnodeObj SMnodeObj; typedef struct SAcctObj SAcctObj; -typedef struct SUserObj SUserObj; -typedef struct SDbObj SDbObj; typedef struct SVgObj SVgObj; typedef struct SFuncObj SFuncObj; typedef struct SOperObj SOperObj; @@ -73,7 +72,8 @@ typedef enum { TRN_STAGE_EXECUTE = 2, TRN_STAGE_COMMIT = 3, TRN_STAGE_ROLLBACK = 4, - TRN_STAGE_RETRY = 5 + TRN_STAGE_RETRY = 5, + TRN_STAGE_OVER = 6, } ETrnStage; typedef enum { TRN_POLICY_ROLLBACK = 1, TRN_POLICY_RETRY = 2 } ETrnPolicy; @@ -103,7 +103,6 @@ typedef struct STrans { int32_t id; ETrnStage stage; ETrnPolicy policy; - SMnode *pMnode; void *rpcHandle; SArray *redoLogs; SArray *undoLogs; @@ -119,7 +118,7 @@ typedef struct SClusterObj { int64_t updateTime; } SClusterObj; -typedef struct SDnodeObj { +typedef struct { int32_t id; int64_t createdTime; int64_t updateTime; @@ -178,7 +177,7 @@ typedef struct SAcctObj { SAcctInfo info; } SAcctObj; -typedef struct SUserObj { +typedef struct { char user[TSDB_USER_LEN]; char pass[TSDB_PASSWORD_LEN]; char acct[TSDB_USER_LEN]; @@ -209,12 +208,13 @@ typedef struct { int8_t cacheLastRow; } SDbCfg; -typedef struct SDbObj { +typedef struct { char name[TSDB_FULL_DB_NAME_LEN]; char acct[TSDB_USER_LEN]; int64_t createdTime; int64_t updateTime; int64_t uid; + int32_t version; SDbCfg cfg; } SDbObj; @@ -304,6 +304,7 @@ typedef struct SMnodeMsg { typedef struct { int32_t id; + int32_t code; void *rpcHandle; } STransMsg; diff --git a/source/dnode/mnode/impl/inc/mndShow.h b/source/dnode/mnode/impl/inc/mndShow.h index 37fb9159dc..67e277677c 100644 --- a/source/dnode/mnode/impl/inc/mndShow.h +++ b/source/dnode/mnode/impl/inc/mndShow.h @@ -27,7 +27,7 @@ void mndCleanupShow(SMnode *pMnode); void mndAddShowMetaHandle(SMnode *pMnode, EShowType showType, ShowMetaFp fp); void mndAddShowRetrieveHandle(SMnode *pMnode, EShowType showType, ShowRetrieveFp fp); void mndAddShowFreeIterHandle(SMnode *pMnode, EShowType msgType, ShowFreeIterFp fp); -void mnodeVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow); +void mndVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow); char *mndShowStr(int32_t showType); #ifdef __cplusplus diff --git a/source/dnode/mnode/impl/inc/mndSync.h b/source/dnode/mnode/impl/inc/mndSync.h index 02ba725be1..fe557cdeac 100644 --- a/source/dnode/mnode/impl/inc/mndSync.h +++ b/source/dnode/mnode/impl/inc/mndSync.h @@ -25,7 +25,7 @@ extern "C" { int32_t mndInitSync(SMnode *pMnode); void mndCleanupSync(SMnode *pMnode); bool mndIsMaster(SMnode *pMnode); -int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, STransMsg *pMsg); +int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/inc/mndTrans.h b/source/dnode/mnode/impl/inc/mndTrans.h index 878337e4be..5da1d1ca2b 100644 --- a/source/dnode/mnode/impl/inc/mndTrans.h +++ b/source/dnode/mnode/impl/inc/mndTrans.h @@ -32,10 +32,10 @@ int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw); int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw); int32_t mndTransAppendRedoAction(STrans *pTrans, SEpSet *, void *pMsg); int32_t mndTransAppendUndoAction(STrans *pTrans, SEpSet *, void *pMsg); - -int32_t mndTransPrepare(STrans *pTrans); +int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans); void mndTransApply(SMnode *pMnode, SSdbRaw *pRaw, STransMsg *pMsg, int32_t code); -int32_t mndTransExecute(SSdb *pSdb, int32_t tranId); +char *mndTransStageStr(ETrnStage stage); +char *mndTransPolicyStr(ETrnPolicy policy); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndAcct.c b/source/dnode/mnode/impl/src/mndAcct.c index a365ad7326..75b0acbd0a 100644 --- a/source/dnode/mnode/impl/src/mndAcct.c +++ b/source/dnode/mnode/impl/src/mndAcct.c @@ -19,12 +19,12 @@ #define SDB_ACCT_VER 1 -static int32_t mnodeCreateDefaultAcct(SMnode *pMnode); -static SSdbRaw *mnodeAcctActionEncode(SAcctObj *pAcct); -static SSdbRow *mnodeAcctActionDecode(SSdbRaw *pRaw); -static int32_t mnodeAcctActionInsert(SSdb *pSdb, SAcctObj *pAcct); -static int32_t mnodeAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct); -static int32_t mnodeAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct); +static int32_t mndCreateDefaultAcct(SMnode *pMnode); +static SSdbRaw *mndAcctActionEncode(SAcctObj *pAcct); +static SSdbRow *mndAcctActionDecode(SSdbRaw *pRaw); +static int32_t mndAcctActionInsert(SSdb *pSdb, SAcctObj *pAcct); +static int32_t mndAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct); +static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct); static int32_t mndProcessCreateAcctMsg(SMnodeMsg *pMnodeMsg); static int32_t mndProcessAlterAcctMsg(SMnodeMsg *pMnodeMsg); static int32_t mndProcessDropAcctMsg(SMnodeMsg *pMnodeMsg); @@ -32,12 +32,12 @@ static int32_t mndProcessDropAcctMsg(SMnodeMsg *pMnodeMsg); int32_t mndInitAcct(SMnode *pMnode) { SSdbTable table = {.sdbType = SDB_ACCT, .keyType = SDB_KEY_BINARY, - .deployFp = mnodeCreateDefaultAcct, - .encodeFp = (SdbEncodeFp)mnodeAcctActionEncode, - .decodeFp = (SdbDecodeFp)mnodeAcctActionDecode, - .insertFp = (SdbInsertFp)mnodeAcctActionInsert, - .updateFp = (SdbUpdateFp)mnodeAcctActionUpdate, - .deleteFp = (SdbDeleteFp)mnodeAcctActionDelete}; + .deployFp = mndCreateDefaultAcct, + .encodeFp = (SdbEncodeFp)mndAcctActionEncode, + .decodeFp = (SdbDecodeFp)mndAcctActionDecode, + .insertFp = (SdbInsertFp)mndAcctActionInsert, + .updateFp = (SdbUpdateFp)mndAcctActionUpdate, + .deleteFp = (SdbDeleteFp)mndAcctActionDelete}; mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_CREATE_ACCT, mndProcessCreateAcctMsg); mndSetMsgHandle(pMnode, TSDB_MSG_TYPE_ALTER_ACCT, mndProcessAlterAcctMsg); @@ -48,7 +48,7 @@ int32_t mndInitAcct(SMnode *pMnode) { void mndCleanupAcct(SMnode *pMnode) {} -static int32_t mnodeCreateDefaultAcct(SMnode *pMnode) { +static int32_t mndCreateDefaultAcct(SMnode *pMnode) { SAcctObj acctObj = {0}; tstrncpy(acctObj.acct, TSDB_DEFAULT_USER, TSDB_USER_LEN); acctObj.createdTime = taosGetTimestampMs(); @@ -61,7 +61,7 @@ static int32_t mnodeCreateDefaultAcct(SMnode *pMnode) { .maxStorage = INT64_MAX, .accessState = TSDB_VN_ALL_ACCCESS}; - SSdbRaw *pRaw = mnodeAcctActionEncode(&acctObj); + SSdbRaw *pRaw = mndAcctActionEncode(&acctObj); if (pRaw == NULL) return -1; sdbSetRawStatus(pRaw, SDB_STATUS_READY); @@ -69,7 +69,7 @@ static int32_t mnodeCreateDefaultAcct(SMnode *pMnode) { return sdbWrite(pMnode->pSdb, pRaw); } -static SSdbRaw *mnodeAcctActionEncode(SAcctObj *pAcct) { +static SSdbRaw *mndAcctActionEncode(SAcctObj *pAcct) { SSdbRaw *pRaw = sdbAllocRaw(SDB_ACCT, SDB_ACCT_VER, sizeof(SAcctObj)); if (pRaw == NULL) return NULL; @@ -90,7 +90,7 @@ static SSdbRaw *mnodeAcctActionEncode(SAcctObj *pAcct) { return pRaw; } -static SSdbRow *mnodeAcctActionDecode(SSdbRaw *pRaw) { +static SSdbRow *mndAcctActionDecode(SSdbRaw *pRaw) { int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL; @@ -120,18 +120,18 @@ static SSdbRow *mnodeAcctActionDecode(SSdbRaw *pRaw) { return pRow; } -static int32_t mnodeAcctActionInsert(SSdb *pSdb, SAcctObj *pAcct) { +static int32_t mndAcctActionInsert(SSdb *pSdb, SAcctObj *pAcct) { mTrace("acct:%s, perform insert action", pAcct->acct); memset(&pAcct->info, 0, sizeof(SAcctInfo)); return 0; } -static int32_t mnodeAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct) { +static int32_t mndAcctActionDelete(SSdb *pSdb, SAcctObj *pAcct) { mTrace("acct:%s, perform delete action", pAcct->acct); return 0; } -static int32_t mnodeAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct) { +static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOldAcct, SAcctObj *pNewAcct) { mTrace("acct:%s, perform update action", pOldAcct->acct); memcpy(pOldAcct->acct, pNewAcct->acct, TSDB_USER_LEN); diff --git a/source/dnode/mnode/impl/src/mndCluster.c b/source/dnode/mnode/impl/src/mndCluster.c index 7edeb73647..0eaa184907 100644 --- a/source/dnode/mnode/impl/src/mndCluster.c +++ b/source/dnode/mnode/impl/src/mndCluster.c @@ -203,7 +203,7 @@ static int32_t mndRetrieveClusters(SMnodeMsg *pMsg, SShowObj *pShow, char *data, numOfRows++; } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index fd02c6e251..9f2b2d17f3 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -65,7 +65,7 @@ int32_t mndInitDb(SMnode *pMnode) { void mndCleanupDb(SMnode *pMnode) {} static SSdbRaw *mndDbActionEncode(SDbObj *pDb) { - SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_DB_VER_NUM, sizeof(SDbObj)); + SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_DB_VER_NUM, sizeof(SDbObj) + TSDB_DB_RESERVE_SIZE); if (pRaw == NULL) return NULL; int32_t dataPos = 0; @@ -74,6 +74,7 @@ static SSdbRaw *mndDbActionEncode(SDbObj *pDb) { SDB_SET_INT64(pRaw, dataPos, pDb->createdTime) SDB_SET_INT64(pRaw, dataPos, pDb->updateTime) SDB_SET_INT64(pRaw, dataPos, pDb->uid) + SDB_SET_INT32(pRaw, dataPos, pDb->version) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.cacheBlockSize) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.totalBlocks) SDB_SET_INT32(pRaw, dataPos, pDb->cfg.daysPerFile) @@ -117,6 +118,7 @@ static SSdbRow *mndDbActionDecode(SSdbRaw *pRaw) { SDB_GET_INT64(pRaw, pRow, dataPos, &pDb->createdTime) SDB_GET_INT64(pRaw, pRow, dataPos, &pDb->updateTime) SDB_GET_INT64(pRaw, pRow, dataPos, &pDb->uid) + SDB_GET_INT32(pRaw, pRow, dataPos, &pDb->version) SDB_GET_INT32(pRaw, pRow, dataPos, &pDb->cfg.cacheBlockSize) SDB_GET_INT32(pRaw, pRow, dataPos, &pDb->cfg.totalBlocks) SDB_GET_INT32(pRaw, pRow, dataPos, &pDb->cfg.daysPerFile) @@ -151,7 +153,8 @@ static int32_t mndDbActionDelete(SSdb *pSdb, SDbObj *pDb) { static int32_t mndDbActionUpdate(SSdb *pSdb, SDbObj *pOldDb, SDbObj *pNewDb) { mTrace("db:%s, perform update action", pOldDb->name); - memcpy(pOldDb, pNewDb, sizeof(SDbObj)); + pOldDb->updateTime = pNewDb->createdTime; + memcpy(&pOldDb->cfg, &pNewDb->cfg, sizeof(SDbCfg)); return 0; } @@ -165,109 +168,146 @@ void mndReleaseDb(SMnode *pMnode, SDbObj *pDb) { sdbRelease(pSdb, pDb); } -static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg) { +static int32_t mndCheckDbName(char *dbName, SUserObj *pUser) { + char *pos = strstr(dbName, TS_PATH_DELIMITER); + if (pos == NULL) { + terrno = TSDB_CODE_MND_INVALID_DB; + return -1; + } + + int32_t acctId = atoi(dbName); + if (acctId != pUser->acctId) { + terrno = TSDB_CODE_MND_INVALID_DB_ACCT; + return -1; + } + + return 0; +} + +static int32_t mndCheckDbCfg(SMnode *pMnode, SDbCfg *pCfg, char *errMsg, int32_t len) { if (pCfg->cacheBlockSize < TSDB_MIN_CACHE_BLOCK_SIZE || pCfg->cacheBlockSize > TSDB_MAX_CACHE_BLOCK_SIZE) { - terrno = TSDB_CODE_MND_INVALID_DB_CACHE_SIZE; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database cache block size option", len); return -1; } if (pCfg->totalBlocks < TSDB_MIN_TOTAL_BLOCKS || pCfg->totalBlocks > TSDB_MAX_TOTAL_BLOCKS) { - terrno = TSDB_CODE_MND_INVALID_DB_TOTAL_BLOCKS; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database total blocks option", len); return -1; } if (pCfg->daysPerFile < TSDB_MIN_DAYS_PER_FILE || pCfg->daysPerFile > TSDB_MAX_DAYS_PER_FILE) { - terrno = TSDB_CODE_MND_INVALID_DB_DAYS; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database days option", len); return -1; } if (pCfg->daysToKeep0 < pCfg->daysPerFile) { - terrno = TSDB_CODE_MND_INVALID_DB_KEEP0; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database days option", len); return -1; } if (pCfg->daysToKeep0 < TSDB_MIN_KEEP || pCfg->daysToKeep0 > TSDB_MAX_KEEP || pCfg->daysToKeep0 > pCfg->daysToKeep1) { - terrno = TSDB_CODE_MND_INVALID_DB_KEEP0; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database keep0 option", len); return -1; } if (pCfg->daysToKeep1 < TSDB_MIN_KEEP || pCfg->daysToKeep1 > TSDB_MAX_KEEP || pCfg->daysToKeep1 > pCfg->daysToKeep2) { - terrno = TSDB_CODE_MND_INVALID_DB_KEEP1; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database keep1 option", len); return -1; } if (pCfg->daysToKeep2 < TSDB_MIN_KEEP || pCfg->daysToKeep2 > TSDB_MAX_KEEP) { - terrno = TSDB_CODE_MND_INVALID_DB_KEEP1; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database keep2 option", len); return -1; } if (pCfg->minRowsPerFileBlock < TSDB_MIN_MIN_ROW_FBLOCK || pCfg->minRowsPerFileBlock > TSDB_MAX_MIN_ROW_FBLOCK) { - terrno = TSDB_CODE_MND_INVALID_DB_MIN_ROWS; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database minrows option", len); return -1; } if (pCfg->maxRowsPerFileBlock < TSDB_MIN_MAX_ROW_FBLOCK || pCfg->maxRowsPerFileBlock > TSDB_MAX_MAX_ROW_FBLOCK) { - terrno = TSDB_CODE_MND_INVALID_DB_MAX_ROWS; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database maxrows option", len); return -1; } if (pCfg->minRowsPerFileBlock > pCfg->maxRowsPerFileBlock) { - terrno = TSDB_CODE_MND_INVALID_DB_MIN_ROWS; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database minrows option", len); return -1; } if (pCfg->commitTime < TSDB_MIN_COMMIT_TIME || pCfg->commitTime > TSDB_MAX_COMMIT_TIME) { - terrno = TSDB_CODE_MND_INVALID_DB_COMMIT_TIME; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database commit option", len); return -1; } if (pCfg->fsyncPeriod < TSDB_MIN_FSYNC_PERIOD || pCfg->fsyncPeriod > TSDB_MAX_FSYNC_PERIOD) { - terrno = TSDB_CODE_MND_INVALID_DB_FSYNC_PERIOD; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database fsync option", len); return -1; } if (pCfg->walLevel < TSDB_MIN_WAL_LEVEL || pCfg->walLevel > TSDB_MAX_WAL_LEVEL) { - terrno = TSDB_CODE_MND_INVALID_DB_WAL_LEVEL; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database wal level option", len); return -1; } if (pCfg->precision < TSDB_MIN_PRECISION && pCfg->precision > TSDB_MAX_PRECISION) { - terrno = TSDB_CODE_MND_INVALID_DB_PRECISION; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid precision option", len); return -1; } if (pCfg->compression < TSDB_MIN_COMP_LEVEL || pCfg->compression > TSDB_MAX_COMP_LEVEL) { - terrno = TSDB_CODE_MND_INVALID_DB_COMP; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database compression option", len); return -1; } if (pCfg->replications < TSDB_MIN_DB_REPLICA_OPTION || pCfg->replications > TSDB_MAX_DB_REPLICA_OPTION) { - terrno = TSDB_CODE_MND_INVALID_DB_REPLICA; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database replication option", len); return -1; } if (pCfg->replications > mndGetDnodeSize(pMnode)) { - terrno = TSDB_CODE_MND_INVALID_DB_REPLICA; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database replication option", len); return -1; } if (pCfg->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCfg->quorum > TSDB_MAX_DB_QUORUM_OPTION) { - terrno = TSDB_CODE_MND_INVALID_DB_QUORUM; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database quorum option", len); return -1; } if (pCfg->quorum > pCfg->replications) { - terrno = TSDB_CODE_MND_INVALID_DB_QUORUM; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database quorum option", len); return -1; } if (pCfg->update < TSDB_MIN_DB_UPDATE || pCfg->update > TSDB_MAX_DB_UPDATE) { - terrno = TSDB_CODE_MND_INVALID_DB_UPDATE; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database update option", len); return -1; } if (pCfg->cacheLastRow < TSDB_MIN_DB_CACHE_LAST_ROW || pCfg->cacheLastRow > TSDB_MAX_DB_CACHE_LAST_ROW) { - terrno = TSDB_CODE_MND_INVALID_DB_CACHE_LAST; + terrno = TSDB_CODE_MND_INVALID_DB_OPTION; + tstrncpy(errMsg, "Invalid database cachelast option", len); return -1; } @@ -294,13 +334,13 @@ static void mndSetDefaultDbCfg(SDbCfg *pCfg) { if (pCfg->cacheLastRow < 0) pCfg->cacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW; } -static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreate, char *acct) { +static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreate, SUserObj *pUser) { SDbObj dbObj = {0}; tstrncpy(dbObj.name, pCreate->db, TSDB_FULL_DB_NAME_LEN); - tstrncpy(dbObj.acct, acct, TSDB_USER_LEN); + tstrncpy(dbObj.acct, pUser->acct, TSDB_USER_LEN); dbObj.createdTime = taosGetTimestampMs(); dbObj.updateTime = dbObj.createdTime; - dbObj.uid = 1234; + dbObj.uid = mndGenerateUid(dbObj.name, TSDB_FULL_DB_NAME_LEN); dbObj.cfg = (SDbCfg){.cacheBlockSize = pCreate->cacheBlockSize, .totalBlocks = pCreate->totalBlocks, .daysPerFile = pCreate->daysPerFile, @@ -321,7 +361,13 @@ static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreat mndSetDefaultDbCfg(&dbObj.cfg); - if (mndCheckDbCfg(pMnode, &dbObj.cfg) != 0) { + if (mndCheckDbName(dbObj.name, pUser) != 0) { + mError("db:%s, failed to create since %s", pCreate->db, terrstr()); + return -1; + } + + char errMsg[TSDB_ERROR_MSG_LEN] = {0}; + if (mndCheckDbCfg(pMnode, &dbObj.cfg, errMsg, TSDB_ERROR_MSG_LEN) != 0) { mError("db:%s, failed to create since %s", pCreate->db, terrstr()); return -1; } @@ -357,7 +403,7 @@ static int32_t mndCreateDb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDbMsg *pCreat } sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -403,11 +449,10 @@ static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg) { return -1; } - int32_t code = mndCreateDb(pMnode, pMsg, pCreate, pOperUser->acct); + int32_t code = mndCreateDb(pMnode, pMsg, pCreate, pOperUser); mndReleaseUser(pMnode, pOperUser); if (code != 0) { - terrno = code; mError("db:%s, failed to create since %s", pCreate->db, terrstr()); return -1; } @@ -415,7 +460,7 @@ static int32_t mndProcessCreateDbMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -static int32_t mnodeSetDbCfgFromAlterDbMsg(SDbObj *pDb, SAlterDbMsg *pAlter) { +static int32_t mndSetDbCfgFromAlterDbMsg(SDbObj *pDb, SAlterDbMsg *pAlter) { bool changed = false; if (pAlter->totalBlocks >= 0 && pAlter->totalBlocks != pDb->cfg.totalBlocks) { @@ -491,7 +536,7 @@ static int32_t mndUpdateDb(SMnode *pMnode, SMnodeMsg *pMsg, SDbObj *pOldDb, SDbO } sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -521,13 +566,14 @@ static int32_t mndProcessAlterDbMsg(SMnodeMsg *pMsg) { SDbObj dbObj = {0}; memcpy(&dbObj, pDb, sizeof(SDbObj)); - int32_t code = mnodeSetDbCfgFromAlterDbMsg(&dbObj, pAlter); + int32_t code = mndSetDbCfgFromAlterDbMsg(&dbObj, pAlter); if (code != 0) { mndReleaseDb(pMnode, pDb); mError("db:%s, failed to alter since %s", pAlter->db, tstrerror(code)); return code; } + dbObj.version++; code = mndUpdateDb(pMnode, pMsg, pDb, &dbObj); mndReleaseDb(pMnode, pDb); @@ -571,7 +617,7 @@ static int32_t mndDropDb(SMnode *pMnode, SMnodeMsg *pMsg, SDbObj *pDb) { } sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -603,7 +649,6 @@ static int32_t mndProcessDropDbMsg(SMnodeMsg *pMsg) { mndReleaseDb(pMnode, pDb); if (code != 0) { - terrno = code; mError("db:%s, failed to drop since %s", pDrop->db, terrstr()); return code; } @@ -772,10 +817,14 @@ static int32_t mndGetDbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pMe return 0; } -char *mnodeGetDbStr(char *src) { +char *mnGetDbStr(char *src) { char *pos = strstr(src, TS_PATH_DELIMITER); if (pos != NULL) ++pos; + if (pos == NULL) { + return src; + } + return pos; } @@ -794,7 +843,7 @@ static int32_t mndRetrieveDbs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int3 cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - char *name = mnodeGetDbStr(pDb->name); + char *name = mnGetDbStr(pDb->name); if (name != NULL) { STR_WITH_MAXSIZE_TO_VARSTR(pWrite, name, pShow->bytes[cols]); } else { @@ -887,7 +936,7 @@ static int32_t mndRetrieveDbs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int3 sdbRelease(pSdb, pDb); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index cf46d044ca..ec5f68a713 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -19,7 +19,7 @@ #include "mndShow.h" #include "mndTrans.h" #include "ttime.h" -#include "tutil.h" +#include "tep.h" #define TSDB_DNODE_VER 1 #define TSDB_DNODE_RESERVE_SIZE 64 @@ -27,8 +27,6 @@ #define TSDB_CONIIG_VALUE_LEN 48 #define TSDB_CONFIG_NUMBER 8 -static int32_t id = 2; - static const char *offlineReason[] = { "", "status msg timeout", @@ -110,7 +108,7 @@ static int32_t mndCreateDefaultDnode(SMnode *pMnode) { } static SSdbRaw *mndDnodeActionEncode(SDnodeObj *pDnode) { - SSdbRaw *pRaw = sdbAllocRaw(SDB_DNODE, TSDB_DNODE_VER, sizeof(SDnodeObj)); + SSdbRaw *pRaw = sdbAllocRaw(SDB_DNODE, TSDB_DNODE_VER, sizeof(SDnodeObj) + TSDB_DNODE_RESERVE_SIZE); if (pRaw == NULL) return NULL; int32_t dataPos = 0; @@ -177,6 +175,7 @@ static int32_t mndDnodeActionDelete(SSdb *pSdb, SDnodeObj *pDnode) { static int32_t mndDnodeActionUpdate(SSdb *pSdb, SDnodeObj *pOldDnode, SDnodeObj *pNewDnode) { mTrace("dnode:%d, perform update action", pOldDnode->id); + pOldDnode->updateTime = pNewDnode->updateTime; return 0; } @@ -389,7 +388,7 @@ static int32_t mndProcessStatusMsg(SMnodeMsg *pMsg) { static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg *pCreate) { SDnodeObj dnodeObj = {0}; - dnodeObj.id = id++; + dnodeObj.id = sdbGetMaxId(pMnode->pSdb, SDB_DNODE); dnodeObj.createdTime = taosGetTimestampMs(); dnodeObj.updateTime = dnodeObj.createdTime; taosGetFqdnPortFromEp(pCreate->ep, dnodeObj.fqdn, &dnodeObj.port); @@ -413,25 +412,9 @@ static int32_t mndCreateDnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateDnodeMsg * mndTransDrop(pTrans); return -1; } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING); + sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY); - SSdbRaw *pUndoRaw = mndDnodeActionEncode(&dnodeObj); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED); - - SSdbRaw *pCommitRaw = mndDnodeActionEncode(&dnodeObj); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -485,25 +468,9 @@ static int32_t mndDropDnode(SMnode *pMnode, SMnodeMsg *pMsg, SDnodeObj *pDnode) mndTransDrop(pTrans); return -1; } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING); + sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED); - SSdbRaw *pUndoRaw = mndDnodeActionEncode(pDnode); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - - SSdbRaw *pCommitRaw = mndDnodeActionEncode(pDnode); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -645,7 +612,7 @@ static int32_t mndRetrieveConfigs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, cols++; } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } @@ -767,7 +734,7 @@ static int32_t mndRetrieveDnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i sdbRelease(pSdb, pDnode); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; diff --git a/source/dnode/mnode/impl/src/mndFunc.c b/source/dnode/mnode/impl/src/mndFunc.c index e407b271fd..b7158bb094 100644 --- a/source/dnode/mnode/impl/src/mndFunc.c +++ b/source/dnode/mnode/impl/src/mndFunc.c @@ -183,7 +183,7 @@ static int32_t mndCreateFunc(SMnode *pMnode, SMnodeMsg *pMsg, SCreateFuncMsg *pC } sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -226,7 +226,7 @@ static int32_t mndDropFunc(SMnode *pMnode, SMnodeMsg *pMsg, SFuncObj *pFunc) { } sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -500,7 +500,7 @@ static int32_t mndRetrieveFuncs(SMnodeMsg *pMsg, SShowObj *pShow, char *data, in sdbRelease(pSdb, pFunc); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index 6278e3ffef..7b6804d43e 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -238,7 +238,7 @@ static int32_t mndCreateMnode(SMnode *pMnode, SMnodeMsg *pMsg, SCreateMnodeMsg * } sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -313,7 +313,7 @@ static int32_t mndDropMnode(SMnode *pMnode, SMnodeMsg *pMsg, SMnodeObj *pMnodeOb } sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -457,7 +457,7 @@ static int32_t mndRetrieveMnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i sdbRelease(pSdb, pMnodeObj); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; diff --git a/source/dnode/mnode/impl/src/mndProfile.c b/source/dnode/mnode/impl/src/mndProfile.c index 59d84e5760..45a63f2dc5 100644 --- a/source/dnode/mnode/impl/src/mndProfile.c +++ b/source/dnode/mnode/impl/src/mndProfile.c @@ -252,7 +252,7 @@ static int32_t mndProcessConnectMsg(SMnodeMsg *pMsg) { return 0; } -static int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pMsg) { +static int32_t mndSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pMsg) { pConn->numOfQueries = 0; pConn->numOfStreams = 0; int32_t numOfQueries = htonl(pMsg->numOfQueries); @@ -338,7 +338,7 @@ static int32_t mndProcessHeartBeatMsg(SMnodeMsg *pMsg) { return -1; } - mnodeSaveQueryStreamList(pConn, pReq); + mndSaveQueryStreamList(pConn, pReq); if (pConn->killed != 0) { pRsp->killConnection = 1; } diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index c2b2acfa0c..91a229956f 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -296,6 +296,8 @@ char *mndShowStr(int32_t showType) { return "show streamtables"; case TSDB_MGMT_TABLE_TP: return "show topics"; + case TSDB_MGMT_TABLE_FUNCTION: + return "show functions"; default: return "undefined"; } @@ -308,7 +310,7 @@ static bool mndCheckRetrieveFinished(SShowObj *pShow) { return false; } -void mnodeVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow) { +void mndVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow) { if (rows < capacity) { for (int32_t i = 0; i < numOfCols; ++i) { memmove(data + pShow->offset[i] * rows, data + pShow->offset[i] * capacity, pShow->bytes[i] * rows); diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index c3afbf37c8..791b6f5d12 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -69,7 +69,7 @@ int32_t mndInitStb(SMnode *pMnode) { void mndCleanupStb(SMnode *pMnode) {} static SSdbRaw *mndStbActionEncode(SStbObj *pStb) { - int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema); + int32_t size = sizeof(SStbObj) + (pStb->numOfColumns + pStb->numOfTags) * sizeof(SSchema) + TSDB_STB_RESERVE_SIZE; SSdbRaw *pRaw = sdbAllocRaw(SDB_STB, TSDB_STB_VER_NUM, size); if (pRaw == NULL) return NULL; @@ -285,7 +285,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SMnodeMsg *pMsg, SCreateStbMsg *pCre } sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -433,7 +433,7 @@ static int32_t mndDropStb(SMnode *pMnode, SMnodeMsg *pMsg, SStbObj *pStb) { } sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -605,7 +605,7 @@ static int32_t mndGetStbMeta(SMnodeMsg *pMsg, SShowObj *pShow, STableMetaMsg *pM return 0; } -static void mnodeExtractTableName(char *tableId, char *name) { +static void mndExtractTableName(char *tableId, char *name) { int pos = -1; int num = 0; for (pos = 0; tableId[pos] != 0; ++pos) { @@ -665,7 +665,7 @@ static int32_t mndRetrieveStb(SMnodeMsg *pMsg, SShowObj *pShow, char *data, int3 } pShow->numOfReads += numOfRows; - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); return numOfRows; } diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index 6e7ee662f8..59161b32f2 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -21,16 +21,16 @@ int32_t mndInitSync(SMnode *pMnode) { return 0; } void mndCleanupSync(SMnode *pMnode) {} -int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw, STransMsg *pMsg) { +int32_t mndSyncPropose(SMnode *pMnode, SSdbRaw *pRaw) { int32_t code = 0; - int32_t len = sdbGetRawTotalSize(pRaw); - SSdbRaw *pReceived = calloc(1, len); - memcpy(pReceived, pRaw, len); - mDebug("trans:%d, data:%p recv from sync, code:0x%x pMsg:%p", pMsg->id, pReceived, code & 0xFFFF, pMsg); + // int32_t len = sdbGetRawTotalSize(pRaw); + // SSdbRaw *pReceived = calloc(1, len); + // memcpy(pReceived, pRaw, len); + // mDebug("trans:%d, data:%p recv from sync, code:0x%x pMsg:%p", pMsg->id, pReceived, code & 0xFFFF, pMsg); - mndTransApply(pMnode, pReceived, pMsg, code); - return 0; + // mndTransApply(pMnode, pReceived, code); + return code; } bool mndIsMaster(SMnode *pMnode) { return true; } \ No newline at end of file diff --git a/source/dnode/mnode/impl/src/mndTrans.c b/source/dnode/mnode/impl/src/mndTrans.c index 3a53472d45..32ac795301 100644 --- a/source/dnode/mnode/impl/src/mndTrans.c +++ b/source/dnode/mnode/impl/src/mndTrans.c @@ -17,8 +17,9 @@ #include "mndTrans.h" #include "mndSync.h" -#define SDB_TRANS_VER 1 -#define TRN_DEFAULT_ARRAY_SIZE 8 +#define TSDB_TRANS_VER 1 +#define TSDB_TRN_ARRAY_SIZE 8 +#define TSDB_TRN_RESERVE_SIZE 64 static SSdbRaw *mndTransActionEncode(STrans *pTrans); static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw); @@ -26,6 +27,22 @@ static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans); static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *OldTrans, STrans *pOldTrans); static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans); +static void mndTransSetRpcHandle(STrans *pTrans, void *rpcHandle); +static void mndTransSendRpcRsp(STrans *pTrans, int32_t code); +static int32_t mndTransAppendArray(SArray *pArray, SSdbRaw *pRaw); +static void mndTransDropArray(SArray *pArray); +static int32_t mndTransExecuteArray(SMnode *pMnode, SArray *pArray); +static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransExecuteCommitLogs(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransPerformExecuteStage(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans); +static int32_t mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans); +static void mndTransExecute(SMnode *pMnode, STrans *pTrans); + int32_t mndInitTrans(SMnode *pMnode) { SSdbTable table = {.sdbType = SDB_TRANS, .keyType = SDB_KEY_INT32, @@ -41,7 +58,7 @@ int32_t mndInitTrans(SMnode *pMnode) { void mndCleanupTrans(SMnode *pMnode) {} static SSdbRaw *mndTransActionEncode(STrans *pTrans) { - int32_t rawDataLen = 16 * sizeof(int32_t); + int32_t rawDataLen = 16 * sizeof(int32_t) + TSDB_TRN_RESERVE_SIZE; int32_t redoLogNum = taosArrayGetSize(pTrans->redoLogs); int32_t undoLogNum = taosArrayGetSize(pTrans->undoLogs); int32_t commitLogNum = taosArrayGetSize(pTrans->commitLogs); @@ -63,7 +80,7 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { rawDataLen += sdbGetRawTotalSize(pTmp); } - SSdbRaw *pRaw = sdbAllocRaw(SDB_TRANS, SDB_TRANS_VER, rawDataLen); + SSdbRaw *pRaw = sdbAllocRaw(SDB_TRANS, TSDB_TRANS_VER, rawDataLen); if (pRaw == NULL) { mError("trans:%d, failed to alloc raw since %s", pTrans->id, terrstr()); return NULL; @@ -71,7 +88,6 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { int32_t dataPos = 0; SDB_SET_INT32(pRaw, dataPos, pTrans->id) - SDB_SET_INT8(pRaw, dataPos, pTrans->stage) SDB_SET_INT8(pRaw, dataPos, pTrans->policy) SDB_SET_INT32(pRaw, dataPos, redoLogNum) SDB_SET_INT32(pRaw, dataPos, undoLogNum) @@ -100,6 +116,8 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) { SDB_SET_BINARY(pRaw, dataPos, (void *)pTmp, len) } + SDB_SET_RESERVE(pRaw, dataPos, TSDB_TRN_RESERVE_SIZE) + SDB_SET_DATALEN(pRaw, dataPos); mTrace("trans:%d, encode to raw:%p, len:%d", pTrans->id, pRaw, dataPos); return pRaw; } @@ -113,7 +131,7 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { return NULL; } - if (sver != SDB_TRANS_VER) { + if (sver != TSDB_TRANS_VER) { terrno = TSDB_CODE_SDB_INVALID_DATA_VER; mError("failed to get check soft ver from raw:%p since %s", pRaw, terrstr()); return NULL; @@ -126,11 +144,11 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { return NULL; } - pTrans->redoLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->undoLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->commitLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->redoActions = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->undoActions = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); + pTrans->redoLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->undoLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->commitLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->redoActions = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->undoActions = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); if (pTrans->redoLogs == NULL || pTrans->undoLogs == NULL || pTrans->commitLogs == NULL || pTrans->redoActions == NULL || pTrans->undoActions == NULL) { @@ -147,7 +165,6 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { int32_t dataPos = 0; SDB_GET_INT32(pRaw, pRow, dataPos, &pTrans->id) - SDB_GET_INT8(pRaw, pRow, dataPos, (int8_t *)&pTrans->stage) SDB_GET_INT8(pRaw, pRow, dataPos, (int8_t *)&pTrans->policy) SDB_GET_INT32(pRaw, pRow, dataPos, &redoLogNum) SDB_GET_INT32(pRaw, pRow, dataPos, &undoLogNum) @@ -197,6 +214,8 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) { } } + SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_TRN_RESERVE_SIZE) + TRANS_DECODE_OVER: if (code != 0) { mError("trans:%d, failed to parse from raw:%p since %s", pTrans->id, pRaw, tstrerror(errno)); @@ -210,62 +229,65 @@ TRANS_DECODE_OVER: } static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans) { - mTrace("trans:%d, perform insert action, stage:%d", pTrans->id, pTrans->stage); - - SArray *pArray = pTrans->redoLogs; - int32_t arraySize = taosArrayGetSize(pArray); - - for (int32_t i = 0; i < arraySize; ++i) { - SSdbRaw *pRaw = taosArrayGetP(pArray, i); - int32_t code = sdbWrite(pSdb, pRaw); - if (code != 0) { - mError("trans:%d, failed to write raw:%p to sdb since %s", pTrans->id, pRaw, terrstr()); - return code; - } - } + pTrans->stage = TRN_STAGE_PREPARE; + mTrace("trans:%d, perform insert action, stage:%s", pTrans->id, mndTransStageStr(pTrans->stage)); return 0; } static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans) { - mTrace("trans:%d, perform delete action, stage:%d", pTrans->id, pTrans->stage); + mTrace("trans:%d, perform delete action, stage:%s", pTrans->id, mndTransStageStr(pTrans->stage)); - SArray *pArray = pTrans->undoLogs; - int32_t arraySize = taosArrayGetSize(pArray); - - for (int32_t i = 0; i < arraySize; ++i) { - SSdbRaw *pRaw = taosArrayGetP(pArray, i); - int32_t code = sdbWrite(pSdb, pRaw); - if (code != 0) { - mError("trans:%d, failed to write raw:%p to sdb since %s", pTrans->id, pRaw, terrstr()); - return code; - } - } + mndTransDropArray(pTrans->redoLogs); + mndTransDropArray(pTrans->undoLogs); + mndTransDropArray(pTrans->commitLogs); + mndTransDropArray(pTrans->redoActions); + mndTransDropArray(pTrans->undoActions); return 0; } static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *pOldTrans, STrans *pNewTrans) { - mTrace("trans:%d, perform update action, stage:%d", pOldTrans->id, pNewTrans->stage); - - SArray *pArray = pOldTrans->commitLogs; - int32_t arraySize = taosArrayGetSize(pArray); - - for (int32_t i = 0; i < arraySize; ++i) { - SSdbRaw *pRaw = taosArrayGetP(pArray, i); - int32_t code = sdbWrite(pSdb, pRaw); - if (code != 0) { - mError("trans:%d, failed to write raw:%p to sdb since %s", pOldTrans->id, pRaw, terrstr()); - return code; - } - } - + mTrace("trans:%d, perform update action, stage:%s", pOldTrans->id, mndTransStageStr(pNewTrans->stage)); pOldTrans->stage = pNewTrans->stage; return 0; } -static int32_t trnGenerateTransId() { - static int32_t tmp = 0; - return ++tmp; +STrans *mndAcquireTrans(SMnode *pMnode, int32_t transId) { + SSdb *pSdb = pMnode->pSdb; + return sdbAcquire(pSdb, SDB_TRANS, &transId); +} + +void mndReleaseTrans(SMnode *pMnode, STrans *pTrans) { + SSdb *pSdb = pMnode->pSdb; + sdbRelease(pSdb, pTrans); +} + +char *mndTransStageStr(ETrnStage stage) { + switch (stage) { + case TRN_STAGE_PREPARE: + return "prepare"; + case TRN_STAGE_EXECUTE: + return "execute"; + case TRN_STAGE_COMMIT: + return "commit"; + case TRN_STAGE_ROLLBACK: + return "rollback"; + case TRN_STAGE_RETRY: + return "retry"; + default: + return "undefined"; + } +} + +char *mndTransPolicyStr(ETrnPolicy policy) { + switch (policy) { + case TRN_POLICY_ROLLBACK: + return "prepare"; + case TRN_POLICY_RETRY: + return "retry"; + default: + return "undefined"; + } } STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, void *rpcHandle) { @@ -276,16 +298,15 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, void *rpcHandle) { return NULL; } - pTrans->id = trnGenerateTransId(); + pTrans->id = sdbGetMaxId(pMnode->pSdb, SDB_TRANS); pTrans->stage = TRN_STAGE_PREPARE; pTrans->policy = policy; - pTrans->pMnode = pMnode; pTrans->rpcHandle = rpcHandle; - pTrans->redoLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->undoLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->commitLogs = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->redoActions = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); - pTrans->undoActions = taosArrayInit(TRN_DEFAULT_ARRAY_SIZE, sizeof(void *)); + pTrans->redoLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->undoLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->commitLogs = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->redoActions = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); + pTrans->undoActions = taosArrayInit(TSDB_TRN_ARRAY_SIZE, sizeof(void *)); if (pTrans->redoLogs == NULL || pTrans->undoLogs == NULL || pTrans->commitLogs == NULL || pTrans->redoActions == NULL || pTrans->undoActions == NULL) { @@ -298,7 +319,7 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, void *rpcHandle) { return pTrans; } -static void trnDropArray(SArray *pArray) { +static void mndTransDropArray(SArray *pArray) { for (int32_t i = 0; i < pArray->size; ++i) { SSdbRaw *pRaw = taosArrayGetP(pArray, i); tfree(pRaw); @@ -308,17 +329,17 @@ static void trnDropArray(SArray *pArray) { } void mndTransDrop(STrans *pTrans) { - trnDropArray(pTrans->redoLogs); - trnDropArray(pTrans->undoLogs); - trnDropArray(pTrans->commitLogs); - trnDropArray(pTrans->redoActions); - trnDropArray(pTrans->undoActions); + mndTransDropArray(pTrans->redoLogs); + mndTransDropArray(pTrans->undoLogs); + mndTransDropArray(pTrans->commitLogs); + mndTransDropArray(pTrans->redoActions); + mndTransDropArray(pTrans->undoActions); mDebug("trans:%d, data:%p is dropped", pTrans->id, pTrans); tfree(pTrans); } -void mndTransSetRpcHandle(STrans *pTrans, void *rpcHandle) { +static void mndTransSetRpcHandle(STrans *pTrans, void *rpcHandle) { pTrans->rpcHandle = rpcHandle; mTrace("trans:%d, set rpc handle:%p", pTrans->id, rpcHandle); } @@ -340,19 +361,19 @@ static int32_t mndTransAppendArray(SArray *pArray, SSdbRaw *pRaw) { int32_t mndTransAppendRedolog(STrans *pTrans, SSdbRaw *pRaw) { int32_t code = mndTransAppendArray(pTrans->redoLogs, pRaw); - mTrace("trans:%d, raw:%p append to redo logs, code:%d", pTrans->id, pRaw, code); + mTrace("trans:%d, raw:%p append to redo logs, code:0x%x", pTrans->id, pRaw, code); return code; } int32_t mndTransAppendUndolog(STrans *pTrans, SSdbRaw *pRaw) { int32_t code = mndTransAppendArray(pTrans->undoLogs, pRaw); - mTrace("trans:%d, raw:%p append to undo logs, code:%d", pTrans->id, pRaw, code); + mTrace("trans:%d, raw:%p append to undo logs, code:0x%x", pTrans->id, pRaw, code); return code; } int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw) { int32_t code = mndTransAppendArray(pTrans->commitLogs, pRaw); - mTrace("trans:%d, raw:%p append to commit logs, code:%d", pTrans->id, pRaw, code); + mTrace("trans:%d, raw:%p append to commit logs, code:0x%x", pTrans->id, pRaw, code); return code; } @@ -368,7 +389,7 @@ int32_t mndTransAppendUndoAction(STrans *pTrans, SEpSet *pEpSet, void *pMsg) { return code; } -int32_t mndTransPrepare(STrans *pTrans) { +int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) { mDebug("trans:%d, prepare transaction", pTrans->id); SSdbRaw *pRaw = mndTransActionEncode(pTrans); @@ -376,180 +397,295 @@ int32_t mndTransPrepare(STrans *pTrans) { mError("trans:%d, failed to decode trans since %s", pTrans->id, terrstr()); return -1; } - sdbSetRawStatus(pRaw, SDB_STATUS_CREATING); + sdbSetRawStatus(pRaw, SDB_STATUS_READY); - if (sdbWriteNotFree(pTrans->pMnode->pSdb, pRaw) != 0) { - mError("trans:%d, failed to write trans since %s", pTrans->id, terrstr()); - return -1; - } - - STransMsg *pMsg = calloc(1, sizeof(STransMsg)); - pMsg->id = pTrans->id; - pMsg->rpcHandle = pTrans->rpcHandle; - - mDebug("trans:%d, start sync, RPC:%p pMsg:%p", pTrans->id, pTrans->rpcHandle, pMsg); - if (mndSyncPropose(pTrans->pMnode, pRaw, pMsg) != 0) { + mTrace("trans:%d, start sync", pTrans->id); + int32_t code = mndSyncPropose(pMnode, pRaw); + if (code != 0) { mError("trans:%d, failed to sync since %s", pTrans->id, terrstr()); - free(pMsg); sdbFreeRaw(pRaw); return -1; } - sdbFreeRaw(pRaw); + mTrace("trans:%d, sync finished", pTrans->id); + + code = sdbWrite(pMnode->pSdb, pRaw); + if (code != 0) { + mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr()); + return -1; + } + + STrans *pNewTrans = mndAcquireTrans(pMnode, pTrans->id); + if (pNewTrans == NULL) { + mError("trans:%d, failed to ready from sdb since %s", pTrans->id, terrstr()); + return -1; + } + + mDebug("trans:%d, prepare finished", pNewTrans->id); + pNewTrans->rpcHandle = pTrans->rpcHandle; + mndTransExecute(pMnode, pNewTrans); + mndReleaseTrans(pMnode, pNewTrans); return 0; } -static void trnSendRpcRsp(STransMsg *pMsg, int32_t code) { - mDebug("trans:%d, send rpc rsp, RPC:%p code:0x%x pMsg:%p", pMsg->id, pMsg->rpcHandle, code & 0xFFFF, pMsg); - if (pMsg->rpcHandle != NULL) { - SRpcMsg rspMsg = {.handle = pMsg->rpcHandle, .code = code}; - rpcSendResponse(&rspMsg); +int32_t mndTransCommit(SMnode *pMnode, STrans *pTrans) { + mDebug("trans:%d, commit transaction", pTrans->id); + + SSdbRaw *pRaw = mndTransActionEncode(pTrans); + if (pRaw == NULL) { + mError("trans:%d, failed to decode trans since %s", pTrans->id, terrstr()); + return -1; + } + sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED); + + if (taosArrayGetSize(pTrans->commitLogs) != 0) { + mTrace("trans:%d, start sync", pTrans->id); + int32_t code = mndSyncPropose(pMnode, pRaw); + if (code != 0) { + mError("trans:%d, failed to sync since %s", pTrans->id, terrstr()); + sdbFreeRaw(pRaw); + return -1; + } + + mTrace("trans:%d, sync finished", pTrans->id); + code = sdbWrite(pMnode->pSdb, pRaw); + if (code != 0) { + mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr()); + return -1; + } } - free(pMsg); + mDebug("trans:%d, commit finished", pTrans->id); + return 0; +} + +int32_t mndTransRollback(SMnode *pMnode, STrans *pTrans) { + mDebug("trans:%d, rollback transaction", pTrans->id); + + SSdbRaw *pRaw = mndTransActionEncode(pTrans); + if (pRaw == NULL) { + mError("trans:%d, failed to decode trans since %s", pTrans->id, terrstr()); + return -1; + } + sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED); + + mTrace("trans:%d, start sync", pTrans->id); + int32_t code = mndSyncPropose(pMnode, pRaw); + if (code != 0) { + mError("trans:%d, failed to sync since %s", pTrans->id, terrstr()); + sdbFreeRaw(pRaw); + return -1; + } + + mTrace("trans:%d, sync finished", pTrans->id); + code = sdbWrite(pMnode->pSdb, pRaw); + if (code != 0) { + mError("trans:%d, failed to write sdb since %s", pTrans->id, terrstr()); + return -1; + } + + mDebug("trans:%d, rollback finished", pTrans->id); + return 0; +} + +static void mndTransSendRpcRsp(STrans *pTrans, int32_t code) { + if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) return; + mDebug("trans:%d, send rpc rsp, RPC:%p code:0x%x", pTrans->id, pTrans->rpcHandle, code & 0xFFFF); + + if (pTrans->rpcHandle != NULL) { + SRpcMsg rspMsg = {.handle = pTrans->rpcHandle, .code = code}; + rpcSendResponse(&rspMsg); + } } void mndTransApply(SMnode *pMnode, SSdbRaw *pRaw, STransMsg *pMsg, int32_t code) { - if (code == 0) { - mDebug("trans:%d, commit transaction", pMsg->id); - sdbSetRawStatus(pRaw, SDB_STATUS_READY); - if (sdbWrite(pMnode->pSdb, pRaw) != 0) { - code = terrno; - mError("trans:%d, failed to write sdb while commit since %s", pMsg->id, terrstr()); - } - trnSendRpcRsp(pMsg, code); - } else { - mDebug("trans:%d, rollback transaction", pMsg->id); - sdbSetRawStatus(pRaw, SDB_STATUS_DROPPED); - if (sdbWrite(pMnode->pSdb, pRaw) != 0) { - mError("trans:%d, failed to write sdb while rollback since %s", pMsg->id, terrstr()); - } - trnSendRpcRsp(pMsg, code); - } + // todo } -static int32_t trnExecuteArray(SMnode *pMnode, SArray *pArray) { - for (int32_t i = 0; i < pArray->size; ++i) { +static int32_t mndTransExecuteArray(SMnode *pMnode, SArray *pArray) { + SSdb *pSdb = pMnode->pSdb; + int32_t arraySize = taosArrayGetSize(pArray); + + for (int32_t i = 0; i < arraySize; ++i) { SSdbRaw *pRaw = taosArrayGetP(pArray, i); - if (sdbWrite(pMnode->pSdb, pRaw) != 0) { - return -1; + int32_t code = sdbWriteNotFree(pSdb, pRaw); + if (code != 0) { + return code; } } return 0; } -static int32_t trnExecuteRedoLogs(STrans *pTrans) { return trnExecuteArray(pTrans->pMnode, pTrans->redoLogs); } - -static int32_t trnExecuteUndoLogs(STrans *pTrans) { return trnExecuteArray(pTrans->pMnode, pTrans->undoLogs); } - -static int32_t trnExecuteCommitLogs(STrans *pTrans) { return trnExecuteArray(pTrans->pMnode, pTrans->commitLogs); } - -static int32_t trnExecuteRedoActions(STrans *pTrans) { return trnExecuteArray(pTrans->pMnode, pTrans->redoActions); } - -static int32_t trnExecuteUndoActions(STrans *pTrans) { return trnExecuteArray(pTrans->pMnode, pTrans->undoActions); } - -static int32_t trnPerformPrepareStage(STrans *pTrans) { - if (trnExecuteRedoLogs(pTrans) == 0) { - pTrans->stage = TRN_STAGE_EXECUTE; - return 0; - } else { - pTrans->stage = TRN_STAGE_ROLLBACK; - return -1; +static int32_t mndTransExecuteRedoLogs(SMnode *pMnode, STrans *pTrans) { + int32_t code = 0; + if (taosArrayGetSize(pTrans->redoLogs) != 0) { + code = mndTransExecuteArray(pMnode, pTrans->redoLogs); + if (code != 0) { + mError("trans:%d, failed to execute redo logs since %s", pTrans->id, terrstr()) + } else { + mTrace("trans:%d, execute redo logs finished", pTrans->id) + } } + + return code; } -static int32_t trnPerformExecuteStage(STrans *pTrans) { - int32_t code = trnExecuteRedoActions(pTrans); +static int32_t mndTransExecuteUndoLogs(SMnode *pMnode, STrans *pTrans) { + int32_t code = 0; + if (taosArrayGetSize(pTrans->undoLogs) != 0) { + code = mndTransExecuteArray(pMnode, pTrans->undoLogs); + if (code != 0) { + mError("trans:%d, failed to execute undo logs since %s", pTrans->id, terrstr()) + } else { + mTrace("trans:%d, execute undo logs finished", pTrans->id) + } + } + + return code; +} + +static int32_t mndTransExecuteCommitLogs(SMnode *pMnode, STrans *pTrans) { + int32_t code = 0; + if (taosArrayGetSize(pTrans->commitLogs) != 0) { + code = mndTransExecuteArray(pMnode, pTrans->commitLogs); + if (code != 0) { + mError("trans:%d, failed to execute commit logs since %s", pTrans->id, terrstr()) + } else { + mTrace("trans:%d, execute commit logs finished", pTrans->id) + } + } + + return code; +} + +static int32_t mndTransExecuteRedoActions(SMnode *pMnode, STrans *pTrans) { + if (taosArrayGetSize(pTrans->redoActions) != 0) { + mTrace("trans:%d, execute redo actions finished", pTrans->id); + } + return 0; +} + +static int32_t mndTransExecuteUndoActions(SMnode *pMnode, STrans *pTrans) { + if (taosArrayGetSize(pTrans->undoActions) != 0) { + mTrace("trans:%d, execute undo actions finished", pTrans->id); + } + return 0; +} + +static int32_t mndTransPerformPrepareStage(SMnode *pMnode, STrans *pTrans) { + int32_t code = mndTransExecuteRedoLogs(pMnode, pTrans); + + if (code == 0) { + pTrans->stage = TRN_STAGE_EXECUTE; + mTrace("trans:%d, stage from prepare to execute", pTrans->id); + } else { + pTrans->stage = TRN_STAGE_ROLLBACK; + mError("trans:%d, stage from prepare to rollback since %s", pTrans->id, terrstr()); + } + + return 0; +} + +static int32_t mndTransPerformExecuteStage(SMnode *pMnode, STrans *pTrans) { + int32_t code = mndTransExecuteRedoActions(pMnode, pTrans); if (code == 0) { pTrans->stage = TRN_STAGE_COMMIT; - return 0; + mTrace("trans:%d, stage from execute to commit", pTrans->id); } else if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) { - return -1; + mTrace("trans:%d, stage keep on execute since %s", pTrans->id, terrstr(code)); + return code; } else { - if (pTrans->policy == TRN_POLICY_RETRY) { - pTrans->stage = TRN_STAGE_RETRY; - } else { + if (pTrans->policy == TRN_POLICY_ROLLBACK) { pTrans->stage = TRN_STAGE_ROLLBACK; + mError("trans:%d, stage from execute to rollback since %s", pTrans->id, terrstr()); + } else { + pTrans->stage = TRN_STAGE_RETRY; + mError("trans:%d, stage from execute to retry since %s", pTrans->id, terrstr()); } - return 0; } + + return 0; } -static int32_t trnPerformCommitStage(STrans *pTrans) { - if (trnExecuteCommitLogs(pTrans) == 0) { - pTrans->stage = TRN_STAGE_EXECUTE; - return 0; +static int32_t mndTransPerformCommitStage(SMnode *pMnode, STrans *pTrans) { + int32_t code = mndTransExecuteCommitLogs(pMnode, pTrans); + + if (code == 0) { + pTrans->stage = TRN_STAGE_OVER; + mTrace("trans:%d, commit stage finished", pTrans->id); + } else { + if (pTrans->policy == TRN_POLICY_ROLLBACK) { + pTrans->stage = TRN_STAGE_ROLLBACK; + mError("trans:%d, stage from commit to rollback since %s", pTrans->id, terrstr()); + } else { + pTrans->stage = TRN_STAGE_RETRY; + mError("trans:%d, stage from commit to retry since %s", pTrans->id, terrstr()); + } + } + + return code; +} + +static int32_t mndTransPerformRollbackStage(SMnode *pMnode, STrans *pTrans) { + int32_t code = mndTransExecuteUndoActions(pMnode, pTrans); + + if (code == 0) { + mTrace("trans:%d, rollbacked", pTrans->id); } else { pTrans->stage = TRN_STAGE_ROLLBACK; - return -1; + mError("trans:%d, stage keep on rollback since %s", pTrans->id, terrstr()); } + + return code; } -static int32_t trnPerformRollbackStage(STrans *pTrans) { - if (trnExecuteCommitLogs(pTrans) == 0) { - pTrans->stage = TRN_STAGE_EXECUTE; - return 0; +static int32_t mndTransPerformRetryStage(SMnode *pMnode, STrans *pTrans) { + int32_t code = mndTransExecuteRedoActions(pMnode, pTrans); + + if (code == 0) { + pTrans->stage = TRN_STAGE_COMMIT; + mTrace("trans:%d, stage from retry to commit", pTrans->id); } else { - pTrans->stage = TRN_STAGE_ROLLBACK; - return -1; + pTrans->stage = TRN_STAGE_RETRY; + mError("trans:%d, stage keep on retry since %s", pTrans->id, terrstr()); } + + return code; } -static int32_t trnPerformRetryStage(STrans *pTrans) { - if (trnExecuteCommitLogs(pTrans) == 0) { - pTrans->stage = TRN_STAGE_EXECUTE; - return 0; - } else { - pTrans->stage = TRN_STAGE_ROLLBACK; - return -1; - } -} - -int32_t mndTransExecute(SSdb *pSdb, int32_t tranId) { +static void mndTransExecute(SMnode *pMnode, STrans *pTrans) { int32_t code = 0; - STrans *pTrans = sdbAcquire(pSdb, SDB_TRANS, &tranId); - if (pTrans == NULL) { - return -1; - } - - if (pTrans->stage == TRN_STAGE_PREPARE) { - if (trnPerformPrepareStage(pTrans) != 0) { - sdbRelease(pSdb, pTrans); - return -1; + while (code == 0) { + switch (pTrans->stage) { + case TRN_STAGE_PREPARE: + code = mndTransPerformPrepareStage(pMnode, pTrans); + break; + case TRN_STAGE_EXECUTE: + code = mndTransPerformExecuteStage(pMnode, pTrans); + break; + case TRN_STAGE_COMMIT: + code = mndTransCommit(pMnode, pTrans); + if (code == 0) { + code = mndTransPerformCommitStage(pMnode, pTrans); + } + break; + case TRN_STAGE_ROLLBACK: + code = mndTransPerformRollbackStage(pMnode, pTrans); + if (code == 0) { + code = mndTransRollback(pMnode, pTrans); + } + break; + case TRN_STAGE_RETRY: + code = mndTransPerformRetryStage(pMnode, pTrans); + break; + default: + mndTransSendRpcRsp(pTrans, 0); + return; } } - if (pTrans->stage == TRN_STAGE_EXECUTE) { - if (trnPerformExecuteStage(pTrans) != 0) { - sdbRelease(pSdb, pTrans); - return -1; - } - } - - if (pTrans->stage == TRN_STAGE_COMMIT) { - if (trnPerformCommitStage(pTrans) != 0) { - sdbRelease(pSdb, pTrans); - return -1; - } - } - - if (pTrans->stage == TRN_STAGE_ROLLBACK) { - if (trnPerformRollbackStage(pTrans) != 0) { - sdbRelease(pSdb, pTrans); - return -1; - } - } - - if (pTrans->stage == TRN_STAGE_RETRY) { - if (trnPerformRetryStage(pTrans) != 0) { - sdbRelease(pSdb, pTrans); - return -1; - } - } - - sdbRelease(pSdb, pTrans); - return 0; -} \ No newline at end of file + mndTransSendRpcRsp(pTrans, code); +} diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 419936f14c..5fa4fe5359 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -20,7 +20,8 @@ #include "mndTrans.h" #include "tkey.h" -#define SDB_USER_VER 1 +#define TSDB_USER_VER 1 +#define TSDB_USER_RESERVE_SIZE 64 static int32_t mndCreateDefaultUsers(SMnode *pMnode); static SSdbRaw *mndUserActionEncode(SUserObj *pUser); @@ -93,7 +94,7 @@ static int32_t mndCreateDefaultUsers(SMnode *pMnode) { } static SSdbRaw *mndUserActionEncode(SUserObj *pUser) { - SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, SDB_USER_VER, sizeof(SUserObj)); + SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, TSDB_USER_VER, sizeof(SUserObj) + TSDB_USER_RESERVE_SIZE); if (pRaw == NULL) return NULL; int32_t dataPos = 0; @@ -103,6 +104,7 @@ static SSdbRaw *mndUserActionEncode(SUserObj *pUser) { SDB_SET_INT64(pRaw, dataPos, pUser->createdTime) SDB_SET_INT64(pRaw, dataPos, pUser->updateTime) SDB_SET_INT8(pRaw, dataPos, pUser->superUser) + SDB_SET_RESERVE(pRaw, dataPos, TSDB_USER_RESERVE_SIZE) SDB_SET_DATALEN(pRaw, dataPos); return pRaw; @@ -112,7 +114,7 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { int8_t sver = 0; if (sdbGetRawSoftVer(pRaw, &sver) != 0) return NULL; - if (sver != SDB_USER_VER) { + if (sver != TSDB_USER_VER) { mError("failed to decode user since %s", terrstr()); terrno = TSDB_CODE_SDB_INVALID_DATA_VER; return NULL; @@ -129,6 +131,7 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { SDB_GET_INT64(pRaw, pRow, dataPos, &pUser->createdTime) SDB_GET_INT64(pRaw, pRow, dataPos, &pUser->updateTime) SDB_GET_INT8(pRaw, pRow, dataPos, &pUser->superUser) + SDB_GET_RESERVE(pRaw, pRow, dataPos, TSDB_USER_RESERVE_SIZE) return pRow; } @@ -166,12 +169,8 @@ static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) { static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOldUser, SUserObj *pNewUser) { mTrace("user:%s, perform update action", pOldUser->user); - memcpy(pOldUser->user, pNewUser->user, TSDB_USER_LEN); memcpy(pOldUser->pass, pNewUser->pass, TSDB_PASSWORD_LEN); - memcpy(pOldUser->acct, pNewUser->acct, TSDB_USER_LEN); - pOldUser->createdTime = pNewUser->createdTime; pOldUser->updateTime = pNewUser->updateTime; - pOldUser->superUser = pNewUser->superUser; return 0; } @@ -207,101 +206,9 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, char *user, char *pass, mndTransDrop(pTrans); return -1; } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_CREATING); - - SSdbRaw *pUndoRaw = mndUserActionEncode(&userObj); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_DROPPED); - - SSdbRaw *pCommitRaw = mndUserActionEncode(&userObj); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_READY); - - if (mndTransPrepare(pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - - mndTransDrop(pTrans); - return 0; -} - -static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOldUser, SUserObj *pNewUser, SMnodeMsg *pMsg) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); - if (pTrans == NULL) { - mError("user:%s, failed to update since %s", pOldUser->user, terrstr()); - return -1; - } - mDebug("trans:%d, used to update user:%s", pTrans->id, pOldUser->user); - - SSdbRaw *pRedoRaw = mndUserActionEncode(pNewUser); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY); - SSdbRaw *pUndoRaw = mndUserActionEncode(pOldUser); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - - if (mndTransPrepare(pTrans) != 0) { - mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - - mndTransDrop(pTrans); - return 0; -} - -static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pMsg, SUserObj *pUser) { - STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); - if (pTrans == NULL) { - mError("user:%s, failed to drop since %s", pUser->user, terrstr()); - return -1; - } - mDebug("trans:%d, used to drop user:%s", pTrans->id, pUser->user); - - SSdbRaw *pRedoRaw = mndUserActionEncode(pUser); - if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { - mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPING); - - SSdbRaw *pUndoRaw = mndUserActionEncode(pUser); - if (pUndoRaw == NULL || mndTransAppendUndolog(pTrans, pUndoRaw) != 0) { - mError("trans:%d, failed to append undo log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pUndoRaw, SDB_STATUS_READY); - - SSdbRaw *pCommitRaw = mndUserActionEncode(pUser); - if (pCommitRaw == NULL || mndTransAppendCommitlog(pTrans, pCommitRaw) != 0) { - mError("trans:%d, failed to append commit log since %s", pTrans->id, terrstr()); - mndTransDrop(pTrans); - return -1; - } - sdbSetRawStatus(pCommitRaw, SDB_STATUS_DROPPED); - - if (mndTransPrepare(pTrans) != 0) { + if (mndTransPrepare(pMnode, pTrans) != 0) { mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); mndTransDrop(pTrans); return -1; @@ -355,6 +262,32 @@ static int32_t mndProcessCreateUserMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } +static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOldUser, SUserObj *pNewUser, SMnodeMsg *pMsg) { + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); + if (pTrans == NULL) { + mError("user:%s, failed to update since %s", pOldUser->user, terrstr()); + return -1; + } + mDebug("trans:%d, used to update user:%s", pTrans->id, pOldUser->user); + + SSdbRaw *pRedoRaw = mndUserActionEncode(pNewUser); + if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { + mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); + mndTransDrop(pTrans); + return -1; + } + sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY); + + if (mndTransPrepare(pMnode, pTrans) != 0) { + mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); + mndTransDrop(pTrans); + return -1; + } + + mndTransDrop(pTrans); + return 0; +} + static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SAlterUserMsg *pAlter = pMsg->rpcMsg.pCont; @@ -391,6 +324,7 @@ static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { memcpy(&newUser, pUser, sizeof(SUserObj)); memset(pUser->pass, 0, sizeof(pUser->pass)); taosEncryptPass((uint8_t *)pAlter->pass, strlen(pAlter->pass), pUser->pass); + newUser.updateTime = taosGetTimestampMs(); int32_t code = mndUpdateUser(pMnode, pUser, &newUser, pMsg); sdbRelease(pMnode->pSdb, pOperUser); @@ -403,6 +337,32 @@ static int32_t mndProcessAlterUserMsg(SMnodeMsg *pMsg) { return TSDB_CODE_MND_ACTION_IN_PROGRESS; } +static int32_t mndDropUser(SMnode *pMnode, SMnodeMsg *pMsg, SUserObj *pUser) { + STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, pMsg->rpcMsg.handle); + if (pTrans == NULL) { + mError("user:%s, failed to drop since %s", pUser->user, terrstr()); + return -1; + } + mDebug("trans:%d, used to drop user:%s", pTrans->id, pUser->user); + + SSdbRaw *pRedoRaw = mndUserActionEncode(pUser); + if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) { + mError("trans:%d, failed to append redo log since %s", pTrans->id, terrstr()); + mndTransDrop(pTrans); + return -1; + } + sdbSetRawStatus(pRedoRaw, SDB_STATUS_DROPPED); + + if (mndTransPrepare(pMnode, pTrans) != 0) { + mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr()); + mndTransDrop(pTrans); + return -1; + } + + mndTransDrop(pTrans); + return 0; +} + static int32_t mndProcessDropUserMsg(SMnodeMsg *pMsg) { SMnode *pMnode = pMsg->pMnode; SDropUserMsg *pDrop = pMsg->rpcMsg.pCont; @@ -526,7 +486,7 @@ static int32_t mndRetrieveUsers(SMnodeMsg *pMsg, SShowObj *pShow, char *data, in sdbRelease(pSdb, pUser); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } diff --git a/source/dnode/mnode/impl/src/mndVgroup.c b/source/dnode/mnode/impl/src/mndVgroup.c index 44d13d1fb4..9a462c024b 100644 --- a/source/dnode/mnode/impl/src/mndVgroup.c +++ b/source/dnode/mnode/impl/src/mndVgroup.c @@ -71,7 +71,7 @@ int32_t mndInitVgroup(SMnode *pMnode) { void mndCleanupVgroup(SMnode *pMnode) {} static SSdbRaw *mndVgroupActionEncode(SVgObj *pVgroup) { - SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_VGROUP_VER_NUM, sizeof(SDbObj)); + SSdbRaw *pRaw = sdbAllocRaw(SDB_DB, TSDB_VGROUP_VER_NUM, sizeof(SVgObj) + TSDB_VGROUP_RESERVE_SIZE); if (pRaw == NULL) return NULL; int32_t dataPos = 0; @@ -141,11 +141,8 @@ static int32_t mndProcessCompactVnodeRsp(SMnodeMsg *pMsg) { return 0; } static int32_t mndVgroupActionUpdate(SSdb *pSdb, SVgObj *pOldVgroup, SVgObj *pNewVgroup) { mTrace("vgId:%d, perform update action", pOldVgroup->vgId); - pOldVgroup->vgId = pNewVgroup->vgId; - pOldVgroup->createdTime = pNewVgroup->createdTime; pOldVgroup->updateTime = pNewVgroup->updateTime; pOldVgroup->version = pNewVgroup->version; - memcpy(pOldVgroup->dbName, pNewVgroup->dbName, TSDB_FULL_DB_NAME_LEN); pOldVgroup->replica = pNewVgroup->replica; memcpy(pOldVgroup->vnodeGid, pNewVgroup->vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid)); return 0; @@ -284,7 +281,7 @@ static int32_t mndRetrieveVgroups(SMnodeMsg *pMsg, SShowObj *pShow, char *data, numOfRows++; } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } @@ -374,7 +371,7 @@ static int32_t mndRetrieveVnodes(SMnodeMsg *pMsg, SShowObj *pShow, char *data, i sdbRelease(pSdb, pVgroup); } - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); + mndVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); pShow->numOfReads += numOfRows; return numOfRows; } diff --git a/source/dnode/mnode/impl/src/mnode.c b/source/dnode/mnode/impl/src/mnode.c index e543478608..24155a4e53 100644 --- a/source/dnode/mnode/impl/src/mnode.c +++ b/source/dnode/mnode/impl/src/mnode.c @@ -69,7 +69,7 @@ static void mndCleanupTimer(SMnode *pMnode) { } } -static int32_t mnodeCreateDir(SMnode *pMnode, const char *path) { +static int32_t mndCreateDir(SMnode *pMnode, const char *path) { pMnode->path = strdup(path); if (pMnode->path == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; @@ -245,7 +245,7 @@ SMnode *mndOpen(const char *path, const SMnodeOpt *pOption) { return NULL; } - int32_t code = mnodeCreateDir(pMnode, path); + int32_t code = mndCreateDir(pMnode, path); if (code != 0) { code = terrno; mError("failed to open mnode since %s", terrstr()); diff --git a/source/dnode/mnode/sdb/inc/sdbInt.h b/source/dnode/mnode/sdb/inc/sdbInt.h index a160533bf2..7e2e2602a8 100644 --- a/source/dnode/mnode/sdb/inc/sdbInt.h +++ b/source/dnode/mnode/sdb/inc/sdbInt.h @@ -59,6 +59,7 @@ typedef struct SSdb { char *tmpDir; int64_t lastCommitVer; int64_t curVer; + int32_t maxId[SDB_MAX]; EKeyType keyTypes[SDB_MAX]; SHashObj *hashObjs[SDB_MAX]; SRWLatch locks[SDB_MAX]; diff --git a/source/dnode/mnode/sdb/src/sdb.c b/source/dnode/mnode/sdb/src/sdb.c index ccff5b6c82..77614e399e 100644 --- a/source/dnode/mnode/sdb/src/sdb.c +++ b/source/dnode/mnode/sdb/src/sdb.c @@ -127,6 +127,7 @@ int32_t sdbSetTable(SSdb *pSdb, SSdbTable table) { return -1; } + pSdb->maxId[sdbType] = 0; pSdb->hashObjs[sdbType] = hash; taosInitRWLatch(&pSdb->locks[sdbType]); mDebug("sdb table:%d is initialized", sdbType); diff --git a/source/dnode/mnode/sdb/src/sdbHash.c b/source/dnode/mnode/sdb/src/sdbHash.c index 8d8daf5ce5..f63f7236fb 100644 --- a/source/dnode/mnode/sdb/src/sdbHash.c +++ b/source/dnode/mnode/sdb/src/sdbHash.c @@ -72,6 +72,10 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow * taosWUnLockLatch(pLock); + if (pSdb->keyTypes[pRow->type] == SDB_KEY_INT32) { + pSdb->maxId[pRow->type] = MAX(pSdb->maxId[pRow->type], *((int32_t *)pRow->pObj)); + } + SdbInsertFp insertFp = pSdb->insertFps[pRow->type]; if (insertFp != NULL) { code = (*insertFp)(pSdb, pRow->pObj); @@ -132,11 +136,6 @@ static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow * taosHashRemove(hash, pOldRow->pObj, keySize); taosWUnLockLatch(pLock); - SdbDeleteFp deleteFp = pSdb->deleteFps[pOldRow->type]; - if (deleteFp != NULL) { - code = (*deleteFp)(pSdb, pOldRow->pObj); - } - sdbRelease(pSdb, pOldRow->pObj); sdbFreeRow(pRow); return code; @@ -161,6 +160,7 @@ int32_t sdbWriteNotFree(SSdb *pSdb, SSdbRaw *pRaw) { case SDB_STATUS_CREATING: code = sdbInsertRow(pSdb, hash, pRaw, pRow, keySize); break; + case SDB_STATUS_UPDATING: case SDB_STATUS_READY: case SDB_STATUS_DROPPING: code = sdbUpdateRow(pSdb, hash, pRaw, pRow, keySize); @@ -228,6 +228,11 @@ void sdbRelease(SSdb *pSdb, void *pObj) { int32_t ref = atomic_sub_fetch_32(&pRow->refCount, 1); if (ref <= 0 && pRow->status == SDB_STATUS_DROPPED) { + SdbDeleteFp deleteFp = pSdb->deleteFps[pRow->type]; + if (deleteFp != NULL) { + (*deleteFp)(pSdb, pRow->pObj); + } + sdbFreeRow(pRow); } @@ -289,3 +294,28 @@ int32_t sdbGetSize(SSdb *pSdb, ESdbType type) { return size; } + +int32_t sdbGetMaxId(SSdb *pSdb, ESdbType type) { + SHashObj *hash = sdbGetHash(pSdb, type); + if (hash == NULL) return -1; + + if (pSdb->keyTypes[type] != SDB_KEY_INT32) return -1; + + int32_t maxId = 0; + + SRWLatch *pLock = &pSdb->locks[type]; + taosRLockLatch(pLock); + + SSdbRow **ppRow = taosHashIterate(hash, NULL); + while (ppRow != NULL) { + SSdbRow *pRow = *ppRow; + int32_t id = *(int32_t *)pRow->pObj; + maxId = MAX(id, maxId); + ppRow = taosHashIterate(hash, ppRow); + } + + taosRUnLockLatch(pLock); + + maxId = MAX(maxId, pSdb->maxId[type]); + return maxId + 1; +} diff --git a/source/dnode/vnode/impl/CMakeLists.txt b/source/dnode/vnode/impl/CMakeLists.txt index 6972605afd..3623516624 100644 --- a/source/dnode/vnode/impl/CMakeLists.txt +++ b/source/dnode/vnode/impl/CMakeLists.txt @@ -19,5 +19,5 @@ target_link_libraries( # test if(${BUILD_TEST}) - add_subdirectory(test) + #add_subdirectory(test) endif(${BUILD_TEST}) \ No newline at end of file diff --git a/source/dnode/vnode/impl/inc/vnodeBufferPool.h b/source/dnode/vnode/impl/inc/vnodeBufferPool.h index bfc4de9e12..d96671d2bd 100644 --- a/source/dnode/vnode/impl/inc/vnodeBufferPool.h +++ b/source/dnode/vnode/impl/inc/vnodeBufferPool.h @@ -27,6 +27,8 @@ typedef struct SVBufPool SVBufPool; int vnodeOpenBufPool(SVnode *pVnode); void vnodeCloseBufPool(SVnode *pVnode); +int vnodeBufPoolSwitch(SVnode *pVnode); +int vnodeBufPoolRecycle(SVnode *pVnode); void *vnodeMalloc(SVnode *pVnode, uint64_t size); bool vnodeBufPoolIsFull(SVnode *pVnode); diff --git a/source/dnode/vnode/impl/inc/vnodeCommit.h b/source/dnode/vnode/impl/inc/vnodeCommit.h index a60e8feac2..031089ba14 100644 --- a/source/dnode/vnode/impl/inc/vnodeCommit.h +++ b/source/dnode/vnode/impl/inc/vnodeCommit.h @@ -24,6 +24,7 @@ extern "C" { #define vnodeShouldCommit vnodeBufPoolIsFull int vnodeAsyncCommit(SVnode *pVnode); +int vnodeCommit(void *arg); #ifdef __cplusplus } diff --git a/source/dnode/vnode/impl/inc/vnodeDef.h b/source/dnode/vnode/impl/inc/vnodeDef.h index e3a3fac6b9..e6a88c7629 100644 --- a/source/dnode/vnode/impl/inc/vnodeDef.h +++ b/source/dnode/vnode/impl/inc/vnodeDef.h @@ -21,9 +21,11 @@ #include "tcoding.h" #include "tdlist.h" #include "tlockfree.h" +#include "tmacro.h" #include "wal.h" #include "vnode.h" + #include "vnodeBufferPool.h" #include "vnodeCfg.h" #include "vnodeCommit.h" @@ -37,6 +39,27 @@ extern "C" { #endif +typedef struct SVnodeTask { + TD_DLIST_NODE(SVnodeTask); + void* arg; + int (*execute)(void*); +} SVnodeTask; + +typedef struct SVnodeMgr { + td_mode_flag_t vnodeInitFlag; + td_mode_flag_t vnodeClearFlag; + // For commit + bool stop; + uint16_t nthreads; + pthread_t* threads; + pthread_mutex_t mutex; + pthread_cond_t hasTask; + TD_DLIST(SVnodeTask) queue; + // For vnode Mgmt +} SVnodeMgr; + +extern SVnodeMgr vnodeMgr; + struct SVnode { char* path; SVnodeCfg config; @@ -50,6 +73,8 @@ struct SVnode { SVnodeFS* pFs; }; +int vnodeScheduleTask(SVnodeTask* task); + #ifdef __cplusplus } #endif diff --git a/source/dnode/vnode/impl/inc/vnodeMemAllocator.h b/source/dnode/vnode/impl/inc/vnodeMemAllocator.h index c8c58e9f69..bdafbf31a7 100644 --- a/source/dnode/vnode/impl/inc/vnodeMemAllocator.h +++ b/source/dnode/vnode/impl/inc/vnodeMemAllocator.h @@ -33,6 +33,7 @@ struct SVArenaNode { }; struct SVMemAllocator { + T_REF_DECLARE() TD_DLIST_NODE(SVMemAllocator); uint64_t capacity; uint64_t ssize; diff --git a/source/dnode/vnode/impl/src/vnodeBufferPool.c b/source/dnode/vnode/impl/src/vnodeBufferPool.c index 1db15c3990..152a346f0a 100644 --- a/source/dnode/vnode/impl/src/vnodeBufferPool.c +++ b/source/dnode/vnode/impl/src/vnodeBufferPool.c @@ -19,6 +19,8 @@ #define VNODE_BUF_POOL_SHARDS 3 struct SVBufPool { + pthread_mutex_t mutex; + pthread_cond_t hasFree; TD_DLIST(SVMemAllocator) free; TD_DLIST(SVMemAllocator) incycle; SVMemAllocator *inuse; @@ -28,7 +30,6 @@ struct SVBufPool { int vnodeOpenBufPool(SVnode *pVnode) { uint64_t capacity; - // EVMemAllocatorT type = E_V_ARENA_ALLOCATOR; if ((pVnode->pBufPool = (SVBufPool *)calloc(1, sizeof(SVBufPool))) == NULL) { /* TODO */ @@ -79,6 +80,27 @@ void vnodeCloseBufPool(SVnode *pVnode) { } } +int vnodeBufPoolSwitch(SVnode *pVnode) { + SVMemAllocator *pvma = pVnode->pBufPool->inuse; + + pVnode->pBufPool->inuse = NULL; + + tDListAppend(&(pVnode->pBufPool->incycle), pvma); + return 0; +} + +int vnodeBufPoolRecycle(SVnode *pVnode) { + SVBufPool * pBufPool = pVnode->pBufPool; + SVMemAllocator *pvma = TD_DLIST_HEAD(&(pBufPool->incycle)); + ASSERT(pvma != NULL); + + tDListPop(&(pBufPool->incycle), pvma); + vmaReset(pvma); + tDListAppend(&(pBufPool->free), pvma); + + return 0; +} + void *vnodeMalloc(SVnode *pVnode, uint64_t size) { SVBufPool *pBufPool = pVnode->pBufPool; @@ -89,6 +111,8 @@ void *vnodeMalloc(SVnode *pVnode, uint64_t size) { if (pBufPool->inuse) { tDListPop(&(pBufPool->free), pBufPool->inuse); break; + } else { + // tsem_wait(&(pBufPool->hasFree)); } } } diff --git a/source/dnode/vnode/impl/src/vnodeCfg.c b/source/dnode/vnode/impl/src/vnodeCfg.c index f5bb7e35d2..97c3cc9cee 100644 --- a/source/dnode/vnode/impl/src/vnodeCfg.c +++ b/source/dnode/vnode/impl/src/vnodeCfg.c @@ -15,7 +15,8 @@ #include "vnodeDef.h" -const SVnodeCfg defaultVnodeOptions = {.wsize = 16 * 1024 * 1024, .walCfg = {.level = TAOS_WAL_WRITE}}; /* TODO */ +const SVnodeCfg defaultVnodeOptions = { + .wsize = 96 * 1024 * 1024, .ssize = 1 * 1024 * 1024, .lsize = 1024, .walCfg = {.level = TAOS_WAL_WRITE}}; /* TODO */ void vnodeOptionsInit(SVnodeCfg *pVnodeOptions) { /* TODO */ vnodeOptionsCopy(pVnodeOptions, &defaultVnodeOptions); diff --git a/source/dnode/vnode/impl/src/vnodeCommit.c b/source/dnode/vnode/impl/src/vnodeCommit.c index cac7999f59..a728de0ebb 100644 --- a/source/dnode/vnode/impl/src/vnodeCommit.c +++ b/source/dnode/vnode/impl/src/vnodeCommit.c @@ -19,28 +19,21 @@ static int vnodeStartCommit(SVnode *pVnode); static int vnodeEndCommit(SVnode *pVnode); int vnodeAsyncCommit(SVnode *pVnode) { -#if 0 - if (vnodeStartCommit(pVnode) < 0) { - // TODO - } + vnodeBufPoolSwitch(pVnode); + SVnodeTask *pTask = (SVnodeTask *)malloc(sizeof(*pTask)); - if (tqCommit(pVnode->pTQ) < 0) { - // TODO - } + pTask->execute = vnodeCommit; // TODO + pTask->arg = pVnode; // TODO - if (metaCommit(pVnode->pMeta) < 0) { - // TODO - } + vnodeScheduleTask(pTask); + return 0; +} - if (tsdbCommit(pVnode->pTsdb) < 0) { - // TODO - } +int vnodeCommit(void *arg) { + SVnode *pVnode = (SVnode *)arg; - if (vnodeEndCommit(pVnode) < 0) { - // TODO - } - -#endif + vnodeBufPoolRecycle(pVnode); + // TODO return 0; } diff --git a/source/dnode/vnode/impl/src/vnodeMain.c b/source/dnode/vnode/impl/src/vnodeMain.c index 9b94b4a361..59e3bae5d7 100644 --- a/source/dnode/vnode/impl/src/vnodeMain.c +++ b/source/dnode/vnode/impl/src/vnodeMain.c @@ -13,7 +13,6 @@ * along with this program. If not, see . */ -#include "tmacro.h" #include "vnodeDef.h" static SVnode *vnodeNew(const char *path, const SVnodeCfg *pVnodeCfg); @@ -21,29 +20,6 @@ static void vnodeFree(SVnode *pVnode); static int vnodeOpenImpl(SVnode *pVnode); static void vnodeCloseImpl(SVnode *pVnode); -TD_DEF_MOD_INIT_FLAG(vnode); -TD_DEF_MOD_CLEAR_FLAG(vnode); - -int vnodeInit() { - if (TD_CHECK_AND_SET_MODE_INIT(vnode) == TD_MOD_INITIALIZED) { - return 0; - } - - if (walInit() < 0) { - return -1; - } - - return 0; -} - -void vnodeClear() { - if (TD_CHECK_AND_SET_MOD_CLEAR(vnode) == TD_MOD_CLEARD) { - return; - } - - walCleanUp(); -} - SVnode *vnodeOpen(const char *path, const SVnodeCfg *pVnodeCfg) { SVnode *pVnode = NULL; diff --git a/source/dnode/vnode/impl/src/vnodeMgr.c b/source/dnode/vnode/impl/src/vnodeMgr.c new file mode 100644 index 0000000000..964cbe77da --- /dev/null +++ b/source/dnode/vnode/impl/src/vnodeMgr.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "vnodeDef.h" + +SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED, .vnodeClearFlag = TD_MOD_UNCLEARD, .stop = false}; + +static void* loop(void* arg); + +int vnodeInit(uint16_t nthreads) { + if (TD_CHECK_AND_SET_MODE_INIT(&(vnodeMgr.vnodeInitFlag)) == TD_MOD_INITIALIZED) { + return 0; + } + + // Start commit handers + if (nthreads > 0) { + vnodeMgr.nthreads = nthreads; + vnodeMgr.threads = (pthread_t*)calloc(nthreads, sizeof(pthread_t)); + if (vnodeMgr.threads == NULL) { + return -1; + } + + pthread_mutex_init(&(vnodeMgr.mutex), NULL); + pthread_cond_init(&(vnodeMgr.hasTask), NULL); + tDListInit(&(vnodeMgr.queue)); + + for (uint16_t i = 0; i < nthreads; i++) { + pthread_create(&(vnodeMgr.threads[i]), NULL, loop, NULL); + } + } else { + // TODO: if no commit thread is set, then another mechanism should be + // given. Otherwise, it is a false. + ASSERT(0); + } + + if (walInit() < 0) { + return -1; + } + + return 0; +} + +void vnodeClear() { + if (TD_CHECK_AND_SET_MOD_CLEAR(&(vnodeMgr.vnodeClearFlag)) == TD_MOD_CLEARD) { + return; + } + + walCleanUp(); + + // Stop commit handler + pthread_mutex_lock(&(vnodeMgr.mutex)); + vnodeMgr.stop = true; + pthread_cond_broadcast(&(vnodeMgr.hasTask)); + pthread_mutex_unlock(&(vnodeMgr.mutex)); + + for (uint16_t i = 0; i < vnodeMgr.nthreads; i++) { + pthread_join(vnodeMgr.threads[i], NULL); + } + + tfree(vnodeMgr.threads); + pthread_cond_destroy(&(vnodeMgr.hasTask)); + pthread_mutex_destroy(&(vnodeMgr.mutex)); +} + +int vnodeScheduleTask(SVnodeTask* pTask) { + pthread_mutex_lock(&(vnodeMgr.mutex)); + + tDListAppend(&(vnodeMgr.queue), pTask); + + pthread_cond_signal(&(vnodeMgr.hasTask)); + + pthread_mutex_unlock(&(vnodeMgr.mutex)); + + return 0; +} + +/* ------------------------ STATIC METHODS ------------------------ */ +static void* loop(void* arg) { + SVnodeTask* pTask; + for (;;) { + pthread_mutex_lock(&(vnodeMgr.mutex)); + for (;;) { + pTask = TD_DLIST_HEAD(&(vnodeMgr.queue)); + if (pTask == NULL) { + if (vnodeMgr.stop) { + pthread_mutex_unlock(&(vnodeMgr.mutex)); + return NULL; + } else { + pthread_cond_wait(&(vnodeMgr.hasTask), &(vnodeMgr.mutex)); + } + } else { + tDListPop(&(vnodeMgr.queue), pTask); + break; + } + } + + pthread_mutex_unlock(&(vnodeMgr.mutex)); + + (*(pTask->execute))(pTask->arg); + } + + return NULL; +} \ No newline at end of file diff --git a/source/dnode/vnode/impl/src/vnodeWrite.c b/source/dnode/vnode/impl/src/vnodeWrite.c index cdeb894932..85460e8d91 100644 --- a/source/dnode/vnode/impl/src/vnodeWrite.c +++ b/source/dnode/vnode/impl/src/vnodeWrite.c @@ -72,7 +72,9 @@ int vnodeProcessWMsgs(SVnode *pVnode, SArray *pMsgs) { } break; case TSDB_MSG_TYPE_SUBMIT: - /* code */ + if (tsdbInsertData(pVnode->pTsdb, (SSubmitMsg *)ptr) < 0) { + // TODO: handle error + } break; default: break; diff --git a/source/dnode/vnode/impl/test/vnodeApiTests.cpp b/source/dnode/vnode/impl/test/vnodeApiTests.cpp index ac2ccbc132..f0bca3aa2e 100644 --- a/source/dnode/vnode/impl/test/vnodeApiTests.cpp +++ b/source/dnode/vnode/impl/test/vnodeApiTests.cpp @@ -92,7 +92,9 @@ TEST(vnodeApiTest, test_create_table_encode_and_decode_function) { #endif TEST(vnodeApiTest, vnodeOpen_vnodeClose_test) { - GTEST_ASSERT_GE(vnodeInit(), 0); + vnodeDestroy("vnode1"); + + GTEST_ASSERT_GE(vnodeInit(2), 0); // Create and open a vnode SVnode *pVnode = vnodeOpen("vnode1", NULL); diff --git a/source/dnode/vnode/tq/inc/tqMetaStore.h b/source/dnode/vnode/tq/inc/tqMetaStore.h index b9e702a89a..253852b00f 100644 --- a/source/dnode/vnode/tq/inc/tqMetaStore.h +++ b/source/dnode/vnode/tq/inc/tqMetaStore.h @@ -24,29 +24,29 @@ extern "C" { #endif -TqMetaStore* tqStoreOpen(const char* path, - TqSerializeFun pSerializer, - TqDeserializeFun pDeserializer, - TqDeleteFun pDeleter, +STqMetaStore* tqStoreOpen(const char* path, + FTqSerialize pSerializer, + FTqDeserialize pDeserializer, + FTqDelete pDeleter, int32_t tqConfigFlag ); -int32_t tqStoreClose(TqMetaStore*); +int32_t tqStoreClose(STqMetaStore*); //int32_t tqStoreDelete(TqMetaStore*); //int32_t tqStoreCommitAll(TqMetaStore*); -int32_t tqStorePersist(TqMetaStore*); +int32_t tqStorePersist(STqMetaStore*); //clean deleted idx and data from persistent file -int32_t tqStoreCompact(TqMetaStore*); +int32_t tqStoreCompact(STqMetaStore*); -void* tqHandleGet(TqMetaStore*, int64_t key); +void* tqHandleGet(STqMetaStore*, int64_t key); //make it unpersist -void* tqHandleTouchGet(TqMetaStore*, int64_t key); -int32_t tqHandleMovePut(TqMetaStore*, int64_t key, void* value); -int32_t tqHandleCopyPut(TqMetaStore*, int64_t key, void* value, size_t vsize); +void* tqHandleTouchGet(STqMetaStore*, int64_t key); +int32_t tqHandleMovePut(STqMetaStore*, int64_t key, void* value); +int32_t tqHandleCopyPut(STqMetaStore*, int64_t key, void* value, size_t vsize); //delete committed kv pair //notice that a delete action still needs to be committed -int32_t tqHandleDel(TqMetaStore*, int64_t key); -int32_t tqHandleCommit(TqMetaStore*, int64_t key); -int32_t tqHandleAbort(TqMetaStore*, int64_t key); +int32_t tqHandleDel(STqMetaStore*, int64_t key); +int32_t tqHandleCommit(STqMetaStore*, int64_t key); +int32_t tqHandleAbort(STqMetaStore*, int64_t key); #ifdef __cplusplus } diff --git a/source/dnode/vnode/tq/src/tq.c b/source/dnode/vnode/tq/src/tq.c index c1a46e567b..1326666857 100644 --- a/source/dnode/vnode/tq/src/tq.c +++ b/source/dnode/vnode/tq/src/tq.c @@ -16,75 +16,70 @@ #include "tqInt.h" #include "tqMetaStore.h" -//static -//read next version data +// static +// read next version data // -//send to fetch queue +// send to fetch queue // -//handle management message +// handle management message // -int tqGetgHandleSSize(const TqGroupHandle *gHandle); +int tqGetgHandleSSize(const STqGroupHandle* gHandle); int tqBufHandleSSize(); int tqBufItemSSize(); -TqGroupHandle* tqFindHandle(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { - TqGroupHandle* gHandle; +STqGroupHandle* tqFindHandle(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { + STqGroupHandle* gHandle; return NULL; } -void* tqSerializeListHandle(TqListHandle* listHandle, void* ptr); -void* tqSerializeBufHandle(TqBufferHandle* bufHandle, void* ptr); -void* tqSerializeBufItem(TqBufferItem* bufItem, void* ptr); +void* tqSerializeListHandle(STqListHandle* listHandle, void* ptr); +void* tqSerializeBufHandle(STqBufferHandle* bufHandle, void* ptr); +void* tqSerializeBufItem(STqBufferItem* bufItem, void* ptr); -const void* tqDeserializeBufHandle(const void* pBytes, TqBufferHandle* bufHandle); -const void* tqDeserializeBufItem(const void* pBytes, TqBufferItem* bufItem); +const void* tqDeserializeBufHandle(const void* pBytes, STqBufferHandle* bufHandle); +const void* tqDeserializeBufItem(const void* pBytes, STqBufferItem* bufItem); -STQ* tqOpen(const char* path, STqCfg* tqConfig, TqLogReader* tqLogReader, SMemAllocatorFactory *allocFac) { +STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemAllocatorFactory* allocFac) { STQ* pTq = malloc(sizeof(STQ)); - if(pTq == NULL) { - //TODO: memory error + if (pTq == NULL) { + // TODO: memory error return NULL; } pTq->path = strdup(path); pTq->tqConfig = tqConfig; pTq->tqLogReader = tqLogReader; - // pTq->tqMemRef.pAlloctorFactory = allocFac; - // pTq->tqMemRef.pAllocator = allocFac->create(allocFac); - if(pTq->tqMemRef.pAllocator == NULL) { - //TODO + pTq->tqMemRef.pAlloctorFactory = allocFac; + pTq->tqMemRef.pAllocator = allocFac->create(allocFac); + if (pTq->tqMemRef.pAllocator == NULL) { + // TODO } - pTq->tqMeta = tqStoreOpen(path, - (TqSerializeFun)tqSerializeGroupHandle, - (TqDeserializeFun)tqDeserializeGroupHandle, - free, - 0); - if(pTq->tqMeta == NULL) { - //TODO: free STQ + pTq->tqMeta = + tqStoreOpen(path, (FTqSerialize)tqSerializeGroupHandle, (FTqDeserialize)tqDeserializeGroupHandle, free, 0); + if (pTq->tqMeta == NULL) { + // TODO: free STQ return NULL; } return pTq; } -static int tqProtoCheck(TmqMsgHead *pMsg) { - return pMsg->protoVer == 0; -} +static int tqProtoCheck(TmqMsgHead* pMsg) { return pMsg->protoVer == 0; } -static int tqAckOneTopic(TqBufferHandle *bHandle, TmqOneAck *pAck, TqQueryMsg** ppQuery) { - //clean old item and move forward +static int tqAckOneTopic(STqBufferHandle* bHandle, TmqOneAck* pAck, STqQueryMsg** ppQuery) { + // clean old item and move forward int32_t consumeOffset = pAck->consumeOffset; - int idx = consumeOffset % TQ_BUFFER_SIZE; + int idx = consumeOffset % TQ_BUFFER_SIZE; ASSERT(bHandle->buffer[idx].content && bHandle->buffer[idx].executor); tfree(bHandle->buffer[idx].content); - if( 1 /* TODO: need to launch new query */) { - TqQueryMsg* pNewQuery = malloc(sizeof(TqQueryMsg)); - if(pNewQuery == NULL) { - //TODO: memory insufficient + if (1 /* TODO: need to launch new query */) { + STqQueryMsg* pNewQuery = malloc(sizeof(STqQueryMsg)); + if (pNewQuery == NULL) { + // TODO: memory insufficient return -1; } - //TODO: lock executor + // TODO: lock executor pNewQuery->exec->executor = bHandle->buffer[idx].executor; - //TODO: read from wal and assign to src + // TODO: read from wal and assign to src pNewQuery->exec->src = 0; pNewQuery->exec->dest = &bHandle->buffer[idx]; pNewQuery->next = *ppQuery; @@ -93,98 +88,94 @@ static int tqAckOneTopic(TqBufferHandle *bHandle, TmqOneAck *pAck, TqQueryMsg** return 0; } -static int tqAck(TqGroupHandle* gHandle, TmqAcks* pAcks) { - int32_t ackNum = pAcks->ackNum; - TmqOneAck *acks = pAcks->acks; - //double ptr for acks and list - int i = 0; - TqListHandle* node = gHandle->head; - int ackCnt = 0; - TqQueryMsg *pQuery = NULL; - while(i < ackNum && node->next) { - if(acks[i].topicId == node->next->bufHandle.topicId) { +static int tqAck(STqGroupHandle* gHandle, TmqAcks* pAcks) { + int32_t ackNum = pAcks->ackNum; + TmqOneAck* acks = pAcks->acks; + // double ptr for acks and list + int i = 0; + STqListHandle* node = gHandle->head; + int ackCnt = 0; + STqQueryMsg* pQuery = NULL; + while (i < ackNum && node->next) { + if (acks[i].topicId == node->next->bufHandle.topicId) { ackCnt++; tqAckOneTopic(&node->next->bufHandle, &acks[i], &pQuery); - } else if(acks[i].topicId < node->next->bufHandle.topicId) { + } else if (acks[i].topicId < node->next->bufHandle.topicId) { i++; } else { node = node->next; } } - if(pQuery) { - //post message + if (pQuery) { + // post message } return ackCnt; } -static int tqCommitTCGroup(TqGroupHandle* handle) { - //persist modification into disk +static int tqCommitTCGroup(STqGroupHandle* handle) { + // persist modification into disk return 0; } -int tqCreateTCGroup(STQ *pTq, int64_t topicId, int64_t cgId, int64_t cId, TqGroupHandle** handle) { - //create in disk - TqGroupHandle* gHandle = (TqGroupHandle*)malloc(sizeof(TqGroupHandle)); - if(gHandle == NULL) { - //TODO +int tqCreateTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId, STqGroupHandle** handle) { + // create in disk + STqGroupHandle* gHandle = (STqGroupHandle*)malloc(sizeof(STqGroupHandle)); + if (gHandle == NULL) { + // TODO return -1; } - memset(gHandle, 0, sizeof(TqGroupHandle)); + memset(gHandle, 0, sizeof(STqGroupHandle)); return 0; } -TqGroupHandle* tqOpenTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { - TqGroupHandle* gHandle = tqHandleGet(pTq->tqMeta, cId); - if(gHandle == NULL) { +STqGroupHandle* tqOpenTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { + STqGroupHandle* gHandle = tqHandleGet(pTq->tqMeta, cId); + if (gHandle == NULL) { int code = tqCreateTCGroup(pTq, topicId, cgId, cId, &gHandle); - if(code != 0) { - //TODO + if (code != 0) { + // TODO return NULL; } } - //create - //open + // create + // open return gHandle; } -int tqCloseTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { - return 0; -} +int tqCloseTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { return 0; } int tqDropTCGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) { - //delete from disk + // delete from disk return 0; } -static int tqFetch(TqGroupHandle* gHandle, void** msg) { - TqListHandle* head = gHandle->head; - TqListHandle* node = head; - int totSize = 0; - //TODO: make it a macro - int sizeLimit = 4 * 1024; +static int tqFetch(STqGroupHandle* gHandle, void** msg) { + STqListHandle* head = gHandle->head; + STqListHandle* node = head; + int totSize = 0; + // TODO: make it a macro + int sizeLimit = 4 * 1024; TmqMsgContent* buffer = malloc(sizeLimit); - if(buffer == NULL) { - //TODO:memory insufficient + if (buffer == NULL) { + // TODO:memory insufficient return -1; } - //iterate the list to get msgs of all topics - //until all topic iterated or msgs over sizeLimit - while(node->next) { + // iterate the list to get msgs of all topics + // until all topic iterated or msgs over sizeLimit + while (node->next) { node = node->next; - TqBufferHandle* bufHandle = &node->bufHandle; - int idx = bufHandle->nextConsumeOffset % TQ_BUFFER_SIZE; - if(bufHandle->buffer[idx].content != NULL && - bufHandle->buffer[idx].offset == bufHandle->nextConsumeOffset - ) { + STqBufferHandle* bufHandle = &node->bufHandle; + int idx = bufHandle->nextConsumeOffset % TQ_BUFFER_SIZE; + if (bufHandle->buffer[idx].content != NULL && bufHandle->buffer[idx].offset == bufHandle->nextConsumeOffset) { totSize += bufHandle->buffer[idx].size; - if(totSize > sizeLimit) { - void *ptr = realloc(buffer, totSize); - if(ptr == NULL) { + if (totSize > sizeLimit) { + void* ptr = realloc(buffer, totSize); + if (ptr == NULL) { totSize -= bufHandle->buffer[idx].size; - //TODO:memory insufficient - //return msgs already copied + // TODO:memory insufficient + // return msgs already copied break; } } @@ -194,7 +185,7 @@ static int tqFetch(TqGroupHandle* gHandle, void** msg) { buffer = POINTER_SHIFT(buffer, sizeof(int64_t)); memcpy(buffer, bufHandle->buffer[idx].content, bufHandle->buffer[idx].size); buffer = POINTER_SHIFT(buffer, bufHandle->buffer[idx].size); - if(totSize > sizeLimit) { + if (totSize > sizeLimit) { break; } } @@ -202,105 +193,98 @@ static int tqFetch(TqGroupHandle* gHandle, void** msg) { return totSize; } +STqGroupHandle* tqGetGroupHandle(STQ* pTq, int64_t cId) { return NULL; } -TqGroupHandle* tqGetGroupHandle(STQ* pTq, int64_t cId) { - return NULL; -} +int tqLaunchQuery(STqGroupHandle* gHandle) { return 0; } -int tqLaunchQuery(TqGroupHandle* gHandle) { - return 0; -} - -int tqSendLaunchQuery(TqGroupHandle* gHandle) { - return 0; -} +int tqSendLaunchQuery(STqGroupHandle* gHandle) { return 0; } /*int tqMoveOffsetToNext(TqGroupHandle* gHandle) {*/ - /*return 0;*/ +/*return 0;*/ /*}*/ -int tqPushMsg(STQ* pTq , void* p, int64_t version) { - //add reference - //judge and launch new query +int tqPushMsg(STQ* pTq, void* p, int64_t version) { + // add reference + // judge and launch new query return 0; } int tqCommit(STQ* pTq) { - //do nothing + // do nothing return 0; } int tqConsume(STQ* pTq, TmqConsumeReq* pMsg) { - if(!tqProtoCheck((TmqMsgHead *)pMsg)) { - //proto version invalid + if (!tqProtoCheck((TmqMsgHead*)pMsg)) { + // proto version invalid return -1; } - int64_t clientId = pMsg->head.clientId; - TqGroupHandle *gHandle = tqGetGroupHandle(pTq, clientId); - if(gHandle == NULL) { - //client not connect + int64_t clientId = pMsg->head.clientId; + STqGroupHandle* gHandle = tqGetGroupHandle(pTq, clientId); + if (gHandle == NULL) { + // client not connect return -1; } - if(pMsg->acks.ackNum != 0) { - if(tqAck(gHandle, &pMsg->acks) != 0) { - //ack not success + if (pMsg->acks.ackNum != 0) { + if (tqAck(gHandle, &pMsg->acks) != 0) { + // ack not success return -1; } } - TmqConsumeRsp *pRsp = (TmqConsumeRsp*) pMsg; + TmqConsumeRsp* pRsp = (TmqConsumeRsp*)pMsg; - if(tqFetch(gHandle, (void**)&pRsp->msgs) <= 0) { - //fetch error + if (tqFetch(gHandle, (void**)&pRsp->msgs) <= 0) { + // fetch error return -1; } - //judge and launch new query - if(tqLaunchQuery(gHandle)) { - //launch query error + // judge and launch new query + if (tqLaunchQuery(gHandle)) { + // launch query error return -1; } return 0; } -int tqSerializeGroupHandle(const TqGroupHandle *gHandle, TqSerializedHead** ppHead) { - //calculate size - int sz = tqGetgHandleSSize(gHandle) + sizeof(TqSerializedHead); - if(sz > (*ppHead)->ssize) { +int tqSerializeGroupHandle(const STqGroupHandle* gHandle, STqSerializedHead** ppHead) { + // calculate size + int sz = tqGetgHandleSSize(gHandle) + sizeof(STqSerializedHead); + if (sz > (*ppHead)->ssize) { void* tmpPtr = realloc(*ppHead, sz); - if(tmpPtr == NULL) { + if (tmpPtr == NULL) { free(*ppHead); - //TODO: memory err + // TODO: memory err return -1; } *ppHead = tmpPtr; (*ppHead)->ssize = sz; } void* ptr = (*ppHead)->content; - //do serialization + // do serialization *(int64_t*)ptr = gHandle->cId; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); *(int64_t*)ptr = gHandle->cgId; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); *(int32_t*)ptr = gHandle->topicNum; ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); - if(gHandle->topicNum > 0) { + if (gHandle->topicNum > 0) { tqSerializeListHandle(gHandle->head, ptr); } return 0; } -void* tqSerializeListHandle(TqListHandle *listHandle, void* ptr) { - TqListHandle *node = listHandle; +void* tqSerializeListHandle(STqListHandle* listHandle, void* ptr) { + STqListHandle* node = listHandle; ASSERT(node != NULL); - while(node) { + while (node) { ptr = tqSerializeBufHandle(&node->bufHandle, ptr); node = node->next; } return ptr; } -void* tqSerializeBufHandle(TqBufferHandle *bufHandle, void* ptr) { +void* tqSerializeBufHandle(STqBufferHandle* bufHandle, void* ptr) { *(int64_t*)ptr = bufHandle->nextConsumeOffset; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); *(int64_t*)ptr = bufHandle->topicId; @@ -309,21 +293,21 @@ void* tqSerializeBufHandle(TqBufferHandle *bufHandle, void* ptr) { ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); *(int32_t*)ptr = bufHandle->tail; ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); - for(int i = 0; i < TQ_BUFFER_SIZE; i++) { + for (int i = 0; i < TQ_BUFFER_SIZE; i++) { ptr = tqSerializeBufItem(&bufHandle->buffer[i], ptr); } return ptr; } -void* tqSerializeBufItem(TqBufferItem *bufItem, void* ptr) { - //TODO: do we need serialize this? - //mainly for executor +void* tqSerializeBufItem(STqBufferItem* bufItem, void* ptr) { + // TODO: do we need serialize this? + // mainly for executor return ptr; } -const void* tqDeserializeGroupHandle(const TqSerializedHead* pHead, TqGroupHandle **ppGHandle) { - TqGroupHandle *gHandle = *ppGHandle; - const void* ptr = pHead->content; +const void* tqDeserializeGroupHandle(const STqSerializedHead* pHead, STqGroupHandle** ppGHandle) { + STqGroupHandle* gHandle = *ppGHandle; + const void* ptr = pHead->content; gHandle->cId = *(int64_t*)ptr; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); gHandle->cgId = *(int64_t*)ptr; @@ -332,20 +316,20 @@ const void* tqDeserializeGroupHandle(const TqSerializedHead* pHead, TqGroupHandl gHandle->topicNum = *(int32_t*)ptr; ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); gHandle->head = NULL; - TqListHandle *node = gHandle->head; - for(int i = 0; i < gHandle->topicNum; i++) { - if(gHandle->head == NULL) { - if((node = malloc(sizeof(TqListHandle))) == NULL) { - //TODO: error + STqListHandle* node = gHandle->head; + for (int i = 0; i < gHandle->topicNum; i++) { + if (gHandle->head == NULL) { + if ((node = malloc(sizeof(STqListHandle))) == NULL) { + // TODO: error return NULL; } - node->next= NULL; - ptr = tqDeserializeBufHandle(ptr, &node->bufHandle); + node->next = NULL; + ptr = tqDeserializeBufHandle(ptr, &node->bufHandle); gHandle->head = node; } else { - node->next = malloc(sizeof(TqListHandle)); - if(node->next == NULL) { - //TODO: error + node->next = malloc(sizeof(STqListHandle)); + if (node->next == NULL) { + // TODO: error return NULL; } node->next->next = NULL; @@ -356,7 +340,7 @@ const void* tqDeserializeGroupHandle(const TqSerializedHead* pHead, TqGroupHandl return ptr; } -const void* tqDeserializeBufHandle(const void* pBytes, TqBufferHandle *bufHandle) { +const void* tqDeserializeBufHandle(const void* pBytes, STqBufferHandle* bufHandle) { const void* ptr = pBytes; bufHandle->nextConsumeOffset = *(int64_t*)ptr; ptr = POINTER_SHIFT(ptr, sizeof(int64_t)); @@ -366,32 +350,30 @@ const void* tqDeserializeBufHandle(const void* pBytes, TqBufferHandle *bufHandle ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); bufHandle->tail = *(int32_t*)ptr; ptr = POINTER_SHIFT(ptr, sizeof(int32_t)); - for(int i = 0; i < TQ_BUFFER_SIZE; i++) { + for (int i = 0; i < TQ_BUFFER_SIZE; i++) { ptr = tqDeserializeBufItem(ptr, &bufHandle->buffer[i]); } return ptr; } -const void* tqDeserializeBufItem(const void* pBytes, TqBufferItem *bufItem) { - return pBytes; +const void* tqDeserializeBufItem(const void* pBytes, STqBufferItem* bufItem) { return pBytes; } + +// TODO: make this a macro +int tqGetgHandleSSize(const STqGroupHandle* gHandle) { + return sizeof(int64_t) * 2 // cId + cgId + + sizeof(int32_t) // topicNum + + gHandle->topicNum * tqBufHandleSSize(); } -//TODO: make this a macro -int tqGetgHandleSSize(const TqGroupHandle *gHandle) { - return sizeof(int64_t) * 2 //cId + cgId - + sizeof(int32_t) //topicNum - + gHandle->topicNum * tqBufHandleSSize(); -} - -//TODO: make this a macro +// TODO: make this a macro int tqBufHandleSSize() { - return sizeof(int64_t) * 2 // nextConsumeOffset + topicId - + sizeof(int32_t) * 2 // head + tail - + TQ_BUFFER_SIZE * tqBufItemSSize(); + return sizeof(int64_t) * 2 // nextConsumeOffset + topicId + + sizeof(int32_t) * 2 // head + tail + + TQ_BUFFER_SIZE * tqBufItemSSize(); } int tqBufItemSSize() { - //TODO: do this need serialization? - //mainly for executor + // TODO: do this need serialization? + // mainly for executor return 0; } diff --git a/source/dnode/vnode/tq/src/tqMetaStore.c b/source/dnode/vnode/tq/src/tqMetaStore.c index 81b48191bc..082f0ad28e 100644 --- a/source/dnode/vnode/tq/src/tqMetaStore.c +++ b/source/dnode/vnode/tq/src/tqMetaStore.c @@ -13,21 +13,20 @@ * along with this program. If not, see . */ #include "tqMetaStore.h" -//TODO:replace by an abstract file layer -#include "osDir.h" +// TODO:replace by an abstract file layer #include #include #include +#include "osDir.h" #define TQ_META_NAME "tq.meta" -#define TQ_IDX_NAME "tq.idx" +#define TQ_IDX_NAME "tq.idx" +static int32_t tqHandlePutCommitted(STqMetaStore*, int64_t key, void* value); +static void* tqHandleGetUncommitted(STqMetaStore*, int64_t key); -static int32_t tqHandlePutCommitted(TqMetaStore*, int64_t key, void* value); -static void* tqHandleGetUncommitted(TqMetaStore*, int64_t key); - -static inline void tqLinkUnpersist(TqMetaStore *pMeta, TqMetaList* pNode) { - if(pNode->unpersistNext == NULL) { +static inline void tqLinkUnpersist(STqMetaStore* pMeta, STqMetaList* pNode) { + if (pNode->unpersistNext == NULL) { pNode->unpersistNext = pMeta->unpersistHead->unpersistNext; pNode->unpersistPrev = pMeta->unpersistHead; pMeta->unpersistHead->unpersistNext->unpersistPrev = pNode; @@ -42,24 +41,24 @@ static inline int tqSeekLastPage(int fd) { return lseek(fd, curPageOffset, SEEK_SET); } -//TODO: the struct is tightly coupled with index entry -typedef struct TqIdxPageHead { +// TODO: the struct is tightly coupled with index entry +typedef struct STqIdxPageHead { int16_t writeOffset; int8_t unused[14]; -} TqIdxPageHead; +} STqIdxPageHead; -typedef struct TqIdxPageBuf { - TqIdxPageHead head; - char buffer[TQ_IDX_PAGE_BODY_SIZE]; -} TqIdxPageBuf; +typedef struct STqIdxPageBuf { + STqIdxPageHead head; + char buffer[TQ_IDX_PAGE_BODY_SIZE]; +} STqIdxPageBuf; -static inline int tqReadLastPage(int fd, TqIdxPageBuf* pBuf) { +static inline int tqReadLastPage(int fd, STqIdxPageBuf* pBuf) { int offset = tqSeekLastPage(fd); int nBytes; - if((nBytes = read(fd, pBuf, TQ_PAGE_SIZE)) == -1) { + if ((nBytes = read(fd, pBuf, TQ_PAGE_SIZE)) == -1) { return -1; } - if(nBytes == 0) { + if (nBytes == 0) { memset(pBuf, 0, TQ_PAGE_SIZE); pBuf->head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE; } @@ -68,28 +67,24 @@ static inline int tqReadLastPage(int fd, TqIdxPageBuf* pBuf) { return lseek(fd, offset, SEEK_SET); } -TqMetaStore* tqStoreOpen(const char* path, - TqSerializeFun serializer, - TqDeserializeFun deserializer, - TqDeleteFun deleter, - int32_t tqConfigFlag - ) { - TqMetaStore* pMeta = malloc(sizeof(TqMetaStore)); - if(pMeta == NULL) { - //close +STqMetaStore* tqStoreOpen(const char* path, FTqSerialize serializer, FTqDeserialize deserializer, FTqDelete deleter, + int32_t tqConfigFlag) { + STqMetaStore* pMeta = malloc(sizeof(STqMetaStore)); + if (pMeta == NULL) { + // close return NULL; } - memset(pMeta, 0, sizeof(TqMetaStore)); + memset(pMeta, 0, sizeof(STqMetaStore)); - //concat data file name and index file name + // concat data file name and index file name size_t pathLen = strlen(path); - pMeta->dirPath = malloc(pathLen+1); - if(pMeta->dirPath != NULL) { - //TODO: memory insufficient + pMeta->dirPath = malloc(pathLen + 1); + if (pMeta->dirPath != NULL) { + // TODO: memory insufficient } strcpy(pMeta->dirPath, path); - - char name[pathLen+10]; + + char name[pathLen + 10]; strcpy(name, path); if (taosDirExist(name) != 0 && taosMkDir(name) != 0) { @@ -97,98 +92,96 @@ TqMetaStore* tqStoreOpen(const char* path, } strcat(name, "/" TQ_IDX_NAME); int idxFd = open(name, O_RDWR | O_CREAT, 0755); - if(idxFd < 0) { + if (idxFd < 0) { ASSERT(false); - //close file - //free memory + // close file + // free memory return NULL; } pMeta->idxFd = idxFd; - pMeta->unpersistHead = malloc(sizeof(TqMetaList)); - if(pMeta->unpersistHead == NULL) { + pMeta->unpersistHead = malloc(sizeof(STqMetaList)); + if (pMeta->unpersistHead == NULL) { ASSERT(false); - //close file - //free memory + // close file + // free memory return NULL; } - memset(pMeta->unpersistHead, 0, sizeof(TqMetaList)); - pMeta->unpersistHead->unpersistNext - = pMeta->unpersistHead->unpersistPrev - = pMeta->unpersistHead; + memset(pMeta->unpersistHead, 0, sizeof(STqMetaList)); + pMeta->unpersistHead->unpersistNext = pMeta->unpersistHead->unpersistPrev = pMeta->unpersistHead; strcpy(name, path); strcat(name, "/" TQ_META_NAME); int fileFd = open(name, O_RDWR | O_CREAT, 0755); - if(fileFd < 0){ + if (fileFd < 0) { ASSERT(false); return NULL; } pMeta->fileFd = fileFd; - + pMeta->pSerializer = serializer; pMeta->pDeserializer = deserializer; pMeta->pDeleter = deleter; pMeta->tqConfigFlag = tqConfigFlag; - //read idx file and load into memory - TqIdxPageBuf idxBuf; - TqSerializedHead* serializedObj = malloc(TQ_PAGE_SIZE); - if(serializedObj == NULL) { - //TODO:memory insufficient + // read idx file and load into memory + STqIdxPageBuf idxBuf; + STqSerializedHead* serializedObj = malloc(TQ_PAGE_SIZE); + if (serializedObj == NULL) { + // TODO:memory insufficient } - int idxRead; - int allocated = TQ_PAGE_SIZE; + int idxRead; + int allocated = TQ_PAGE_SIZE; bool readEnd = false; - while((idxRead = read(idxFd, &idxBuf, TQ_PAGE_SIZE))) { - if(idxRead == -1) { - //TODO: handle error + while ((idxRead = read(idxFd, &idxBuf, TQ_PAGE_SIZE))) { + if (idxRead == -1) { + // TODO: handle error ASSERT(false); } ASSERT(idxBuf.head.writeOffset == idxRead); - //loop read every entry - for(int i = 0; i < idxBuf.head.writeOffset - TQ_IDX_PAGE_HEAD_SIZE; i += TQ_IDX_SIZE) { - TqMetaList *pNode = malloc(sizeof(TqMetaList)); - if(pNode == NULL) { - //TODO: free memory and return error + // loop read every entry + for (int i = 0; i < idxBuf.head.writeOffset - TQ_IDX_PAGE_HEAD_SIZE; i += TQ_IDX_SIZE) { + STqMetaList* pNode = malloc(sizeof(STqMetaList)); + if (pNode == NULL) { + // TODO: free memory and return error } - memset(pNode, 0, sizeof(TqMetaList)); + memset(pNode, 0, sizeof(STqMetaList)); memcpy(&pNode->handle, &idxBuf.buffer[i], TQ_IDX_SIZE); lseek(fileFd, pNode->handle.offset, SEEK_SET); - if(allocated < pNode->handle.serializedSize) { - void *ptr = realloc(serializedObj, pNode->handle.serializedSize); - if(ptr == NULL) { - //TODO: memory insufficient + if (allocated < pNode->handle.serializedSize) { + void* ptr = realloc(serializedObj, pNode->handle.serializedSize); + if (ptr == NULL) { + // TODO: memory insufficient } serializedObj = ptr; allocated = pNode->handle.serializedSize; } serializedObj->ssize = pNode->handle.serializedSize; - if(read(fileFd, serializedObj, pNode->handle.serializedSize) != pNode->handle.serializedSize) { - //TODO: read error + if (read(fileFd, serializedObj, pNode->handle.serializedSize) != pNode->handle.serializedSize) { + // TODO: read error } - if(serializedObj->action == TQ_ACTION_INUSE) { - if(serializedObj->ssize != sizeof(TqSerializedHead)) { + if (serializedObj->action == TQ_ACTION_INUSE) { + if (serializedObj->ssize != sizeof(STqSerializedHead)) { pMeta->pDeserializer(serializedObj, &pNode->handle.valueInUse); } else { pNode->handle.valueInUse = TQ_DELETE_TOKEN; } - } else if(serializedObj->action == TQ_ACTION_INTXN) { - if(serializedObj->ssize != sizeof(TqSerializedHead)) { + } else if (serializedObj->action == TQ_ACTION_INTXN) { + if (serializedObj->ssize != sizeof(STqSerializedHead)) { pMeta->pDeserializer(serializedObj, &pNode->handle.valueInTxn); } else { pNode->handle.valueInTxn = TQ_DELETE_TOKEN; } - } else if(serializedObj->action == TQ_ACTION_INUSE_CONT) { - if(serializedObj->ssize != sizeof(TqSerializedHead)) { + } else if (serializedObj->action == TQ_ACTION_INUSE_CONT) { + if (serializedObj->ssize != sizeof(STqSerializedHead)) { pMeta->pDeserializer(serializedObj, &pNode->handle.valueInUse); } else { pNode->handle.valueInUse = TQ_DELETE_TOKEN; } - TqSerializedHead* ptr = POINTER_SHIFT(serializedObj, serializedObj->ssize); - if(ptr->ssize != sizeof(TqSerializedHead)) { + STqSerializedHead* ptr = POINTER_SHIFT(serializedObj, serializedObj->ssize); + if (ptr->ssize != sizeof(STqSerializedHead)) { pMeta->pDeserializer(ptr, &pNode->handle.valueInTxn); } else { pNode->handle.valueInTxn = TQ_DELETE_TOKEN; @@ -197,22 +190,21 @@ TqMetaStore* tqStoreOpen(const char* path, ASSERT(0); } - //put into list - int bucketKey = pNode->handle.key & TQ_BUCKET_MASK; - TqMetaList* pBucketNode = pMeta->bucket[bucketKey]; - if(pBucketNode == NULL) { + // put into list + int bucketKey = pNode->handle.key & TQ_BUCKET_MASK; + STqMetaList* pBucketNode = pMeta->bucket[bucketKey]; + if (pBucketNode == NULL) { pMeta->bucket[bucketKey] = pNode; - } else if(pBucketNode->handle.key == pNode->handle.key) { + } else if (pBucketNode->handle.key == pNode->handle.key) { pNode->next = pBucketNode->next; pMeta->bucket[bucketKey] = pNode; } else { - while(pBucketNode->next && - pBucketNode->next->handle.key != pNode->handle.key) { - pBucketNode = pBucketNode->next; + while (pBucketNode->next && pBucketNode->next->handle.key != pNode->handle.key) { + pBucketNode = pBucketNode->next; } - if(pBucketNode->next) { + if (pBucketNode->next) { ASSERT(pBucketNode->next->handle.key == pNode->handle.key); - TqMetaList *pNodeFound = pBucketNode->next; + STqMetaList* pNodeFound = pBucketNode->next; pNode->next = pNodeFound->next; pBucketNode->next = pNode; pBucketNode = pNodeFound; @@ -222,13 +214,11 @@ TqMetaStore* tqStoreOpen(const char* path, pBucketNode = NULL; } } - if(pBucketNode) { - if(pBucketNode->handle.valueInUse - && pBucketNode->handle.valueInUse != TQ_DELETE_TOKEN) { + if (pBucketNode) { + if (pBucketNode->handle.valueInUse && pBucketNode->handle.valueInUse != TQ_DELETE_TOKEN) { pMeta->pDeleter(pBucketNode->handle.valueInUse); } - if(pBucketNode->handle.valueInTxn - && pBucketNode->handle.valueInTxn != TQ_DELETE_TOKEN) { + if (pBucketNode->handle.valueInTxn && pBucketNode->handle.valueInTxn != TQ_DELETE_TOKEN) { pMeta->pDeleter(pBucketNode->handle.valueInTxn); } free(pBucketNode); @@ -239,27 +229,25 @@ TqMetaStore* tqStoreOpen(const char* path, return pMeta; } -int32_t tqStoreClose(TqMetaStore* pMeta) { - //commit data and idx +int32_t tqStoreClose(STqMetaStore* pMeta) { + // commit data and idx tqStorePersist(pMeta); - ASSERT(pMeta->unpersistHead && pMeta->unpersistHead->next==NULL); + ASSERT(pMeta->unpersistHead && pMeta->unpersistHead->next == NULL); close(pMeta->fileFd); close(pMeta->idxFd); - //free memory - for(int i = 0; i < TQ_BUCKET_SIZE; i++) { - TqMetaList* pNode = pMeta->bucket[i]; - while(pNode) { + // free memory + for (int i = 0; i < TQ_BUCKET_SIZE; i++) { + STqMetaList* pNode = pMeta->bucket[i]; + while (pNode) { ASSERT(pNode->unpersistNext == NULL); ASSERT(pNode->unpersistPrev == NULL); - if(pNode->handle.valueInTxn - && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInTxn && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInTxn); } - if(pNode->handle.valueInUse - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInUse); } - TqMetaList* next = pNode->next; + STqMetaList* next = pNode->next; free(pNode); pNode = next; } @@ -270,23 +258,21 @@ int32_t tqStoreClose(TqMetaStore* pMeta) { return 0; } -int32_t tqStoreDelete(TqMetaStore* pMeta) { +int32_t tqStoreDelete(STqMetaStore* pMeta) { close(pMeta->fileFd); close(pMeta->idxFd); - //free memory - for(int i = 0; i < TQ_BUCKET_SIZE; i++) { - TqMetaList* pNode = pMeta->bucket[i]; + // free memory + for (int i = 0; i < TQ_BUCKET_SIZE; i++) { + STqMetaList* pNode = pMeta->bucket[i]; pMeta->bucket[i] = NULL; - while(pNode) { - if(pNode->handle.valueInTxn - && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { + while (pNode) { + if (pNode->handle.valueInTxn && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInTxn); } - if(pNode->handle.valueInUse - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInUse); } - TqMetaList* next = pNode->next; + STqMetaList* next = pNode->next; free(pNode); pNode = next; } @@ -298,26 +284,26 @@ int32_t tqStoreDelete(TqMetaStore* pMeta) { return 0; } -//TODO: wrap in tfile -int32_t tqStorePersist(TqMetaStore* pMeta) { - TqIdxPageBuf idxBuf; - int64_t* bufPtr = (int64_t*)idxBuf.buffer; - TqMetaList *pHead = pMeta->unpersistHead; - TqMetaList *pNode = pHead->unpersistNext; - TqSerializedHead *pSHead = malloc(sizeof(TqSerializedHead)); - if(pSHead == NULL) { - //TODO: memory error +// TODO: wrap in tfile +int32_t tqStorePersist(STqMetaStore* pMeta) { + STqIdxPageBuf idxBuf; + int64_t* bufPtr = (int64_t*)idxBuf.buffer; + STqMetaList* pHead = pMeta->unpersistHead; + STqMetaList* pNode = pHead->unpersistNext; + STqSerializedHead* pSHead = malloc(sizeof(STqSerializedHead)); + if (pSHead == NULL) { + // TODO: memory error return -1; } pSHead->ver = TQ_SVER; pSHead->checksum = 0; - pSHead->ssize = sizeof(TqSerializedHead); - int allocatedSize = sizeof(TqSerializedHead); + pSHead->ssize = sizeof(STqSerializedHead); + int allocatedSize = sizeof(STqSerializedHead); int offset = lseek(pMeta->fileFd, 0, SEEK_CUR); tqReadLastPage(pMeta->idxFd, &idxBuf); - if(idxBuf.head.writeOffset == TQ_PAGE_SIZE) { + if (idxBuf.head.writeOffset == TQ_PAGE_SIZE) { lseek(pMeta->idxFd, 0, SEEK_END); memset(&idxBuf, 0, TQ_PAGE_SIZE); idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE; @@ -325,18 +311,18 @@ int32_t tqStorePersist(TqMetaStore* pMeta) { bufPtr = POINTER_SHIFT(&idxBuf, idxBuf.head.writeOffset); } - while(pHead != pNode) { + while (pHead != pNode) { int nBytes = 0; - if(pNode->handle.valueInUse) { - if(pNode->handle.valueInTxn) { + if (pNode->handle.valueInUse) { + if (pNode->handle.valueInTxn) { pSHead->action = TQ_ACTION_INUSE_CONT; } else { pSHead->action = TQ_ACTION_INUSE; } - if(pNode->handle.valueInUse == TQ_DELETE_TOKEN) { - pSHead->ssize = sizeof(TqSerializedHead); + if (pNode->handle.valueInUse == TQ_DELETE_TOKEN) { + pSHead->ssize = sizeof(STqSerializedHead); } else { pMeta->pSerializer(pNode->handle.valueInUse, &pSHead); } @@ -344,10 +330,10 @@ int32_t tqStorePersist(TqMetaStore* pMeta) { ASSERT(nBytes == pSHead->ssize); } - if(pNode->handle.valueInTxn) { + if (pNode->handle.valueInTxn) { pSHead->action = TQ_ACTION_INTXN; - if(pNode->handle.valueInTxn == TQ_DELETE_TOKEN) { - pSHead->ssize = sizeof(TqSerializedHead); + if (pNode->handle.valueInTxn == TQ_DELETE_TOKEN) { + pSHead->ssize = sizeof(STqSerializedHead); } else { pMeta->pSerializer(pNode->handle.valueInTxn, &pSHead); } @@ -358,42 +344,39 @@ int32_t tqStorePersist(TqMetaStore* pMeta) { pNode->handle.offset = offset; offset += nBytes; - //write idx file - //TODO: endian check and convert + // write idx file + // TODO: endian check and convert *(bufPtr++) = pNode->handle.key; *(bufPtr++) = pNode->handle.offset; *(bufPtr++) = (int64_t)nBytes; idxBuf.head.writeOffset += TQ_IDX_SIZE; - if(idxBuf.head.writeOffset >= TQ_PAGE_SIZE) { + if (idxBuf.head.writeOffset >= TQ_PAGE_SIZE) { nBytes = write(pMeta->idxFd, &idxBuf, TQ_PAGE_SIZE); - //TODO: handle error with tfile + // TODO: handle error with tfile ASSERT(nBytes == TQ_PAGE_SIZE); memset(&idxBuf, 0, TQ_PAGE_SIZE); idxBuf.head.writeOffset = TQ_IDX_PAGE_HEAD_SIZE; bufPtr = (int64_t*)&idxBuf.buffer; } - //remove from unpersist list + // remove from unpersist list pHead->unpersistNext = pNode->unpersistNext; pHead->unpersistNext->unpersistPrev = pHead; pNode->unpersistPrev = pNode->unpersistNext = NULL; pNode = pHead->unpersistNext; - //remove from bucket - if(pNode->handle.valueInUse == TQ_DELETE_TOKEN && - pNode->handle.valueInTxn == NULL - ) { - int bucketKey = pNode->handle.key & TQ_BUCKET_MASK; - TqMetaList* pBucketHead = pMeta->bucket[bucketKey]; - if(pBucketHead == pNode) { + // remove from bucket + if (pNode->handle.valueInUse == TQ_DELETE_TOKEN && pNode->handle.valueInTxn == NULL) { + int bucketKey = pNode->handle.key & TQ_BUCKET_MASK; + STqMetaList* pBucketHead = pMeta->bucket[bucketKey]; + if (pBucketHead == pNode) { pMeta->bucket[bucketKey] = pNode->next; } else { - TqMetaList* pBucketNode = pBucketHead; - while(pBucketNode->next != NULL - && pBucketNode->next != pNode) { - pBucketNode = pBucketNode->next; + STqMetaList* pBucketNode = pBucketHead; + while (pBucketNode->next != NULL && pBucketNode->next != pNode) { + pBucketNode = pBucketNode->next; } - //impossible for pBucket->next == NULL + // impossible for pBucket->next == NULL ASSERT(pBucketNode->next == pNode); pBucketNode->next = pNode->next; } @@ -401,46 +384,45 @@ int32_t tqStorePersist(TqMetaStore* pMeta) { } } - //write left bytes + // write left bytes free(pSHead); - //TODO: write new version in tfile - if((char*)bufPtr != idxBuf.buffer) { + // TODO: write new version in tfile + if ((char*)bufPtr != idxBuf.buffer) { int nBytes = write(pMeta->idxFd, &idxBuf, idxBuf.head.writeOffset); - //TODO: handle error in tfile + // TODO: handle error in tfile ASSERT(nBytes == idxBuf.head.writeOffset); } - //TODO: using fsync in tfile + // TODO: using fsync in tfile fsync(pMeta->idxFd); fsync(pMeta->fileFd); return 0; } -static int32_t tqHandlePutCommitted(TqMetaStore* pMeta, int64_t key, void* value) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - //TODO: think about thread safety - if(pNode->handle.valueInUse - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { +static int32_t tqHandlePutCommitted(STqMetaStore* pMeta, int64_t key, void* value) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + // TODO: think about thread safety + if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInUse); } - //change pointer ownership + // change pointer ownership pNode->handle.valueInUse = value; return 0; } else { pNode = pNode->next; } } - TqMetaList *pNewNode = malloc(sizeof(TqMetaList)); - if(pNewNode == NULL) { - //TODO: memory error + STqMetaList* pNewNode = malloc(sizeof(STqMetaList)); + if (pNewNode == NULL) { + // TODO: memory error return -1; } - memset(pNewNode, 0, sizeof(TqMetaList)); + memset(pNewNode, 0, sizeof(STqMetaList)); pNewNode->handle.key = key; pNewNode->handle.valueInUse = value; - //put into unpersist list + // put into unpersist list pNewNode->unpersistPrev = pMeta->unpersistHead; pNewNode->unpersistNext = pMeta->unpersistHead->unpersistNext; pMeta->unpersistHead->unpersistNext->unpersistPrev = pNewNode; @@ -448,13 +430,12 @@ static int32_t tqHandlePutCommitted(TqMetaStore* pMeta, int64_t key, void* value return 0; } -void* tqHandleGet(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - if(pNode->handle.valueInUse != NULL - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { +void* tqHandleGet(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + if (pNode->handle.valueInUse != NULL && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { return pNode->handle.valueInUse; } else { return NULL; @@ -466,13 +447,12 @@ void* tqHandleGet(TqMetaStore* pMeta, int64_t key) { return NULL; } -void* tqHandleTouchGet(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - if(pNode->handle.valueInUse != NULL - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { +void* tqHandleTouchGet(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + if (pNode->handle.valueInUse != NULL && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { tqLinkUnpersist(pMeta, pNode); return pNode->handle.valueInUse; } else { @@ -485,17 +465,17 @@ void* tqHandleTouchGet(TqMetaStore* pMeta, int64_t key) { return NULL; } -static inline int32_t tqHandlePutImpl(TqMetaStore* pMeta, int64_t key, void* value) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - //TODO: think about thread safety - if(pNode->handle.valueInTxn) { - if(TqDupIntxnReject(pMeta->tqConfigFlag)) { +static inline int32_t tqHandlePutImpl(STqMetaStore* pMeta, int64_t key, void* value) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + // TODO: think about thread safety + if (pNode->handle.valueInTxn) { + if (TqDupIntxnReject(pMeta->tqConfigFlag)) { return -2; } - if(pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInTxn); } } @@ -506,12 +486,12 @@ static inline int32_t tqHandlePutImpl(TqMetaStore* pMeta, int64_t key, void* val pNode = pNode->next; } } - TqMetaList *pNewNode = malloc(sizeof(TqMetaList)); - if(pNewNode == NULL) { - //TODO: memory error + STqMetaList* pNewNode = malloc(sizeof(STqMetaList)); + if (pNewNode == NULL) { + // TODO: memory error return -1; } - memset(pNewNode, 0, sizeof(TqMetaList)); + memset(pNewNode, 0, sizeof(STqMetaList)); pNewNode->handle.key = key; pNewNode->handle.valueInTxn = value; pNewNode->next = pMeta->bucket[bucketKey]; @@ -520,27 +500,24 @@ static inline int32_t tqHandlePutImpl(TqMetaStore* pMeta, int64_t key, void* val return 0; } -int32_t tqHandleMovePut(TqMetaStore* pMeta, int64_t key, void* value) { - return tqHandlePutImpl(pMeta, key, value); -} +int32_t tqHandleMovePut(STqMetaStore* pMeta, int64_t key, void* value) { return tqHandlePutImpl(pMeta, key, value); } -int32_t tqHandleCopyPut(TqMetaStore* pMeta, int64_t key, void* value, size_t vsize) { - void *vmem = malloc(vsize); - if(vmem == NULL) { - //TODO: memory error +int32_t tqHandleCopyPut(STqMetaStore* pMeta, int64_t key, void* value, size_t vsize) { + void* vmem = malloc(vsize); + if (vmem == NULL) { + // TODO: memory error return -1; } memcpy(vmem, value, vsize); return tqHandlePutImpl(pMeta, key, vmem); } -static void* tqHandleGetUncommitted(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - if(pNode->handle.valueInTxn != NULL - && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { +static void* tqHandleGetUncommitted(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + if (pNode->handle.valueInTxn != NULL && pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { return pNode->handle.valueInTxn; } else { return NULL; @@ -552,16 +529,15 @@ static void* tqHandleGetUncommitted(TqMetaStore* pMeta, int64_t key) { return NULL; } -int32_t tqHandleCommit(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - if(pNode->handle.valueInTxn == NULL) { +int32_t tqHandleCommit(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + if (pNode->handle.valueInTxn == NULL) { return -1; } - if(pNode->handle.valueInUse - && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInUse && pNode->handle.valueInUse != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInUse); } pNode->handle.valueInUse = pNode->handle.valueInTxn; @@ -575,13 +551,13 @@ int32_t tqHandleCommit(TqMetaStore* pMeta, int64_t key) { return -2; } -int32_t tqHandleAbort(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.key == key) { - if(pNode->handle.valueInTxn) { - if(pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { +int32_t tqHandleAbort(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.key == key) { + if (pNode->handle.valueInTxn) { + if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { pMeta->pDeleter(pNode->handle.valueInTxn); } pNode->handle.valueInTxn = NULL; @@ -596,14 +572,15 @@ int32_t tqHandleAbort(TqMetaStore* pMeta, int64_t key) { return -2; } -int32_t tqHandleDel(TqMetaStore* pMeta, int64_t key) { - int64_t bucketKey = key & TQ_BUCKET_MASK; - TqMetaList* pNode = pMeta->bucket[bucketKey]; - while(pNode) { - if(pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { - if(pNode->handle.valueInTxn) { +int32_t tqHandleDel(STqMetaStore* pMeta, int64_t key) { + int64_t bucketKey = key & TQ_BUCKET_MASK; + STqMetaList* pNode = pMeta->bucket[bucketKey]; + while (pNode) { + if (pNode->handle.valueInTxn != TQ_DELETE_TOKEN) { + if (pNode->handle.valueInTxn) { pMeta->pDeleter(pNode->handle.valueInTxn); } + pNode->handle.valueInTxn = TQ_DELETE_TOKEN; tqLinkUnpersist(pMeta, pNode); return 0; @@ -611,11 +588,9 @@ int32_t tqHandleDel(TqMetaStore* pMeta, int64_t key) { pNode = pNode->next; } } - //no such key + // no such key return -1; } -//TODO: clean deleted idx and data from persistent file -int32_t tqStoreCompact(TqMetaStore *pMeta) { - return 0; -} +// TODO: clean deleted idx and data from persistent file +int32_t tqStoreCompact(STqMetaStore* pMeta) { return 0; } diff --git a/source/dnode/vnode/tq/test/tqMetaTest.cpp b/source/dnode/vnode/tq/test/tqMetaTest.cpp index bbd436ab1a..58263efa71 100644 --- a/source/dnode/vnode/tq/test/tqMetaTest.cpp +++ b/source/dnode/vnode/tq/test/tqMetaTest.cpp @@ -9,17 +9,17 @@ struct Foo { int32_t a; }; -int FooSerializer(const void* pObj, TqSerializedHead** ppHead) { +int FooSerializer(const void* pObj, STqSerializedHead** ppHead) { Foo* foo = (Foo*) pObj; - if((*ppHead) == NULL || (*ppHead)->ssize < sizeof(TqSerializedHead) + sizeof(int32_t)) { - *ppHead = (TqSerializedHead*)realloc(*ppHead, sizeof(TqSerializedHead) + sizeof(int32_t)); - (*ppHead)->ssize = sizeof(TqSerializedHead) + sizeof(int32_t); + if((*ppHead) == NULL || (*ppHead)->ssize < sizeof(STqSerializedHead) + sizeof(int32_t)) { + *ppHead = (STqSerializedHead*)realloc(*ppHead, sizeof(STqSerializedHead) + sizeof(int32_t)); + (*ppHead)->ssize = sizeof(STqSerializedHead) + sizeof(int32_t); } *(int32_t*)(*ppHead)->content = foo->a; return (*ppHead)->ssize; } -const void* FooDeserializer(const TqSerializedHead* pHead, void** ppObj) { +const void* FooDeserializer(const STqSerializedHead* pHead, void** ppObj) { if(*ppObj == NULL) { *ppObj = realloc(*ppObj, sizeof(int32_t)); } diff --git a/source/dnode/vnode/tsdb/inc/tsdbDef.h b/source/dnode/vnode/tsdb/inc/tsdbDef.h index 0a57f5f670..7c593cb4c7 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbDef.h +++ b/source/dnode/vnode/tsdb/inc/tsdbDef.h @@ -17,6 +17,10 @@ #define _TD_TSDB_DEF_H_ #include "mallocator.h" +#include "taosmsg.h" +#include "tdlist.h" +#include "thash.h" +#include "tskiplist.h" #include "tsdb.h" #include "tsdbMemTable.h" @@ -29,6 +33,8 @@ extern "C" { struct STsdb { char * path; STsdbCfg options; + STsdbMemTable * mem; + STsdbMemTable * imem; SMemAllocatorFactory *pmaf; }; diff --git a/source/dnode/vnode/tsdb/inc/tsdbMemTable.h b/source/dnode/vnode/tsdb/inc/tsdbMemTable.h index 6be90ef53c..e7787af7cf 100644 --- a/source/dnode/vnode/tsdb/inc/tsdbMemTable.h +++ b/source/dnode/vnode/tsdb/inc/tsdbMemTable.h @@ -22,10 +22,11 @@ extern "C" { #endif -typedef struct SMemTable { - /* TODO */ - SMemAllocator *pma; -} SMemTable; +typedef struct STsdbMemTable STsdbMemTable; + +STsdbMemTable *tsdbNewMemTable(SMemAllocatorFactory *pMAF); +void tsdbFreeMemTable(SMemAllocatorFactory *pMAF, STsdbMemTable *pMemTable); +int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitMsg *pMsg); #ifdef __cplusplus } diff --git a/src/inc/tp.h b/source/dnode/vnode/tsdb/src/tsdbCommit.c similarity index 74% rename from src/inc/tp.h rename to source/dnode/vnode/tsdb/src/tsdbCommit.c index 1d6570898e..b124197736 100644 --- a/src/inc/tp.h +++ b/source/dnode/vnode/tsdb/src/tsdbCommit.c @@ -13,19 +13,9 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_TP -#define TDENGINE_TP +#include "tsdbDef.h" -#ifdef __cplusplus -extern "C" { -#endif - -int32_t tpInit(); -void tpCleanUp(); -void tpUpdateTs(int32_t vgId, int64_t *seq, void *pMsg); - -#ifdef __cplusplus -} -#endif - -#endif +int tsdbCommit(STsdb *pTsdb) { + // TODO + return 0; +} \ No newline at end of file diff --git a/source/dnode/vnode/tsdb/src/tsdbMemTable.c b/source/dnode/vnode/tsdb/src/tsdbMemTable.c index 6dea4a4e57..e3d1f8673e 100644 --- a/source/dnode/vnode/tsdb/src/tsdbMemTable.c +++ b/source/dnode/vnode/tsdb/src/tsdbMemTable.c @@ -11,4 +11,84 @@ * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . - */ \ No newline at end of file + */ + +#include "tsdbDef.h" + +#if 1 +typedef struct STbData { + TD_SLIST_NODE(STbData); + SSubmitMsg *pMsg; +} STbData; +#else +typedef struct STbData { + TD_SLIST_NODE(STbData); + uint64_t uid; // TODO: change here as tb_uid_t + TSKEY keyMin; + TSKEY keyMax; + uint64_t nRows; + SSkipList *pData; // Here need a container, may not use the SL + T_REF_DECLARE() +} STbData; +#endif + +struct STsdbMemTable { + T_REF_DECLARE() + SRWLatch latch; + TSKEY keyMin; + TSKEY keyMax; + uint64_t nRow; + SMemAllocator *pMA; + // Container + TD_SLIST(STbData) list; +}; + +STsdbMemTable *tsdbNewMemTable(SMemAllocatorFactory *pMAF) { + STsdbMemTable *pMemTable; + SMemAllocator *pMA; + + pMA = (*pMAF->create)(pMAF); + ASSERT(pMA != NULL); + + pMemTable = (STsdbMemTable *)((*pMA->malloc)(pMA, sizeof(*pMemTable))); + if (pMemTable == NULL) { + (*pMAF->destroy)(pMAF, pMA); + return NULL; + } + + T_REF_INIT_VAL(pMemTable, 1); + taosInitRWLatch(&(pMemTable->latch)); + pMemTable->keyMin = TSKEY_MAX; + pMemTable->keyMax = TSKEY_MIN; + pMemTable->nRow = 0; + pMemTable->pMA = pMA; + tSListInit(&(pMemTable->list)); + + // TODO + return pMemTable; +} + +void tsdbFreeMemTable(SMemAllocatorFactory *pMAF, STsdbMemTable *pMemTable) { + SMemAllocator *pMA = pMemTable->pMA; + + if (pMA->free) { + // TODO + ASSERT(0); + } + + (*pMAF->destroy)(pMAF, pMA); +} + +int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitMsg *pMsg) { + SMemAllocator *pMA = pMemTable->pMA; + STbData * pTbData = (STbData *)((*pMA->malloc)(pMA, sizeof(*pTbData))); + if (pTbData == NULL) { + // TODO + } + + tSListPush(&(pMemTable->list), pTbData); + + return 0; +} + +/* ------------------------ STATIC METHODS ------------------------ */ \ No newline at end of file diff --git a/src/inc/tadmin.h b/source/dnode/vnode/tsdb/src/tsdbWrite.c similarity index 70% rename from src/inc/tadmin.h rename to source/dnode/vnode/tsdb/src/tsdbWrite.c index b7de33576a..f9441cbe44 100644 --- a/src/inc/tadmin.h +++ b/source/dnode/vnode/tsdb/src/tsdbWrite.c @@ -13,20 +13,13 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_ADMIN_H -#define TDENGINE_ADMIN_H +#include "tsdbDef.h" -#ifdef __cplusplus -extern "C" { -#endif - -struct HttpServer; - -void adminInitHandle(struct HttpServer* pServer); -void opInitHandle(struct HttpServer* pServer); - -#ifdef __cplusplus -} -#endif - -#endif +int tsdbInsertData(STsdb *pTsdb, SSubmitMsg *pMsg) { + // Check if mem is there. If not, create one. + pTsdb->mem = tsdbNewMemTable(pTsdb->pmaf); + if (pTsdb->mem == NULL) { + return -1; + } + return tsdbInsertDataToMemTable(pTsdb->mem, pMsg); +} \ No newline at end of file diff --git a/source/libs/CMakeLists.txt b/source/libs/CMakeLists.txt index 007bb1e967..57a5023807 100644 --- a/source/libs/CMakeLists.txt +++ b/source/libs/CMakeLists.txt @@ -9,4 +9,5 @@ add_subdirectory(cache) add_subdirectory(catalog) add_subdirectory(executor) add_subdirectory(planner) -add_subdirectory(function) \ No newline at end of file +add_subdirectory(function) +add_subdirectory(query) diff --git a/source/libs/catalog/CMakeLists.txt b/source/libs/catalog/CMakeLists.txt index ff3e62700a..e6311152d6 100644 --- a/source/libs/catalog/CMakeLists.txt +++ b/source/libs/catalog/CMakeLists.txt @@ -8,5 +8,7 @@ target_include_directories( target_link_libraries( catalog - PRIVATE os util common transport -) \ No newline at end of file + PRIVATE os util common transport query +) + +ADD_SUBDIRECTORY(test) \ No newline at end of file diff --git a/source/libs/catalog/inc/catalogInt.h b/source/libs/catalog/inc/catalogInt.h index 5b50bbff4c..455c82b1bc 100644 --- a/source/libs/catalog/inc/catalogInt.h +++ b/source/libs/catalog/inc/catalogInt.h @@ -21,14 +21,62 @@ extern "C" { #endif #include "catalog.h" +#include "common.h" +#include "tlog.h" + +#define CTG_DEFAULT_CACHE_CLUSTER_NUMBER 6 +#define CTG_DEFAULT_CACHE_VGROUP_NUMBER 100 +#define CTG_DEFAULT_CACHE_DB_NUMBER 20 +#define CTG_DEFAULT_CACHE_TABLEMETA_NUMBER 100000 + +#define CTG_DEFAULT_INVALID_VERSION (-1) + +typedef struct SVgroupListCache { + int32_t vgroupVersion; + SHashObj *cache; // key:vgId, value:SVgroupInfo +} SVgroupListCache; + +typedef struct SDBVgroupCache { + SHashObj *cache; //key:dbname, value:SDBVgroupInfo +} SDBVgroupCache; + +typedef struct STableMetaCache { + SHashObj *cache; //key:fulltablename, value:STableMeta + SHashObj *stableCache; //key:suid, value:STableMeta* +} STableMetaCache; typedef struct SCatalog { - void *pMsgSender; // used to send messsage to mnode to fetch necessary metadata - SHashObj *pData; // items cached for each cluster, the hash key is the cluster-id, returned by mgmt node + SVgroupListCache vgroupCache; + SDBVgroupCache dbCache; + STableMetaCache tableCache; } SCatalog; +typedef struct SCatalogMgmt { + void *pMsgSender; // used to send messsage to mnode to fetch necessary metadata + SHashObj *pCluster; // items cached for each cluster, the hash key is the cluster-id got from mgmt node + SCatalogCfg cfg; +} SCatalogMgmt; + +typedef uint32_t (*tableNameHashFp)(const char *, uint32_t); + +extern int32_t ctgDebugFlag; + +#define ctgFatal(...) do { if (ctgDebugFlag & DEBUG_FATAL) { taosPrintLog("CTG FATAL ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgError(...) do { if (ctgDebugFlag & DEBUG_ERROR) { taosPrintLog("CTG ERROR ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgWarn(...) do { if (ctgDebugFlag & DEBUG_WARN) { taosPrintLog("CTG WARN ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgInfo(...) do { if (ctgDebugFlag & DEBUG_INFO) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgDebug(...) do { if (ctgDebugFlag & DEBUG_DEBUG) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgTrace(...) do { if (ctgDebugFlag & DEBUG_TRACE) { taosPrintLog("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) +#define ctgDebugL(...) do { if (ctgDebugFlag & DEBUG_DEBUG) { taosPrintLongString("CTG ", ctgDebugFlag, __VA_ARGS__); }} while(0) + + +#define CTG_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { return _code; } } while (0) +#define CTG_ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { ctgError(__VA_ARGS__); return _code; } } while (0) +#define CTG_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { goto _return; } } while (0) + + #ifdef __cplusplus } #endif -#endif /*_TD_CATALOG_INT_H_*/ \ No newline at end of file +#endif /*_TD_CATALOG_INT_H_*/ diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index 08e2172adb..9fdac36060 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -14,11 +14,656 @@ */ #include "catalogInt.h" +#include "trpc.h" +#include "query.h" +#include "tname.h" -struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) { - return (struct SCatalog*) 0x1; +SCatalogMgmt ctgMgmt = {0}; + +int32_t ctgGetDBVgroupFromCache(struct SCatalog* pCatalog, const char *dbName, SDBVgroupInfo *dbInfo, int32_t *exist) { + if (NULL == pCatalog->dbCache.cache) { + *exist = 0; + return TSDB_CODE_SUCCESS; + } + + SDBVgroupInfo *info = taosHashGet(pCatalog->dbCache.cache, dbName, strlen(dbName)); + + if (NULL == info) { + *exist = 0; + return TSDB_CODE_SUCCESS; + } + + if (dbInfo) { + *dbInfo = *info; + } + + *exist = 1; + + return TSDB_CODE_SUCCESS; } -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) { - return 0; + + +int32_t ctgGetDBVgroupFromMnode(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, SBuildUseDBInput *input, SUseDbOutput *out) { + char *msg = NULL; + SEpSet *pVnodeEpSet = NULL; + int32_t msgLen = 0; + + int32_t code = queryBuildMsg[TSDB_MSG_TYPE_USE_DB](input, &msg, 0, &msgLen); + if (code) { + return code; + } + + SRpcMsg rpcMsg = { + .msgType = TSDB_MSG_TYPE_USE_DB, + .pCont = msg, + .contLen = msgLen, + }; + + SRpcMsg rpcRsp = {0}; + + rpcSendRecv(pRpc, (SEpSet*)pMgmtEps, &rpcMsg, &rpcRsp); + + code = queryProcessMsgRsp[TSDB_MSG_TYPE_USE_DB](out, rpcRsp.pCont, rpcRsp.contLen); + if (code) { + return code; + } + + return TSDB_CODE_SUCCESS; } + + +int32_t ctgGetTableMetaFromCache(struct SCatalog* pCatalog, const char *dbName, const char* pTableName, STableMeta** pTableMeta, int32_t *exist) { + if (NULL == pCatalog->tableCache.cache) { + *exist = 0; + return TSDB_CODE_SUCCESS; + } + + char tbFullName[TSDB_TABLE_FNAME_LEN]; + + snprintf(tbFullName, sizeof(tbFullName), "%s.%s", dbName, pTableName); + + STableMeta *tbMeta = taosHashGet(pCatalog->tableCache.cache, tbFullName, strlen(tbFullName)); + + if (NULL == tbMeta) { + *exist = 0; + return TSDB_CODE_SUCCESS; + } + + if (tbMeta->tableType == TSDB_CHILD_TABLE) { + STableMeta **stbMeta = taosHashGet(pCatalog->tableCache.stableCache, &tbMeta->suid, sizeof(tbMeta->suid)); + if (NULL == stbMeta || NULL == *stbMeta) { + *exist = 0; + return TSDB_CODE_SUCCESS; + } + + if ((*stbMeta)->suid != tbMeta->suid) { + ctgError("stable cache error, expected suid:%"PRId64 ",actual suid:%"PRId64, tbMeta->suid, (*stbMeta)->suid); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + int32_t metaSize = sizeof(STableMeta) + ((*stbMeta)->tableInfo.numOfTags + (*stbMeta)->tableInfo.numOfColumns) * sizeof(SSchema); + *pTableMeta = calloc(1, metaSize); + if (NULL == *pTableMeta) { + ctgError("calloc size[%d] failed", metaSize); + return TSDB_CODE_CTG_MEM_ERROR; + } + + memcpy(*pTableMeta, tbMeta, sizeof(SCTableMeta)); + memcpy(&(*pTableMeta)->sversion, &(*stbMeta)->sversion, metaSize - sizeof(SCTableMeta)); + } else { + int32_t metaSize = sizeof(STableMeta) + (tbMeta->tableInfo.numOfTags + tbMeta->tableInfo.numOfColumns) * sizeof(SSchema); + *pTableMeta = calloc(1, metaSize); + if (NULL == *pTableMeta) { + ctgError("calloc size[%d] failed", metaSize); + return TSDB_CODE_CTG_MEM_ERROR; + } + + memcpy(*pTableMeta, tbMeta, metaSize); + } + + *exist = 1; + + return TSDB_CODE_SUCCESS; +} + +void ctgGenEpSet(SEpSet *epSet, SVgroupInfo *vgroupInfo) { + epSet->inUse = 0; + epSet->numOfEps = vgroupInfo->numOfEps; + + for (int32_t i = 0; i < vgroupInfo->numOfEps; ++i) { + memcpy(&epSet->port[i], &vgroupInfo->epAddr[i].port, sizeof(epSet->port[i])); + memcpy(&epSet->fqdn[i], &vgroupInfo->epAddr[i].fqdn, sizeof(epSet->fqdn[i])); + } +} + + +int32_t ctgGetTableMetaFromMnode(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char *pDBName, const char* pTableName, SVgroupInfo *vgroupInfo, STableMetaOutput* output) { + if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pDBName || NULL == pTableName || NULL == vgroupInfo || NULL == output) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + char tbFullName[TSDB_TABLE_FNAME_LEN]; + + snprintf(tbFullName, sizeof(tbFullName), "%s.%s", pDBName, pTableName); + + SBuildTableMetaInput bInput = {.vgId = vgroupInfo->vgId, .tableFullName = tbFullName}; + char *msg = NULL; + SEpSet *pVnodeEpSet = NULL; + int32_t msgLen = 0; + + int32_t code = queryBuildMsg[TSDB_MSG_TYPE_TABLE_META](&bInput, &msg, 0, &msgLen); + if (code) { + return code; + } + + SRpcMsg rpcMsg = { + .msgType = TSDB_MSG_TYPE_TABLE_META, + .pCont = msg, + .contLen = msgLen, + }; + + SRpcMsg rpcRsp = {0}; + SEpSet epSet; + + ctgGenEpSet(&epSet, vgroupInfo); + + rpcSendRecv(pRpc, &epSet, &rpcMsg, &rpcRsp); + + if (TSDB_CODE_SUCCESS != rpcRsp.code) { + ctgError("get table meta from mnode failed, error code:%d", rpcRsp.code); + return rpcRsp.code; + } + + code = queryProcessMsgRsp[TSDB_MSG_TYPE_TABLE_META](output, rpcRsp.pCont, rpcRsp.contLen); + if (code) { + return code; + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgGetHashFunction(int8_t hashMethod, tableNameHashFp *fp) { + switch (hashMethod) { + default: + *fp = MurmurHash3_32; + break; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t ctgGetVgInfoFromDB(struct SCatalog *pCatalog, void *pRpc, const SEpSet *pMgmtEps, SDBVgroupInfo *dbInfo, SArray* vgroupList) { + SHashObj *vgroupHash = NULL; + SVgroupInfo *vgInfo = NULL; + + void *pIter = taosHashIterate(dbInfo->vgInfo, NULL); + while (pIter) { + vgInfo = pIter; + + if (NULL == taosArrayPush(vgroupList, vgInfo)) { + ctgError("taosArrayPush failed"); + break; + } + + pIter = taosHashIterate(dbInfo->vgInfo, pIter); + vgInfo = NULL; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t ctgGetVgInfoFromHashValue(SDBVgroupInfo *dbInfo, const char *pDBName, const char *pTableName, SVgroupInfo *pVgroup) { + int32_t vgNum = taosHashGetSize(dbInfo->vgInfo); + if (vgNum <= 0) { + ctgError("db[%s] vgroup cache invalid, vgroup number:%d", pDBName, vgNum); + return TSDB_CODE_TSC_DB_NOT_SELECTED; + } + + tableNameHashFp fp = NULL; + SVgroupInfo *vgInfo = NULL; + + CTG_ERR_RET(ctgGetHashFunction(dbInfo->hashMethod, &fp)); + + char tbFullName[TSDB_TABLE_FNAME_LEN]; + + snprintf(tbFullName, sizeof(tbFullName), "%s.%s", pDBName, pTableName); + + uint32_t hashValue = (*fp)(tbFullName, (uint32_t)strlen(tbFullName)); + + void *pIter = taosHashIterate(dbInfo->vgInfo, NULL); + while (pIter) { + vgInfo = pIter; + if (hashValue >= vgInfo->hashBegin && hashValue <= vgInfo->hashEnd) { + break; + } + + pIter = taosHashIterate(dbInfo->vgInfo, pIter); + vgInfo = NULL; + } + + if (NULL == vgInfo) { + ctgError("no hash range found for hashvalue[%u]", hashValue); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + *pVgroup = *vgInfo; + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgGetTableHashVgroup(struct SCatalog *pCatalog, void *pRpc, const SEpSet *pMgmtEps, const char *pDBName, const char *pTableName, SVgroupInfo *pVgroup) { + SDBVgroupInfo dbInfo = {0}; + int32_t code = 0; + int32_t vgId = 0; + + CTG_ERR_RET(catalogGetDBVgroup(pCatalog, pRpc, pMgmtEps, pDBName, false, &dbInfo)); + + if (dbInfo.vgVersion < 0 || NULL == dbInfo.vgInfo) { + ctgError("db[%s] vgroup cache invalid, vgroup version:%d, vgInfo:%p", pDBName, dbInfo.vgVersion, dbInfo.vgInfo); + return TSDB_CODE_TSC_DB_NOT_SELECTED; + } + + CTG_ERR_RET(ctgGetVgInfoFromHashValue(&dbInfo, pDBName, pTableName, pVgroup)); + + return code; +} + + + +STableMeta* ctgCreateSTableMeta(STableMetaMsg* pChild) { + assert(pChild != NULL); + int32_t total = pChild->numOfColumns + pChild->numOfTags; + + STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * total); + pTableMeta->tableType = TSDB_SUPER_TABLE; + pTableMeta->tableInfo.numOfTags = pChild->numOfTags; + pTableMeta->tableInfo.numOfColumns = pChild->numOfColumns; + pTableMeta->tableInfo.precision = pChild->precision; + + pTableMeta->uid = pChild->suid; + pTableMeta->tversion = pChild->tversion; + pTableMeta->sversion = pChild->sversion; + + memcpy(pTableMeta->schema, pChild->pSchema, sizeof(SSchema) * total); + + int32_t num = pTableMeta->tableInfo.numOfColumns; + for(int32_t i = 0; i < num; ++i) { + pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes; + } + + return pTableMeta; +} + +int32_t ctgGetTableMetaImpl(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, bool forceUpdate, STableMeta** pTableMeta) { + if (NULL == pCatalog || NULL == pDBName || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName || NULL == pTableMeta) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + int32_t exist = 0; + + if (!forceUpdate) { + CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pDBName, pTableName, pTableMeta, &exist)); + + if (exist) { + return TSDB_CODE_SUCCESS; + } + } + + CTG_ERR_RET(catalogRenewTableMeta(pCatalog, pRpc, pMgmtEps, pDBName, pTableName)); + + CTG_ERR_RET(ctgGetTableMetaFromCache(pCatalog, pDBName, pTableName, pTableMeta, &exist)); + + if (0 == exist) { + ctgError("get table meta from cache failed, but fetch succeed"); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + return TSDB_CODE_SUCCESS; +} + + +int32_t ctgUpdateTableMetaCache(struct SCatalog *pCatalog, STableMetaOutput *output) { + if (output->metaNum != 1 && output->metaNum != 2) { + ctgError("invalid table meta number[%d] got from meta rsp", output->metaNum); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + if (NULL == output->tbMeta) { + ctgError("no valid table meta got from meta rsp"); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + if (NULL == pCatalog->tableCache.cache) { + pCatalog->tableCache.cache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == pCatalog->tableCache.cache) { + ctgError("init hash[%d] for tablemeta cache failed", ctgMgmt.cfg.maxTblCacheNum); + return TSDB_CODE_CTG_MEM_ERROR; + } + } + + if (NULL == pCatalog->tableCache.cache) { + pCatalog->tableCache.cache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == pCatalog->tableCache.cache) { + ctgError("init hash[%d] for tablemeta cache failed", ctgMgmt.cfg.maxTblCacheNum); + return TSDB_CODE_CTG_MEM_ERROR; + } + + pCatalog->tableCache.stableCache = taosHashInit(ctgMgmt.cfg.maxTblCacheNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), true, HASH_ENTRY_LOCK); + if (NULL == pCatalog->tableCache.stableCache) { + ctgError("init hash[%d] for stablemeta cache failed", ctgMgmt.cfg.maxTblCacheNum); + return TSDB_CODE_CTG_MEM_ERROR; + } + } + + if (output->metaNum == 2) { + if (taosHashPut(pCatalog->tableCache.cache, output->ctbFname, strlen(output->ctbFname), &output->ctbMeta, sizeof(output->ctbMeta)) != 0) { + ctgError("push ctable[%s] to table cache failed", output->ctbFname); + goto error_exit; + } + + if (TSDB_SUPER_TABLE != output->tbMeta->tableType) { + ctgError("table type[%d] error, expected:%d", output->tbMeta->tableType, TSDB_SUPER_TABLE); + goto error_exit; + } + } + + if (taosHashPut(pCatalog->tableCache.cache, output->tbFname, strlen(output->tbFname), output->tbMeta, sizeof(*output->tbMeta)) != 0) { + ctgError("push table[%s] to table cache failed", output->tbFname); + goto error_exit; + } + + if (TSDB_SUPER_TABLE == output->tbMeta->tableType) { + if (taosHashPut(pCatalog->tableCache.stableCache, &output->tbMeta->suid, sizeof(output->tbMeta->suid), &output->tbMeta, POINTER_BYTES) != 0) { + ctgError("push suid[%"PRIu64"] to stable cache failed", output->tbMeta->suid); + goto error_exit; + } + } + + return TSDB_CODE_SUCCESS; + +error_exit: + if (pCatalog->vgroupCache.cache) { + taosHashCleanup(pCatalog->vgroupCache.cache); + pCatalog->vgroupCache.cache = NULL; + } + + pCatalog->vgroupCache.vgroupVersion = CTG_DEFAULT_INVALID_VERSION; + + return TSDB_CODE_CTG_INTERNAL_ERROR; +} + +int32_t catalogInit(SCatalogCfg *cfg) { + ctgMgmt.pCluster = taosHashInit(CTG_DEFAULT_CACHE_CLUSTER_NUMBER, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == ctgMgmt.pCluster) { + CTG_ERR_LRET(TSDB_CODE_CTG_INTERNAL_ERROR, "init %d cluster cache failed", CTG_DEFAULT_CACHE_CLUSTER_NUMBER); + } + + if (cfg) { + memcpy(&ctgMgmt.cfg, cfg, sizeof(*cfg)); + } else { + ctgMgmt.cfg.enableVgroupCache = true; + ctgMgmt.cfg.maxDBCacheNum = CTG_DEFAULT_CACHE_DB_NUMBER; + ctgMgmt.cfg.maxTblCacheNum = CTG_DEFAULT_CACHE_TABLEMETA_NUMBER; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) { + if (NULL == clusterId || NULL == catalogHandle) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + if (NULL == ctgMgmt.pCluster) { + ctgError("cluster cache are not ready"); + return TSDB_CODE_CTG_NOT_READY; + } + + size_t clen = strlen(clusterId); + SCatalog *clusterCtg = (SCatalog *)taosHashGet(ctgMgmt.pCluster, clusterId, clen); + + if (clusterCtg) { + *catalogHandle = clusterCtg; + return TSDB_CODE_SUCCESS; + } + + clusterCtg = calloc(1, sizeof(*clusterCtg)); + if (NULL == clusterCtg) { + ctgError("calloc %d failed", (int32_t)sizeof(*clusterCtg)); + return TSDB_CODE_CTG_MEM_ERROR; + } + + clusterCtg->vgroupCache.vgroupVersion = CTG_DEFAULT_INVALID_VERSION; + + if (taosHashPut(ctgMgmt.pCluster, clusterId, clen, &clusterCtg, POINTER_BYTES)) { + ctgError("put cluster %s cache to hash failed", clusterId); + tfree(clusterCtg); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + *catalogHandle = clusterCtg; + + return TSDB_CODE_SUCCESS; +} + +int32_t catalogGetDBVgroupVersion(struct SCatalog* pCatalog, const char* dbName, int32_t* version) { + if (NULL == pCatalog || NULL == dbName || NULL == version) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + if (NULL == pCatalog->dbCache.cache) { + *version = CTG_DEFAULT_INVALID_VERSION; + return TSDB_CODE_SUCCESS; + } + + SDBVgroupInfo * dbInfo = taosHashGet(pCatalog->dbCache.cache, dbName, strlen(dbName)); + if (NULL == dbInfo) { + *version = CTG_DEFAULT_INVALID_VERSION; + return TSDB_CODE_SUCCESS; + } + + *version = dbInfo->vgVersion; + + return TSDB_CODE_SUCCESS; +} + +int32_t catalogUpdateDBVgroupCache(struct SCatalog* pCatalog, const char* dbName, SDBVgroupInfo* dbInfo) { + if (NULL == pCatalog || NULL == dbName || NULL == dbInfo) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + if (dbInfo->vgVersion < 0) { + if (pCatalog->dbCache.cache) { + taosHashRemove(pCatalog->dbCache.cache, dbName, strlen(dbName)); + } + + ctgWarn("remove db [%s] from cache", dbName); + return TSDB_CODE_SUCCESS; + } + + if (NULL == pCatalog->dbCache.cache) { + pCatalog->dbCache.cache = taosHashInit(CTG_DEFAULT_CACHE_DB_NUMBER, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + if (NULL == pCatalog->dbCache.cache) { + ctgError("init hash[%d] for db cache failed", CTG_DEFAULT_CACHE_DB_NUMBER); + return TSDB_CODE_CTG_MEM_ERROR; + } + } else { + SDBVgroupInfo *oldInfo = taosHashGet(pCatalog->dbCache.cache, dbName, strlen(dbName)); + if (oldInfo && oldInfo->vgInfo) { + taosHashCleanup(oldInfo->vgInfo); + oldInfo->vgInfo = NULL; + } + } + + if (taosHashPut(pCatalog->dbCache.cache, dbName, strlen(dbName), dbInfo, sizeof(*dbInfo)) != 0) { + ctgError("push to vgroup hash cache failed"); + return TSDB_CODE_CTG_MEM_ERROR; + } + + return TSDB_CODE_SUCCESS; +} + + + + +int32_t catalogGetDBVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* dbName, int32_t forceUpdate, SDBVgroupInfo* dbInfo) { + if (NULL == pCatalog || NULL == dbName || NULL == pRpc || NULL == pMgmtEps) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + int32_t exist = 0; + int32_t code = 0; + + if (0 == forceUpdate) { + CTG_ERR_RET(ctgGetDBVgroupFromCache(pCatalog, dbName, dbInfo, &exist)); + + if (exist) { + return TSDB_CODE_SUCCESS; + } + } + + SUseDbOutput DbOut = {0}; + SBuildUseDBInput input = {0}; + + strncpy(input.db, dbName, sizeof(input.db)); + input.db[sizeof(input.db) - 1] = 0; + input.vgVersion = CTG_DEFAULT_INVALID_VERSION; + + CTG_ERR_RET(ctgGetDBVgroupFromMnode(pCatalog, pRpc, pMgmtEps, &input, &DbOut)); + + CTG_ERR_RET(catalogUpdateDBVgroupCache(pCatalog, dbName, &DbOut.dbVgroup)); + + if (dbInfo) { + *dbInfo = DbOut.dbVgroup; + } + + return code; +} + +int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) { + return ctgGetTableMetaImpl(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, false, pTableMeta); +} + +int32_t catalogRenewTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName) { + if (NULL == pCatalog || NULL == pDBName || NULL == pRpc || NULL == pMgmtEps || NULL == pTableName) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + SVgroupInfo vgroupInfo = {0}; + + CTG_ERR_RET(ctgGetTableHashVgroup(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, &vgroupInfo)); + + STableMetaOutput output = {0}; + + CTG_ERR_RET(ctgGetTableMetaFromMnode(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, &vgroupInfo, &output)); + + CTG_ERR_RET(ctgUpdateTableMetaCache(pCatalog, &output)); + + tfree(output.tbMeta); + + return TSDB_CODE_SUCCESS; +} + +int32_t catalogRenewAndGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) { + return ctgGetTableMetaImpl(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, true, pTableMeta); +} + +int32_t catalogGetTableVgroup(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, SArray* pVgroupList) { + if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pDBName || NULL == pTableName || NULL == pVgroupList) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + STableMeta *tbMeta = NULL; + int32_t code = 0; + SVgroupInfo vgroupInfo = {0}; + SDBVgroupInfo dbVgroup = {0}; + + CTG_ERR_JRET(catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, &tbMeta)); + + CTG_ERR_JRET(catalogGetDBVgroup(pCatalog, pRpc, pMgmtEps, pDBName, false, &dbVgroup)); + + if (tbMeta->tableType == TSDB_SUPER_TABLE) { + CTG_ERR_JRET(ctgGetVgInfoFromDB(pCatalog, pRpc, pMgmtEps, &dbVgroup, pVgroupList)); + } else { + int32_t vgId = tbMeta->vgId; + if (NULL == taosHashGetClone(dbVgroup.vgInfo, &vgId, sizeof(vgId), &vgroupInfo)) { + ctgError("vgId[%d] not found in vgroup list", vgId); + return TSDB_CODE_CTG_INTERNAL_ERROR; + } + + if (NULL == taosArrayPush(pVgroupList, &vgroupInfo)) { + ctgError("push vgroupInfo to array failed"); + CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR); + } + } + +_return: + tfree(tbMeta); + + return code; +} + + +int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const SCatalogReq* pReq, SMetaData* pRsp) { + if (NULL == pCatalog || NULL == pRpc || NULL == pMgmtEps || NULL == pReq || NULL == pRsp) { + return TSDB_CODE_CTG_INVALID_INPUT; + } + + int32_t code = 0; + + if (pReq->pTableName) { + char dbName[TSDB_FULL_DB_NAME_LEN]; + int32_t tbNum = (int32_t)taosArrayGetSize(pReq->pTableName); + if (tbNum > 0) { + pRsp->pTableMeta = taosArrayInit(tbNum, POINTER_BYTES); + if (NULL == pRsp->pTableMeta) { + ctgError("taosArrayInit num[%d] failed", tbNum); + return TSDB_CODE_CTG_MEM_ERROR; + } + } + + for (int32_t i = 0; i < tbNum; ++i) { + SName *name = taosArrayGet(pReq->pTableName, i); + STableMeta *pTableMeta = NULL; + + snprintf(dbName, sizeof(dbName), "%s.%s", name->acctId, name->dbname); + + CTG_ERR_JRET(catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, dbName, name->tname, &pTableMeta)); + + if (NULL == taosArrayPush(pRsp->pTableMeta, &pTableMeta)) { + ctgError("taosArrayPush failed, idx:%d", i); + tfree(pTableMeta); + CTG_ERR_JRET(TSDB_CODE_CTG_MEM_ERROR); + } + } + } + + return TSDB_CODE_SUCCESS; + +_return: + + if (pRsp->pTableMeta) { + int32_t aSize = taosArrayGetSize(pRsp->pTableMeta); + for (int32_t i = 0; i < aSize; ++i) { + STableMeta *pMeta = taosArrayGetP(pRsp->pTableMeta, i); + tfree(pMeta); + } + + taosArrayDestroy(pRsp->pTableMeta); + } + + return code; +} + +void catalogDestroy(void) { + if (ctgMgmt.pCluster) { + taosHashCleanup(ctgMgmt.pCluster); //TBD + ctgMgmt.pCluster = NULL; + } +} + + + diff --git a/source/libs/catalog/test/CMakeLists.txt b/source/libs/catalog/test/CMakeLists.txt new file mode 100644 index 0000000000..527156f176 --- /dev/null +++ b/source/libs/catalog/test/CMakeLists.txt @@ -0,0 +1,18 @@ + +MESSAGE(STATUS "build catalog unit test") + +# GoogleTest requires at least C++11 +SET(CMAKE_CXX_STANDARD 11) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) + +ADD_EXECUTABLE(catalogTest ${SOURCE_LIST}) +TARGET_LINK_LIBRARIES( + catalogTest + PUBLIC os util common catalog transport gtest query +) + +TARGET_INCLUDE_DIRECTORIES( + catalogTest + PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/catalog/" + PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/catalog/inc" +) diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp index e69de29bb2..f495451091 100644 --- a/source/libs/catalog/test/catalogTests.cpp +++ b/source/libs/catalog/test/catalogTests.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include +#include +#include +#pragma GCC diagnostic ignored "-Wwrite-strings" + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "os.h" + +#include "taos.h" +#include "tdef.h" +#include "tvariant.h" +#include "catalog.h" + +namespace { + + +} + +TEST(testCase, normalCase) { + char *clusterId = "cluster1"; + struct SCatalog* pCtg = NULL; + + int32_t code = catalogInit(NULL); + ASSERT_EQ(code, 0); + + code = catalogGetHandle(clusterId, &pCtg); + ASSERT_EQ(code, 0); + + +} + +/* +TEST(testCase, normalCase) { + SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)"); + ASSERT_EQ(info1.valid, true); + + char msg[128] = {0}; + SMsgBuf buf; + buf.len = 128; + buf.buf = msg; + + SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0); + int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); + ASSERT_EQ(code, 0); + + SCatalogReq req = {0}; + int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); + ASSERT_EQ(ret, 0); + ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); + + SQueryStmtInfo* pQueryInfo = createQueryInfo(); + setTableMetaInfo(pQueryInfo, &req); + + SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0); + ret = validateSqlNode(pSqlNode, pQueryInfo, &buf); + ASSERT_EQ(ret, 0); + + SArray* pExprList = pQueryInfo->exprList[0]; + + int32_t num = tsCompatibleModel? 2:1; + ASSERT_EQ(taosArrayGetSize(pExprList), num); + + SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1); + ASSERT_EQ(p1->base.pColumns->uid, 110); + ASSERT_EQ(p1->base.numOfParams, 1); + ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP); + ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)"); + ASSERT_EQ(p1->base.interBytes, 16); + + ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE); + ASSERT_STREQ(p1->pExpr->_function.functionName, "top"); + + tExprNode* pParam = p1->pExpr->_function.pChild[0]; + + ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE); + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); + + struct SQueryPlanNode* n = nullptr; + code = createQueryPlan(pQueryInfo, &n); + + char* str = NULL; + queryPlanToString(n, &str); + printf("%s\n", str); + + destroyQueryInfo(pQueryInfo); + qParserClearupMetaRequestInfo(&req); + destroySqlInfo(&info1); +} + +TEST(testCase, displayPlan) { + generateLogicplan("select count(*) from `t.1abc`"); + generateLogicplan("select count(*)+ 22 from `t.1abc`"); + generateLogicplan("select count(*)+ 22 from `t.1abc` interval(1h, 20s) sliding(10m) limit 20,30"); + generateLogicplan("select count(*) from `t.1abc` group by a"); + generateLogicplan("select count(A+B) from `t.1abc` group by a"); + generateLogicplan("select count(length(a)+b) from `t.1abc` group by a"); + generateLogicplan("select count(*) from `t.1abc` interval(10s, 5s) sliding(7s)"); + generateLogicplan("select count(*) from `t.1abc` interval(10s, 5s) sliding(7s) order by 1 desc "); + generateLogicplan("select count(*),sum(a),avg(b),min(a+b)+99 from `t.1abc`"); + generateLogicplan("select count(*), min(a) + 99 from `t.1abc`"); + generateLogicplan("select count(length(count(*) + 22)) from `t.1abc`"); + generateLogicplan("select concat(concat(a,b), concat(a,b)) from `t.1abc` limit 20"); + generateLogicplan("select count(*), first(a), last(b) from `t.1abc` state_window(a)"); + generateLogicplan("select count(*), first(a), last(b) from `t.1abc` session(ts, 20s)"); + + // order by + group by column + limit offset + generateLogicplan("select top(a, 20) k from `t.1abc` order by k asc limit 3 offset 1"); + + // fill + generateLogicplan("select min(a) from `t.1abc` where ts>now and tspRuntimeEnv->tableqinfoGroupInfo.numOfTables; - int32_t numRowSteps = tsMaxRowsInFileBlock / TSDB_BLOCK_DIST_STEP_ROWS; - if (tsMaxRowsInFileBlock % TSDB_BLOCK_DIST_STEP_ROWS != 0) { + int32_t numRowSteps = TSDB_DEFAULT_MAX_ROW_FBLOCK / TSDB_BLOCK_DIST_STEP_ROWS; + if (TSDB_DEFAULT_MAX_ROW_FBLOCK % TSDB_BLOCK_DIST_STEP_ROWS != 0) { ++numRowSteps; } tableBlockDist.dataBlockInfos = taosArrayInit(numRowSteps, sizeof(SFileBlockInfo)); diff --git a/source/libs/index/inc/index_fst.h b/source/libs/index/inc/index_fst.h index a1d4962e8b..20037f829a 100644 --- a/source/libs/index/inc/index_fst.h +++ b/source/libs/index/inc/index_fst.h @@ -30,6 +30,7 @@ extern "C" { typedef struct Fst Fst; typedef struct FstNode FstNode; +typedef struct StreamWithState StreamWithState; typedef enum { Included, Excluded, Unbounded} FstBound; @@ -283,6 +284,9 @@ Output fstEmptyFinalOutput(Fst *fst, bool *null); FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx); FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx); +// into stream to expand later +StreamWithState* streamBuilderIntoStream(FstStreamBuilder *sb); + bool fstVerify(Fst *fst); diff --git a/source/libs/index/inc/index_fst_automation.h b/source/libs/index/inc/index_fst_automation.h index c2ab61bf5f..8050b85b08 100644 --- a/source/libs/index/inc/index_fst_automation.h +++ b/source/libs/index/inc/index_fst_automation.h @@ -20,6 +20,8 @@ extern "C" { #endif #include "index_fst_util.h" + + typedef struct AutomationCtx AutomationCtx; typedef enum AutomationType { @@ -38,18 +40,30 @@ typedef struct Complement { // automation typedef struct AutomationCtx { AutomationType type; - void *data; + void *stdata; + char *data; } AutomationCtx; - +typedef enum ValueType { FST_INT, FST_CHAR, FST_ARRAY} ValueType; typedef enum StartWithStateKind { Done, Running } StartWithStateKind; typedef struct StartWithStateValue { StartWithStateKind kind; - void *value; + ValueType type; + union { + int val; + char *ptr; + SArray *arr; + // add more type + } ; } StartWithStateValue; +StartWithStateValue *startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void *val); +StartWithStateValue *startWithStateValueDump(StartWithStateValue *sv); +void startWithStateValueDestroy(void *sv); + + typedef struct AutomationFunc { void* (*start)(AutomationCtx *ctx) ; bool (*isMatch)(AutomationCtx *ctx, void *); @@ -59,7 +73,7 @@ typedef struct AutomationFunc { void* (*acceptEof)(AutomationCtx *ct, void *state); } AutomationFunc; -AutomationCtx *automCtxCreate(void *data, AutomationType type); +AutomationCtx *automCtxCreate(void *data, AutomationType atype); void automCtxDestroy(AutomationCtx *ctx); extern AutomationFunc automFuncs[]; diff --git a/source/libs/index/src/index_fst.c b/source/libs/index/src/index_fst.c index 07f1e343bd..9cb4ac6836 100644 --- a/source/libs/index/src/index_fst.c +++ b/source/libs/index/src/index_fst.c @@ -17,6 +17,7 @@ #include "tcoding.h" #include "tchecksum.h" #include "indexInt.h" +#include "index_fst_automation.h" static void fstPackDeltaIn(FstCountingWriter *wrt, CompiledAddr nodeAddr, CompiledAddr transAddr, uint8_t nBytes) { @@ -1093,6 +1094,10 @@ bool fstGet(Fst *fst, FstSlice *b, Output *out) { FstStreamBuilder *fstSearch(Fst *fst, AutomationCtx *ctx) { return fstStreamBuilderCreate(fst, ctx); } +StreamWithState* streamBuilderIntoStream(FstStreamBuilder *sb) { + if (sb == NULL) { return NULL; } + return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max); +} FstStreamWithStateBuilder *fstSearchWithState(Fst *fst, AutomationCtx *ctx) { return fstStreamBuilderCreate(fst, ctx); } @@ -1118,7 +1123,7 @@ CompiledAddr fstGetRootAddr(Fst *fst) { Output fstEmptyFinalOutput(Fst *fst, bool *null) { Output res = 0; - FstNode *node = fst->root; + FstNode *node = fstGetRoot(fst); if (FST_NODE_IS_FINAL(node)) { *null = false; res = FST_NODE_FINAL_OUTPUT(node); @@ -1175,7 +1180,7 @@ bool fstBoundWithDataIsEmpty(FstBoundWithData *bound) { bool fstBoundWithDataIsIncluded(FstBoundWithData *bound) { - return bound->type == Included ? true : false; + return bound->type == Excluded? false : true; } void fstBoundDestroy(FstBoundWithData *bound) { @@ -1322,6 +1327,7 @@ StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallb return swsResultCreate(&s, output, callback(start)); } } + SArray *nodes = taosArrayInit(8, sizeof(FstNode *)); while (taosArrayGetSize(sws->stack) > 0) { StreamState *p = (StreamState *)taosArrayPop(sws->stack); if (p->trans >= FST_NODE_LEN(p->node) || automFuncs[aut->type].canMatch(aut, p->autState)) { @@ -1337,8 +1343,8 @@ StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallb void* nextState = automFuncs[aut->type].accept(aut, p->autState, trn.inp); void* tState = callback(nextState); bool isMatch = automFuncs[aut->type].isMatch(aut, nextState); - //bool isMatch = sws->aut->isMatch(nextState); FstNode *nextNode = fstGetNode(sws->fst, trn.addr); + taosArrayPush(nodes, &nextNode); taosArrayPush(sws->inp, &(trn.inp)); if (FST_NODE_IS_FINAL(nextNode)) { @@ -1354,26 +1360,35 @@ StreamWithStateResult *streamWithStateNextWith(StreamWithState *sws, StreamCallb StreamState s2 = {.node = nextNode, .trans = 0, .out = {.null = false, .out = out}, .autState = nextState}; taosArrayPush(sws->stack, &s2); - uint8_t *buf = (uint8_t *)malloc(taosArrayGetSize(sws->inp) * sizeof(uint8_t)); - for (uint32_t i = 0; i < taosArrayGetSize(sws->inp); i++) { - uint8_t *t = (uint8_t *)taosArrayGet(sws->inp, i); - buf[i] = *t; + + size_t isz = taosArrayGetSize(sws->inp); + uint8_t *buf = (uint8_t *)malloc(isz * sizeof(uint8_t)); + for (uint32_t i = 0; i < isz; i++) { + buf[i] = *(uint8_t *)taosArrayGet(sws->inp, i); } FstSlice slice = fstSliceCreate(buf, taosArrayGetSize(sws->inp)); if (fstBoundWithDataExceededBy(sws->endAt, &slice)) { taosArrayDestroyEx(sws->stack, streamStateDestroy); sws->stack = (SArray *)taosArrayInit(256, sizeof(StreamState)); + free(buf); fstSliceDestroy(&slice); return NULL; } if (FST_NODE_IS_FINAL(nextNode) && isMatch) { FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)}; - StreamWithStateResult *result = swsResultCreate(&slice, fOutput , tState); + StreamWithStateResult *result = swsResultCreate(&slice, fOutput, tState); + free(buf); fstSliceDestroy(&slice); return result; } + free(buf); fstSliceDestroy(&slice); } + for (size_t i = 0; i < taosArrayGetSize(nodes); i++) { + FstNode** node = (FstNode **)taosArrayGet(nodes, i); + fstNodeDestroy(*node); + } + taosArrayDestroy(nodes); return NULL; } @@ -1392,6 +1407,7 @@ void swsResultDestroy(StreamWithStateResult *result) { if (NULL == result) { return; } fstSliceDestroy(&result->data); + startWithStateValueDestroy(result->state); free(result); } diff --git a/source/libs/index/src/index_fst_automation.c b/source/libs/index/src/index_fst_automation.c index 6a08b41b12..f70b90041b 100644 --- a/source/libs/index/src/index_fst_automation.c +++ b/source/libs/index/src/index_fst_automation.c @@ -16,21 +16,81 @@ #include "index_fst_automation.h" +StartWithStateValue *startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void *val) { + StartWithStateValue *nsv = calloc(1, sizeof(StartWithStateValue)); + if (nsv == NULL) { return NULL; } + + nsv->kind = kind; + nsv->type = ty; + if (ty == FST_INT) { + nsv->val = *(int *)val; + } else if (ty == FST_CHAR) { + size_t len = strlen((char *)val); + nsv->ptr = (char *)calloc(1, len + 1); + memcpy(nsv->ptr, val, len); + } else if (ty == FST_ARRAY) { + //TODO, + //nsv->arr = taosArrayFromList() + } + return nsv; +} +void startWithStateValueDestroy(void *val) { + StartWithStateValue *sv = (StartWithStateValue *)val; + if (sv == NULL) { return; } + + if (sv->type == FST_INT) { + // + } else if (sv->type == FST_CHAR) { + free(sv->ptr); + } else if (sv->type == FST_ARRAY) { + taosArrayDestroy(sv->arr); + } + free(sv); +} +StartWithStateValue *startWithStateValueDump(StartWithStateValue *sv) { + StartWithStateValue *nsv = calloc(1, sizeof(StartWithStateValue)); + if (nsv == NULL) { return NULL; } + + nsv->kind = sv->kind; + nsv->type= sv->type; + if (nsv->type == FST_INT) { + nsv->val = sv->val; + } else if (nsv->type == FST_CHAR) { + size_t len = strlen(sv->ptr); + nsv->ptr = (char *)calloc(1, len + 1); + memcpy(nsv->ptr, sv->ptr, len); + } else if (nsv->type == FST_ARRAY) { + } + return nsv; +} + + // prefix query, impl later + static void* prefixStart(AutomationCtx *ctx) { - StartWithStateValue *data = (StartWithStateValue *)(ctx->data); - return data; + StartWithStateValue *data = (StartWithStateValue *)(ctx->stdata); + return startWithStateValueDump(data); }; -static bool prefixIsMatch(AutomationCtx *ctx, void *data) { - return true; +static bool prefixIsMatch(AutomationCtx *ctx, void *sv) { + StartWithStateValue* ssv = (StartWithStateValue *)sv; + return ssv->val == strlen(ctx->data); } -static bool prefixCanMatch(AutomationCtx *ctx, void *data) { - return true; +static bool prefixCanMatch(AutomationCtx *ctx, void *sv) { + StartWithStateValue* ssv = (StartWithStateValue *)sv; + return ssv->val >= 0; } static bool prefixWillAlwaysMatch(AutomationCtx *ctx, void *state) { return true; } static void* prefixAccept(AutomationCtx *ctx, void *state, uint8_t byte) { + StartWithStateValue* ssv = (StartWithStateValue *)state; + if (ssv == NULL || ctx == NULL) {return NULL;} + + char *data = ctx->data; + if ((strlen(data) > ssv->val) && data[ssv->val] == byte) { + int val = ssv->val + 1; + return startWithStateValueCreate(Running, FST_INT, &val); + } return NULL; } static void* prefixAcceptEof(AutomationCtx *ctx, void *state) { @@ -79,28 +139,34 @@ AutomationFunc automFuncs[] = {{ // add more search type }; -AutomationCtx* automCtxCreate(void *data, AutomationType type) { +AutomationCtx* automCtxCreate(void *data,AutomationType atype) { AutomationCtx *ctx = calloc(1, sizeof(AutomationCtx)); if (ctx == NULL) { return NULL; } - if (type == AUTOMATION_PREFIX) { - StartWithStateValue *swsv = (StartWithStateValue *)calloc(1, sizeof(StartWithStateValue)); - swsv->kind = Done; - swsv->value = NULL; - ctx->data = (void *)swsv; - } else if (type == AUTMMATION_MATCH) { + StartWithStateValue *sv = NULL; + if (atype == AUTOMATION_PREFIX) { + int val = 0; + sv = startWithStateValueCreate(Running, FST_INT, &val); + ctx->stdata = (void *)sv; + } else if (atype == AUTMMATION_MATCH) { } else { // add more search type } - ctx->type = type; + char* src = (char *)data; + size_t len = strlen(src); + char* dst = (char *)malloc(len * sizeof(char) + 1); + memcpy(dst, src, len); + dst[len] = 0; + + ctx->data = dst; + ctx->type = atype; + ctx->stdata = (void *)sv; return ctx; } void automCtxDestroy(AutomationCtx *ctx) { - if (ctx->type == AUTOMATION_PREFIX) { - free(ctx->data); - } else if (ctx->type == AUTMMATION_MATCH) { - } + startWithStateValueDestroy(ctx->stdata); + free(ctx->data); free(ctx); } diff --git a/source/libs/index/test/indexTests.cpp b/source/libs/index/test/indexTests.cpp index 0cfb0fedc3..f582536817 100644 --- a/source/libs/index/test/indexTests.cpp +++ b/source/libs/index/test/indexTests.cpp @@ -59,9 +59,22 @@ class FstReadMemory { return ok; } // add later - bool Search(const std::string &key, std::vector &result) { + bool Search(AutomationCtx *ctx, std::vector &result) { + FstStreamBuilder *sb = fstSearch(_fst, ctx); + StreamWithState *st = streamBuilderIntoStream(sb); + StreamWithStateResult *rt = NULL; + + while ((rt = streamWithStateNextWith(st, NULL)) != NULL) { + result.push_back((uint64_t)(rt->out.out)); + } return true; } + bool SearchWithTimeCostUs(AutomationCtx *ctx, std::vector &result) { + int64_t s = taosGetTimestampUs(); + bool ok = this->Search(ctx, result); + int64_t e = taosGetTimestampUs(); + return ok; + } ~FstReadMemory() { fstCountingWriterDestroy(_w); @@ -186,11 +199,43 @@ void checkFstPerf() { printf("success to init fst read"); } Performance_fstReadRecords(m); - delete m; } +void checkFstPrefixSearch() { + FstWriter *fw = new FstWriter; + int64_t s = taosGetTimestampUs(); + int count = 2; + std::string key("ab"); + + for (int i = 0; i < count; i++) { + key[1] = key[1] + i; + fw->Put(key, i); + } + int64_t e = taosGetTimestampUs(); + + std::cout << "insert data count : " << count << "elapas time: " << e - s << std::endl; + delete fw; + FstReadMemory *m = new FstReadMemory(1024 * 64); + if (m->init() == false) { + std::cout << "init readMemory failed" << std::endl; + delete m; + return; + } + + // prefix search + std::vector result; + AutomationCtx *ctx = automCtxCreate((void *)"ab", AUTOMATION_PREFIX); + m->Search(ctx, result); + assert(result.size() == count); + for (int i = 0; i < result.size(); i++) { + assert(result[i] == i); // check result + } + + free(ctx); + delete m; +} void validateFst() { int val = 100; int count = 100; @@ -209,6 +254,8 @@ void validateFst() { FstReadMemory *m = new FstReadMemory(1024 * 64); if (m->init() == false) { std::cout << "init readMemory failed" << std::endl; + delete m; + return; } { @@ -230,10 +277,12 @@ void validateFst() { } } delete m; - } + + int main(int argc, char** argv) { checkFstPerf(); + //checkFstPrefixSearch(); return 1; } diff --git a/source/libs/parser/CMakeLists.txt b/source/libs/parser/CMakeLists.txt index 155b72c1f9..5e635aa6a1 100644 --- a/source/libs/parser/CMakeLists.txt +++ b/source/libs/parser/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories( target_link_libraries( parser - PRIVATE os util common catalog function transport + PRIVATE os util common catalog function transport query ) -ADD_SUBDIRECTORY(test) \ No newline at end of file +ADD_SUBDIRECTORY(test) diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h index 8e8dc27c4f..4f506e631f 100644 --- a/source/libs/parser/inc/parserInt.h +++ b/source/libs/parser/inc/parserInt.h @@ -88,13 +88,13 @@ int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf); * @param msgBufLen * @return */ -int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen); +int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, char* msg, int32_t msgBufLen); /** * Destroy the meta data request structure. * @param pMetaInfo */ -void qParserClearupMetaRequestInfo(SMetaReq* pMetaInfo); +void qParserClearupMetaRequestInfo(SCatalogReq* pMetaInfo); #ifdef __cplusplus } diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index 300dd53df3..2ee95732d0 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -4029,18 +4029,18 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer } - SMetaReq req = {0}; + SCatalogReq req = {0}; SMetaData data = {0}; // TODO: check if the qnode info has been cached already - req.qNodeEpset = true; + req.qNodeRequired = true; code = qParserExtractRequestedMetaInfo(pInfo, &req, msgBuf, msgBufLen); if (code != TSDB_CODE_SUCCESS) { return code; } // load the meta data from catalog - code = catalogGetMetaData(pCatalog, &req, &data); + code = catalogGetAllMeta(pCatalog, NULL, NULL, &req, &data); if (code != TSDB_CODE_SUCCESS) { return code; } diff --git a/source/libs/parser/src/insertParser.c b/source/libs/parser/src/insertParser.c index c6ae149f1f..f63f13d8ac 100644 --- a/source/libs/parser/src/insertParser.c +++ b/source/libs/parser/src/insertParser.c @@ -71,8 +71,7 @@ typedef struct SInsertParseContext { const char* pSql; SMsgBuf msg; struct SCatalog* pCatalog; - SMetaData meta; // need release - const STableMeta* pTableMeta; + STableMeta* pTableMeta; SHashObj* pTableBlockHashObj; // data block for each table. need release int32_t totalNum; SInsertStmtInfo* pOutput; @@ -165,29 +164,29 @@ static int32_t skipInsertInto(SInsertParseContext* pCxt) { return TSDB_CODE_SUCCESS; } -static int32_t buildTableName(SInsertParseContext* pCxt, SToken* pStname, SArray* tableNameList) { +static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullDbName, char* tableName) { if (parserValidateIdToken(pStname) != TSDB_CODE_SUCCESS) { return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pStname->z); } - SName name = {0}; - strcpy(name.dbname, pCxt->pComCxt->pDbname); - strncpy(name.tname, pStname->z, pStname->n); - taosArrayPush(tableNameList, &name); - + char* p = strnchr(pStname->z, TS_PATH_DELIMITER[0], pStname->n, false); + if (NULL != p) { // db.table + strcpy(fullDbName, pCxt->pComCxt->pAcctId); + fullDbName[strlen(pCxt->pComCxt->pAcctId)] = TS_PATH_DELIMITER[0]; + strncpy(fullDbName, pStname->z, p - pStname->z); + strncpy(tableName, p + 1, pStname->n - (p - pStname->z) - 1); + } else { + snprintf(fullDbName, TSDB_FULL_DB_NAME_LEN, "%s.%s", pCxt->pComCxt->pAcctId, pCxt->pComCxt->pDbname); + strncpy(tableName, pStname->z, pStname->n); + } return TSDB_CODE_SUCCESS; } -static int32_t buildMetaReq(SInsertParseContext* pCxt, SToken* pStname, SMetaReq* pMetaReq) { - pMetaReq->pTableName = taosArrayInit(4, sizeof(SName)); - return buildTableName(pCxt, pStname, pMetaReq->pTableName); -} - static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) { - SMetaReq req; - CHECK_CODE(buildMetaReq(pCxt, pTname, &req)); - CHECK_CODE(catalogGetMetaData(pCxt->pCatalog, &req, &pCxt->meta)); - pCxt->pTableMeta = (STableMeta*)taosArrayGetP(pCxt->meta.pTableMeta, 0); + char fullDbName[TSDB_FULL_DB_NAME_LEN] = {0}; + char tableName[TSDB_TABLE_NAME_LEN] = {0}; + CHECK_CODE(buildName(pCxt, pTname, fullDbName, tableName)); + CHECK_CODE(catalogGetTableMeta(pCxt->pCatalog, pCxt->pComCxt->pRpc, pCxt->pComCxt->pEpSet, fullDbName, tableName, &pCxt->pTableMeta)); return TSDB_CODE_SUCCESS; } @@ -861,7 +860,7 @@ int32_t parseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) { .pComCxt = pContext, .pSql = pContext->pSql, .msg = {.buf = pContext->pMsg, .len = pContext->msgLen}, - .pCatalog = getCatalogHandle(pContext->pEpSet), + .pCatalog = NULL, .pTableMeta = NULL, .pTableBlockHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false), .totalNum = 0, @@ -872,6 +871,7 @@ int32_t parseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } + CHECK_CODE(catalogGetHandle(pContext->pClusterId, &context.pCatalog)); CHECK_CODE(skipInsertInto(&context)); CHECK_CODE(parseInsertBody(&context)); diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 4d08ddba96..1d883974b8 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -51,9 +51,9 @@ int32_t qParseQuerySql(const char* pStr, size_t length, int64_t id, int32_t *typ // do nothing } } else { - struct SCatalog* pCatalog = getCatalogHandle(NULL); - - int32_t code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, id, msg, msgLen); + struct SCatalog* pCatalog = NULL; + int32_t code = catalogGetHandle(NULL, &pCatalog); + code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, id, msg, msgLen); if (code == TSDB_CODE_SUCCESS) { *pOutput = pQueryInfo; } @@ -147,7 +147,7 @@ static void freePtrElem(void* p) { tfree(*(char**)p); } -int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMetaInfo, char* msg, int32_t msgBufLen) { +int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SCatalogReq* pMetaInfo, char* msg, int32_t msgBufLen) { int32_t code = TSDB_CODE_SUCCESS; SMsgBuf msgBuf = {.buf = msg, .len = msgBufLen}; @@ -204,7 +204,7 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet return code; } -void qParserClearupMetaRequestInfo(SMetaReq* pMetaReq) { +void qParserClearupMetaRequestInfo(SCatalogReq* pMetaReq) { if (pMetaReq == NULL) { return; } diff --git a/source/libs/parser/src/parserUtil.c b/source/libs/parser/src/parserUtil.c index 28c3bf20ef..3a61f5912b 100644 --- a/source/libs/parser/src/parserUtil.c +++ b/source/libs/parser/src/parserUtil.c @@ -1458,23 +1458,6 @@ void* vgroupInfoClear(SVgroupsInfo *vgroupList) { return NULL; } -char* serializeTagData(STagData* pTagData, char* pMsg) { - int32_t n = (int32_t) strlen(pTagData->name); - *(int32_t*) pMsg = htonl(n); - pMsg += sizeof(n); - - memcpy(pMsg, pTagData->name, n); - pMsg += n; - - *(int32_t*)pMsg = htonl(pTagData->dataLen); - pMsg += sizeof(int32_t); - - memcpy(pMsg, pTagData->data, pTagData->dataLen); - pMsg += pTagData->dataLen; - - return pMsg; -} - int32_t copyTagData(STagData* dst, const STagData* src) { dst->dataLen = src->dataLen; tstrncpy(dst->name, src->name, tListLen(dst->name)); @@ -1491,29 +1474,6 @@ int32_t copyTagData(STagData* dst, const STagData* src) { return 0; } -STableMeta* createSuperTableMeta(STableMetaMsg* pChild) { - assert(pChild != NULL); - int32_t total = pChild->numOfColumns + pChild->numOfTags; - - STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * total); - pTableMeta->tableType = TSDB_SUPER_TABLE; - pTableMeta->tableInfo.numOfTags = pChild->numOfTags; - pTableMeta->tableInfo.numOfColumns = pChild->numOfColumns; - pTableMeta->tableInfo.precision = pChild->precision; - - pTableMeta->uid = pChild->suid; - pTableMeta->tversion = pChild->tversion; - pTableMeta->sversion = pChild->sversion; - - memcpy(pTableMeta->schema, pChild->pSchema, sizeof(SSchema) * total); - - int32_t num = pTableMeta->tableInfo.numOfColumns; - for(int32_t i = 0; i < num; ++i) { - pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes; - } - - return pTableMeta; -} uint32_t getTableMetaSize(const STableMeta* pTableMeta) { assert(pTableMeta != NULL); diff --git a/source/libs/parser/test/CMakeLists.txt b/source/libs/parser/test/CMakeLists.txt index f7d7113243..03b76152da 100644 --- a/source/libs/parser/test/CMakeLists.txt +++ b/source/libs/parser/test/CMakeLists.txt @@ -6,13 +6,16 @@ SET(CMAKE_CXX_STANDARD 11) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) ADD_EXECUTABLE(parserTest ${SOURCE_LIST}) -TARGET_LINK_LIBRARIES( - parserTest - PUBLIC os util common parser catalog transport gtest function planner -) TARGET_INCLUDE_DIRECTORIES( parserTest PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/parser/" PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/inc" ) + +TARGET_LINK_LIBRARIES( + parserTest + PUBLIC os util common parser catalog transport gtest function planner query +) + +TARGET_LINK_OPTIONS(parserTest PRIVATE -Wl,-wrap,malloc) diff --git a/source/libs/parser/test/insertTest.cpp b/source/libs/parser/test/insertTest.cpp index 9cf48da4eb..5877adf41c 100644 --- a/source/libs/parser/test/insertTest.cpp +++ b/source/libs/parser/test/insertTest.cpp @@ -27,6 +27,27 @@ namespace { } } +extern "C" { + +#include + +void *__real_malloc(size_t); + +void *__wrap_malloc(size_t c) { + // printf("My MALLOC called: %d\n", c); + // void *array[32]; + // int size = backtrace(array, 32); + // char **symbols = backtrace_symbols(array, size); + // for (int i = 0; i < size; ++i) { + // cout << symbols[i] << endl; + // } + // free(symbols); + + return __real_malloc(c); +} + +} + // syntax: // INSERT INTO // tb_name diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 1f6fd71030..f2b34971ef 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -48,6 +48,6 @@ struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) { return mockCatalogService->getCatalogHandle(pMgmtEps); } -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) { +int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) { return mockCatalogService->catalogGetMetaData(pCatalog, pMetaReq, pMetaData); } diff --git a/source/libs/parser/test/mockCatalog.h b/source/libs/parser/test/mockCatalog.h index 32001d19fd..e60f7727e6 100644 --- a/source/libs/parser/test/mockCatalog.h +++ b/source/libs/parser/test/mockCatalog.h @@ -22,6 +22,6 @@ void generateMetaData(MockCatalogService* mcs); // mock struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps); -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData); +int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData); #endif // MOCK_CATALOG_H diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 46e82566d6..457f8d88bd 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -87,7 +87,7 @@ public: return (struct SCatalog*)0x01; } - int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) const { + int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const { assert(nullptr != pMetaReq && 1 == taosArrayGetSize(pMetaReq->pTableName)); SName* fullName = (SName*)taosArrayGet(pMetaReq->pTableName, 0); std::unique_ptr table; @@ -248,7 +248,7 @@ struct SCatalog* MockCatalogService::getCatalogHandle(const SEpSet* pMgmtEps) co return impl_->getCatalogHandle(pMgmtEps); } -int32_t MockCatalogService::catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) const { +int32_t MockCatalogService::catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const { return impl_->catalogGetMetaData(pCatalog, pMetaReq, pMetaData); } diff --git a/source/libs/parser/test/mockCatalogService.h b/source/libs/parser/test/mockCatalogService.h index 79572086a1..66b439b3e9 100644 --- a/source/libs/parser/test/mockCatalogService.h +++ b/source/libs/parser/test/mockCatalogService.h @@ -50,7 +50,7 @@ public: MockCatalogService(); ~MockCatalogService(); struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) const; - int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SMetaReq* pMetaReq, SMetaData* pMetaData) const; + int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const; ITableBuilder& createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, int32_t numOfColumns, int32_t numOfTags = 0); void createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid); void showTables() const; diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index 3a929c32f2..396e8a12fe 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -39,7 +39,7 @@ void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_ strcpy(p->name, name); } -void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq* req) { +void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SCatalogReq* req) { pQueryInfo->numOfTables = 1; pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES); @@ -81,7 +81,7 @@ void sqlCheck(const char* sql, bool valid) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -118,7 +118,7 @@ TEST(testCase, validateAST_test) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -176,7 +176,7 @@ TEST(testCase, function_Test) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -222,7 +222,7 @@ TEST(testCase, function_Test2) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -268,7 +268,7 @@ TEST(testCase, function_Test3) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -313,7 +313,7 @@ TEST(testCase, function_Test4) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -361,7 +361,7 @@ TEST(testCase, function_Test5) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -446,7 +446,7 @@ TEST(testCase, function_Test6) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -524,7 +524,7 @@ TEST(testCase, function_Test6) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -586,7 +586,7 @@ TEST(testCase, function_Test6) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -665,7 +665,7 @@ TEST(testCase, function_Test6) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); diff --git a/source/libs/parser/test/plannerTest.cpp b/source/libs/parser/test/plannerTest.cpp index c86e687664..a2078defda 100644 --- a/source/libs/parser/test/plannerTest.cpp +++ b/source/libs/parser/test/plannerTest.cpp @@ -30,6 +30,7 @@ #include "tdef.h" #include "tvariant.h" #include "planner.h" +#include "../../planner/inc/plannerInt.h" namespace { void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) { @@ -39,7 +40,7 @@ void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_ strcpy(p->name, name); } -void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) { +void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SCatalogReq *req) { pQueryInfo->numOfTables = 1; pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES); @@ -79,7 +80,7 @@ void generateLogicplan(const char* sql) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -92,10 +93,10 @@ void generateLogicplan(const char* sql) { ASSERT_EQ(ret, 0); struct SQueryPlanNode* n = nullptr; - code = qCreateQueryPlan(pQueryInfo, &n); + code = createQueryPlan(pQueryInfo, &n); char* str = NULL; - qQueryPlanToString(n, &str); + queryPlanToString(n, &str); printf("--------SQL:%s\n", sql); printf("%s\n", str); @@ -119,7 +120,7 @@ TEST(testCase, planner_test) { int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf); ASSERT_EQ(code, 0); - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); @@ -155,10 +156,10 @@ TEST(testCase, planner_test) { ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2); struct SQueryPlanNode* n = nullptr; - code = qCreateQueryPlan(pQueryInfo, &n); + code = createQueryPlan(pQueryInfo, &n); char* str = NULL; - qQueryPlanToString(n, &str); + queryPlanToString(n, &str); printf("%s\n", str); destroyQueryInfo(pQueryInfo); diff --git a/source/libs/parser/test/tokenizerTest.cpp b/source/libs/parser/test/tokenizerTest.cpp index 032a93cd32..23c0aae15f 100644 --- a/source/libs/parser/test/tokenizerTest.cpp +++ b/source/libs/parser/test/tokenizerTest.cpp @@ -709,7 +709,7 @@ TEST(testCase, extractMeta_test) { ASSERT_EQ(info1.valid, true); char msg[128] = {0}; - SMetaReq req = {0}; + SCatalogReq req = {0}; int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128); ASSERT_EQ(ret, 0); ASSERT_EQ(taosArrayGetSize(req.pTableName), 1); diff --git a/source/libs/planner/CMakeLists.txt b/source/libs/planner/CMakeLists.txt index 23efce38f4..4e0d03d07a 100644 --- a/source/libs/planner/CMakeLists.txt +++ b/source/libs/planner/CMakeLists.txt @@ -8,7 +8,7 @@ target_include_directories( target_link_libraries( planner - PRIVATE os util common catalog parser transport function + PRIVATE os util common catalog parser transport function query ) -ADD_SUBDIRECTORY(test) \ No newline at end of file +ADD_SUBDIRECTORY(test) diff --git a/source/libs/planner/inc/plannerInt.h b/source/libs/planner/inc/plannerInt.h index 6bd89905b1..38b399fb0b 100644 --- a/source/libs/planner/inc/plannerInt.h +++ b/source/libs/planner/inc/plannerInt.h @@ -23,12 +23,23 @@ extern "C" { #include "common.h" #include "tarray.h" #include "planner.h" +#include "parser.h" #include "taosmsg.h" -typedef struct SQueryNodeBasicInfo { - int32_t type; // operator type - char *name; // operator name -} SQueryNodeBasicInfo; +#define QNODE_TAGSCAN 1 +#define QNODE_TABLESCAN 2 +#define QNODE_PROJECT 3 +#define QNODE_AGGREGATE 4 +#define QNODE_GROUPBY 5 +#define QNODE_LIMIT 6 +#define QNODE_JOIN 7 +#define QNODE_DISTINCT 8 +#define QNODE_SORT 9 +#define QNODE_UNION 10 +#define QNODE_TIMEWINDOW 11 +#define QNODE_SESSIONWINDOW 12 +#define QNODE_STATEWINDOW 13 +#define QNODE_FILL 14 typedef struct SQueryDistPlanNodeInfo { bool stableQuery; // super table query or not @@ -39,8 +50,9 @@ typedef struct SQueryDistPlanNodeInfo { } SQueryDistPlanNodeInfo; typedef struct SQueryTableInfo { - char *tableName; - uint64_t uid; + char *tableName; // to be deleted + uint64_t uid; // to be deleted + STableMetaInfo* pMeta; STimeWindow window; } SQueryTableInfo; @@ -51,56 +63,64 @@ typedef struct SQueryPlanNode { SArray *pExpr; // the query functions or sql aggregations int32_t numOfExpr; // number of result columns, which is also the number of pExprs void *pExtInfo; // additional information - // previous operator to generated result for current node to process + // children operator to generated result for current node to process // in case of join, multiple prev nodes exist. - SArray *pPrevNodes; // upstream nodes - struct SQueryPlanNode *nextNode; + SArray *pChildren; // upstream nodes + struct SQueryPlanNode *pParent; } SQueryPlanNode; -typedef struct SQueryDistPlanNode { - SQueryNodeBasicInfo info; - SSchema *pSchema; // the schema of the input SSDatablock - int32_t numOfCols; // number of input columns - SArray *pExpr; // the query functions or sql aggregations - int32_t numOfExpr; // number of result columns, which is also the number of pExprs - void *pExtInfo; // additional information +/** + * Optimize the query execution plan, currently not implement yet. + * @param pQueryNode + * @return + */ +int32_t optimizeQueryPlan(struct SQueryPlanNode* pQueryNode); - // previous operator to generated result for current node to process - // in case of join, multiple prev nodes exist. - SArray *pPrevNodes; // upstream nodes, or exchange operator to load data from multiple sources. -} SQueryDistPlanNode; +/** + * Create the query plan according to the bound AST, which is in the form of pQueryInfo + * @param pQueryInfo + * @param pQueryNode + * @return + */ +int32_t createQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode); -typedef struct SQueryCostSummary { - int64_t startTs; // Object created and added into the message queue - int64_t endTs; // the timestamp when the task is completed - int64_t cputime; // total cpu cost, not execute elapsed time +/** + * Convert the query plan to string, in order to display it in the shell. + * @param pQueryNode + * @return + */ +int32_t queryPlanToString(struct SQueryPlanNode* pQueryNode, char** str); - int64_t loadRemoteDataDuration; // remote io time - int64_t loadNativeDataDuration; // native disk io time +/** + * Restore the SQL statement according to the logic query plan. + * @param pQueryNode + * @param sql + * @return + */ +int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql); - uint64_t loadNativeData; // blocks + SMA + header files - uint64_t loadRemoteData; // remote data acquired by exchange operator. +int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryDag** pDag); - uint64_t waitDuration; // the time to waiting to be scheduled in queue does matter, so we need to record it - int64_t addQTs; // the time to be added into the message queue, used to calculate the waiting duration in queue. +/** + * Convert to physical plan to string to enable to print it out in the shell. + * @param pPhyNode + * @param str + * @return + */ +int32_t phyPlanToString(struct SPhyNode *pPhyNode, char** str); - uint64_t totalRows; - uint64_t loadRows; - uint32_t totalBlocks; - uint32_t loadBlocks; - uint32_t loadBlockAgg; - uint32_t skipBlocks; - uint64_t resultSize; // generated result size in Kb. -} SQueryCostSummary; +/** + * Destroy the query plan object. + * @return + */ +void destroyQueryPlan(struct SQueryPlanNode* pQueryNode); -typedef struct SQueryTask { - uint64_t queryId; // query id - uint64_t taskId; // task id - SQueryDistPlanNode *pNode; // operator tree - uint64_t status; // task status - SQueryCostSummary summary; // task execution summary - void *pOutputHandle; // result buffer handle, to temporarily keep the output result for next stage -} SQueryTask; +/** + * Destroy the physical plan. + * @param pQueryPhyNode + * @return + */ +void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode); #ifdef __cplusplus } diff --git a/source/libs/planner/src/logicPlan.c b/source/libs/planner/src/logicPlan.c new file mode 100644 index 0000000000..ce923314bd --- /dev/null +++ b/source/libs/planner/src/logicPlan.c @@ -0,0 +1,604 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "function.h" +#include "os.h" +#include "parser.h" +#include "plannerInt.h" + +typedef struct SFillEssInfo { + int32_t fillType; // fill type + int64_t *val; // fill value +} SFillEssInfo; + +typedef struct SJoinCond { + bool tagExists; // denote if tag condition exists or not + SColumn *tagCond[2]; + SColumn *colCond[2]; +} SJoinCond; + +static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo); +static void doDestroyQueryNode(SQueryPlanNode* pQueryNode); + +int32_t printExprInfo(char* buf, const SQueryPlanNode* pQueryNode, int32_t len); +int32_t optimizeQueryPlan(struct SQueryPlanNode* pQueryNode) { + return 0; +} + +int32_t createQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode) { + SArray* upstream = createQueryPlanImpl((struct SQueryStmtInfo*) pQueryInfo); + assert(taosArrayGetSize(upstream) == 1); + + *pQueryNode = taosArrayGetP(upstream, 0); + + taosArrayDestroy(upstream); + return TSDB_CODE_SUCCESS; +} + +int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql) { + return 0; +} + +void destroyQueryPlan(SQueryPlanNode* pQueryNode) { + if (pQueryNode == NULL) { + return; + } + + doDestroyQueryNode(pQueryNode); +} + +//====================================================================================================================== + +static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** prev, int32_t numOfPrev, + SExprInfo** pExpr, int32_t numOfOutput, void* pExtInfo) { + SQueryPlanNode* pNode = calloc(1, sizeof(SQueryPlanNode)); + + pNode->info.type = type; + pNode->info.name = strdup(name); + + pNode->numOfExpr = numOfOutput; + pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); + + for(int32_t i = 0; i < numOfOutput; ++i) { + taosArrayPush(pNode->pExpr, &pExpr[i]); + } + + pNode->pChildren = taosArrayInit(4, POINTER_BYTES); + for(int32_t i = 0; i < numOfPrev; ++i) { + taosArrayPush(pNode->pChildren, &prev[i]); + } + + switch(type) { + case QNODE_TAGSCAN: + case QNODE_TABLESCAN: { + SQueryTableInfo* info = calloc(1, sizeof(SQueryTableInfo)); + memcpy(info, pExtInfo, sizeof(SQueryTableInfo)); + info->tableName = strdup(((SQueryTableInfo*) pExtInfo)->tableName); + pNode->pExtInfo = info; + break; + } + + case QNODE_TIMEWINDOW: { + SInterval* pInterval = calloc(1, sizeof(SInterval)); + pNode->pExtInfo = pInterval; + memcpy(pInterval, pExtInfo, sizeof(SInterval)); + break; + } + + case QNODE_STATEWINDOW: { + SColumn* psw = calloc(1, sizeof(SColumn)); + pNode->pExtInfo = psw; + memcpy(psw, pExtInfo, sizeof(SColumn)); + break; + } + + case QNODE_SESSIONWINDOW: { + SSessionWindow *pSessionWindow = calloc(1, sizeof(SSessionWindow)); + pNode->pExtInfo = pSessionWindow; + memcpy(pSessionWindow, pExtInfo, sizeof(struct SSessionWindow)); + break; + } + + case QNODE_GROUPBY: { + SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo; + + SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr)); + pGroupbyExpr->groupbyTag = p->groupbyTag; + pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo); + + pNode->pExtInfo = pGroupbyExpr; + break; + } + + case QNODE_FILL: { // todo !! + pNode->pExtInfo = pExtInfo; + break; + } + + case QNODE_LIMIT: { + pNode->pExtInfo = calloc(1, sizeof(SLimit)); + memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimit)); + break; + } + + case QNODE_SORT: { + pNode->pExtInfo = taosArrayDup(pExtInfo); + break; + } + + default: + break; + } + + return pNode; +} + +static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info, + SArray* pExprs, SArray* tableCols) { + if (pQueryInfo->info.onlyTagQuery) { + int32_t num = (int32_t) taosArrayGetSize(pExprs); + SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info); + + if (pQueryInfo->info.distinct) { + pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, NULL); + } + + return pNode; + } + + SQueryPlanNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0, info); + + if (pQueryInfo->info.projectionQuery) { + int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); + pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, NULL); + } else { + STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0); + + // table source column projection, generate the projection expr + int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols); + SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES); + for (int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCol = taosArrayGetP(tableCols, i); + + SSourceParam param = {0}; + addIntoSourceParam(¶m, NULL, pCol); + SSchema s = createSchema(pCol->info.type, pCol->info.bytes, pCol->info.colId, pCol->name); + SExprInfo* p = createExprInfo(pTableMetaInfo1, "project", ¶m, &s, 0); + pExpr[i] = p; + } + + pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, NULL); + tfree(pExpr); + } + + return pNode; +} + +static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(SQueryStmtInfo* pQueryInfo, SQueryPlanNode* pNode, SQueryTableInfo* info) { + // group by column not by tag + size_t numOfGroupCols = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo); + + // check for aggregation + int32_t level = getExprFunctionLevel(pQueryInfo); + + for(int32_t i = level - 1; i >= 0; --i) { + SArray* p = pQueryInfo->exprList[i]; + size_t num = taosArrayGetSize(p); + + bool aggregateFunc = false; + for(int32_t j = 0; j < num; ++j) { + SExprInfo* pExpr = (SExprInfo*)taosArrayGetP(p, 0); + if (pExpr->pExpr->nodeType != TEXPR_FUNCTION_NODE) { + continue; + } + + aggregateFunc = qIsAggregateFunction(pExpr->pExpr->_function.functionName); + if (aggregateFunc) { + break; + } + } + + if (aggregateFunc) { + if (pQueryInfo->interval.interval > 0) { + pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->interval); + } else if (pQueryInfo->sessionWindow.gap > 0) { + pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->sessionWindow); + } else if (pQueryInfo->stateWindow.col.info.colId > 0) { + pNode = createQueryNode(QNODE_STATEWINDOW, "StateWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->stateWindow); + } else if (numOfGroupCols != 0 && !pQueryInfo->groupbyExpr.groupbyTag) { + pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, p->pData, num, &pQueryInfo->groupbyExpr); + } else { + pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, p->pData, num, NULL); + } + } else { + pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, num, NULL); + } + } + + if (pQueryInfo->havingFieldNum > 0) { +// int32_t numOfExpr = (int32_t)taosArrayGetSize(pQueryInfo->exprList1); +// pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, NULL); + } + + if (pQueryInfo->fillType != TSDB_FILL_NONE) { + SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo)); + pInfo->fillType = pQueryInfo->fillType; + pInfo->val = calloc(pNode->numOfExpr, sizeof(int64_t)); + memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfExpr); + + SArray* p = pQueryInfo->exprList[0]; // top expression in select clause + pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, p, taosArrayGetSize(p), pInfo); + } + + if (pQueryInfo->order != NULL) { + SArray* pList = pQueryInfo->exprList[0]; + pNode = createQueryNode(QNODE_SORT, "Sort", &pNode, 1, pList->pData, taosArrayGetSize(pList), pQueryInfo->order); + } + + if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) { + pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, &pQueryInfo->limit); + } + + return pNode; +} + +static SQueryPlanNode* doCreateQueryPlanForSingleTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs, + SArray* tableCols) { + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tstrncpy(name, pTableMetaInfo->name.tname, TSDB_TABLE_FNAME_LEN); + + SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; + + // handle the only tag query + SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols); + if (pQueryInfo->info.onlyTagQuery) { + tfree(info.tableName); + return pNode; + } + + SQueryPlanNode* pNode1 = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info); + tfree(info.tableName); + return pNode1; +} + +static bool isAllAggExpr(SArray* pList) { + assert(pList != NULL); + + for (int32_t k = 0; k < taosArrayGetSize(pList); ++k) { + SExprInfo* p = taosArrayGetP(pList, k); + if (p->pExpr->nodeType != TEXPR_FUNCTION_NODE || !qIsAggregateFunction(p->pExpr->_function.functionName)) { + return false; + } + } + + return true; +} + +SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) { + SArray* upstream = NULL; + + if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause + upstream = taosArrayInit(4, POINTER_BYTES); + + size_t size = taosArrayGetSize(pQueryInfo->pUpstream); + for(int32_t i = 0; i < size; ++i) { + SQueryStmtInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i); + SArray* p = createQueryPlanImpl(pq); + taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p)); + } + } + + if (pQueryInfo->numOfTables > 1) { // it is a join query + // 1. separate the select clause according to table + taosArrayDestroy(upstream); + upstream = taosArrayInit(5, POINTER_BYTES); + + for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i]; + uint64_t uid = pTableMetaInfo->pTableMeta->uid; + + SArray* exprList = taosArrayInit(4, POINTER_BYTES); + if (copyExprInfoList(exprList, pQueryInfo->exprList[0], uid, true) != 0) { + terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; +// dropAllExprInfo(exprList); + exit(-1); + } + + // 2. create the query execution node + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tNameExtractFullName(&pTableMetaInfo->name, name); + SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; + + // 3. get the required table column list + SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn)); + columnListCopy(tableColumnList, pQueryInfo->colList, uid); + + // 4. add the projection query node + SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList); + columnListDestroy(tableColumnList); +// dropAllExprInfo(exprList); + taosArrayPush(upstream, &pNode); + } + + // 3. add the join node here + SQueryTableInfo info = {0}; + int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList[0]); + SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables, + pQueryInfo->exprList[0]->pData, num, NULL); + + // 4. add the aggregation or projection execution node + pNode = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info); + upstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(upstream, &pNode); + } else { // only one table, normal query process + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; + SQueryPlanNode* pNode = doCreateQueryPlanForSingleTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList[0], pQueryInfo->colList); + upstream = taosArrayInit(5, POINTER_BYTES); + taosArrayPush(upstream, &pNode); + } + + return upstream; +} + +static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) { + tfree(pQueryNode->pExtInfo); + tfree(pQueryNode->pSchema); + tfree(pQueryNode->info.name); +// dropAllExprInfo(pQueryNode->pExpr); + + if (pQueryNode->pChildren != NULL) { + int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pChildren); + for(int32_t i = 0; i < size; ++i) { + SQueryPlanNode* p = taosArrayGetP(pQueryNode->pChildren, i); + doDestroyQueryNode(p); + } + + taosArrayDestroy(pQueryNode->pChildren); + } + + tfree(pQueryNode); +} + +static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) { + if (level > 0) { + sprintf(buf + totalLen, "%*c", level, ' '); + totalLen += level; + } + + int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name); + int32_t len = len1 + totalLen; + + switch(pQueryNode->info.type) { + case QNODE_TABLESCAN: { + SQueryTableInfo* pInfo = (SQueryTableInfo*)pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64, pInfo->tableName, pInfo->uid, + pInfo->window.skey, pInfo->window.ekey); + assert(len1 > 0); + len += len1; + + for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { + SColumn* pCol = taosArrayGetP(pQueryNode->pExpr, i); + len1 = sprintf(buf + len, " [%s #%d] ", pCol->name, pCol->info.colId); + + assert(len1 > 0); + len += len1; + } + + len1 = sprintf(buf + len, "\n"); + assert(len1 > 0); + + len += len1; + break; + } + + case QNODE_PROJECT: { + len1 = sprintf(buf + len, "cols:"); + assert(len1 > 0); + len += len1; + + len = printExprInfo(buf, pQueryNode, len); + len1 = sprintf(buf + len, ")"); + len += len1; + + // todo print filter info + len1 = sprintf(buf + len, " filters:(nil)\n"); + len += len1; + break; + } + + case QNODE_AGGREGATE: { + len = printExprInfo(buf, pQueryNode, len); + len1 = sprintf(buf + len, ")\n"); + len += len1; + + break; + } + + case QNODE_TIMEWINDOW: { + len = printExprInfo(buf, pQueryNode, len); + len1 = sprintf(buf + len, ") "); + len += len1; + + SInterval* pInterval = pQueryNode->pExtInfo; + + // todo dynamic return the time precision + len1 = sprintf(buf + len, "interval:%" PRId64 "(%s), sliding:%" PRId64 "(%s), offset:%" PRId64 "(%s)\n", + pInterval->interval, TSDB_TIME_PRECISION_MILLI_STR, pInterval->sliding, + TSDB_TIME_PRECISION_MILLI_STR, pInterval->offset, TSDB_TIME_PRECISION_MILLI_STR); + len += len1; + + break; + } + + case QNODE_STATEWINDOW: { + len = printExprInfo(buf, pQueryNode, len); + len1 = sprintf(buf + len, ") "); + len += len1; + + SColumn* pCol = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "col:%s #%d\n", pCol->name, pCol->info.colId); + len += len1; + break; + } + + case QNODE_SESSIONWINDOW: { + len = printExprInfo(buf, pQueryNode, len); + + len1 = sprintf(buf + len, ") "); + len += len1; + + struct SSessionWindow* ps = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "col:[%s #%d], gap:%" PRId64 " (ms) \n", ps->col.name, ps->col.info.colId, ps->gap); + len += len1; + break; + } + + case QNODE_GROUPBY: { + len = printExprInfo(buf, pQueryNode, len); + + SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, ") groupby_col: "); + len += len1; + + for (int32_t i = 0; i < taosArrayGetSize(pGroupbyExpr->columnInfo); ++i) { + SColumn* pCol = taosArrayGet(pGroupbyExpr->columnInfo, i); + len1 = sprintf(buf + len, "[%s #%d] ", pCol->name, pCol->info.colId); + len += len1; + } + + len += sprintf(buf + len, "\n"); + break; + } + + case QNODE_FILL: { + SFillEssInfo* pEssInfo = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "%d", pEssInfo->fillType); + len += len1; + + if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) { + len1 = sprintf(buf + len, ", val:"); + len += len1; + + // todo get the correct fill data type + for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { + len1 = sprintf(buf + len, "%" PRId64, pEssInfo->val[i]); + len += len1; + + if (i < pQueryNode->numOfExpr - 1) { + len1 = sprintf(buf + len, ", "); + len += len1; + } + } + } + + len1 = sprintf(buf + len, ")\n"); + len += len1; + break; + } + + case QNODE_LIMIT: { + SLimit* pVal = pQueryNode->pExtInfo; + len1 = sprintf(buf + len, "limit: %" PRId64 ", offset: %" PRId64 ")\n", pVal->limit, pVal->offset); + len += len1; + break; + } + + case QNODE_DISTINCT: + case QNODE_TAGSCAN: { + len1 = sprintf(buf + len, "cols: "); + len += len1; + + len = printExprInfo(buf, pQueryNode, len); + + len1 = sprintf(buf + len, ")\n"); + len += len1; + + break; + } + + case QNODE_SORT: { + len1 = sprintf(buf + len, "cols:"); + len += len1; + + SArray* pSort = pQueryNode->pExtInfo; + for (int32_t i = 0; i < taosArrayGetSize(pSort); ++i) { + SOrder* p = taosArrayGet(pSort, i); + len1 = sprintf(buf + len, " [%s #%d %s]", p->col.name, p->col.info.colId, p->order == TSDB_ORDER_ASC? "ASC":"DESC"); + + len += len1; + } + + len1 = sprintf(buf + len, ")\n"); + len += len1; + break; + } + + case QNODE_JOIN: { + // print join condition + len1 = sprintf(buf + len, ")\n"); + len += len1; + break; + } + } + + return len; +} + +int32_t printExprInfo(char* buf, const SQueryPlanNode* pQueryNode, int32_t len) { + int32_t len1 = 0; + + for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { + SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i); + + SSqlExpr* pExpr = &pExprInfo->base; + len1 = sprintf(buf + len, "%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); + assert(len1 > 0); + + len += len1; + if (i < pQueryNode->numOfExpr - 1) { + len1 = sprintf(buf + len, ", "); + len += len1; + } + } + + return len; +} + +int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) { + int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen); + + for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pChildren); ++i) { + SQueryPlanNode* p1 = taosArrayGetP(pQueryNode->pChildren, i); + int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len); + len = len1; + } + + return len; +} + +int32_t queryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) { + assert(pQueryNode); + + *str = calloc(1, 4096); + + int32_t len = sprintf(*str, "===== logic plan =====\n"); + queryPlanToStringImpl(*str, pQueryNode, 0, len); + + return TSDB_CODE_SUCCESS; +} + +SQueryPlanNode* queryPlanFromString() { + return NULL; +} diff --git a/source/libs/planner/src/physicalPlan.c b/source/libs/planner/src/physicalPlan.c new file mode 100644 index 0000000000..277703f5c0 --- /dev/null +++ b/source/libs/planner/src/physicalPlan.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "plannerInt.h" +#include "parser.h" + +#define STORE_CURRENT_SUBPLAN(cxt) SSubplan* _ = cxt->pCurrentSubplan +#define RECOVERY_CURRENT_SUBPLAN(cxt) cxt->pCurrentSubplan = _ + +static const char* gOpName[] = { + "Unknown", +#define INCLUDE_AS_NAME +#include "plannerOp.h" +#undef INCLUDE_AS_NAME +}; + +typedef struct SPlanContext { + struct SCatalog* pCatalog; + struct SQueryDag* pDag; + SSubplan* pCurrentSubplan; + SSubplanId nextId; +} SPlanContext; + +static void toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) { + SWAP(dataBlockSchema->pSchema, pPlanNode->pSchema, SSchema*); + dataBlockSchema->numOfCols = pPlanNode->numOfCols; +} + +static SPhyNode* initPhyNode(SQueryPlanNode* pPlanNode, int32_t type, int32_t size) { + SPhyNode* node = (SPhyNode*)calloc(1, size); + node->info.type = type; + node->info.name = gOpName[type]; + SWAP(node->pTargets, pPlanNode->pExpr, SArray*); + toDataBlockSchema(pPlanNode, &(node->targetSchema)); +} + +static SPhyNode* initScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t type, int32_t size) { + SScanPhyNode* node = (SScanPhyNode*)initPhyNode(pPlanNode, type, size); + node->uid = pTable->pMeta->pTableMeta->uid; + node->tableType = pTable->pMeta->pTableMeta->tableType; + return (SPhyNode*)node; +} + +static SPhyNode* createPseudoScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t op) { + return initScanNode(pPlanNode, pTable, op, sizeof(SScanPhyNode)); +} + +static SPhyNode* createTagScanNode(SQueryPlanNode* pPlanNode) { + SQueryTableInfo* pTable = (SQueryTableInfo*)pPlanNode->pExtInfo; + return createPseudoScanNode(pPlanNode, pTable, OP_TagScan); +} + +static uint8_t getScanFlag(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { + // todo + return MASTER_SCAN; +} + +static SPhyNode* createUserTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t op) { + STableScanPhyNode* node = (STableScanPhyNode*)initScanNode(pPlanNode, pTable, op, sizeof(STableScanPhyNode)); + node->scanFlag = getScanFlag(pPlanNode, pTable); + node->window = pTable->window; + // todo tag cond + return (SPhyNode*)node; +} + +static SPhyNode* createSingleTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { + return createUserTableScanNode(pPlanNode, pTable, OP_TableScan); +} + +static bool isSystemTable(SQueryTableInfo* pTable) { + // todo + return false; +} + +static bool needSeqScan(SQueryPlanNode* pPlanNode) { + // todo + return false; +} + +static SPhyNode* createMultiTableScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { + if (isSystemTable(pTable)) { + return createPseudoScanNode(pPlanNode, pTable, OP_SystemTableScan); + } else if (needSeqScan(pPlanNode)) { + return createUserTableScanNode(pPlanNode, pTable, OP_TableSeqScan); + } + return createUserTableScanNode(pPlanNode, pTable, OP_DataBlocksOptScan); +} + +static SSubplan* initSubplan(SPlanContext* pCxt, int32_t type) { + SSubplan* subplan = calloc(1, sizeof(SSubplan)); + subplan->id = pCxt->nextId; + ++(pCxt->nextId.subplanId); + subplan->type = type; + subplan->level = 0; + if (NULL != pCxt->pCurrentSubplan) { + subplan->level = pCxt->pCurrentSubplan->level + 1; + if (NULL == pCxt->pCurrentSubplan->pChildern) { + pCxt->pCurrentSubplan->pChildern = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); + } + taosArrayPush(pCxt->pCurrentSubplan->pChildern, &subplan); + subplan->pParents = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); + taosArrayPush(subplan->pParents, &pCxt->pCurrentSubplan); + } + SArray* currentLevel; + if (subplan->level >= taosArrayGetSize(pCxt->pDag->pSubplans)) { + currentLevel = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); + taosArrayPush(pCxt->pDag->pSubplans, ¤tLevel); + } else { + currentLevel = taosArrayGetP(pCxt->pDag->pSubplans, subplan->level); + } + taosArrayPush(currentLevel, &subplan); + pCxt->pCurrentSubplan = subplan; + return subplan; +} + +static void vgroupToEpSet(const SVgroupMsg* vg, SEpSet* epSet) { + epSet->inUse = 0; // todo + epSet->numOfEps = vg->numOfEps; + for (int8_t i = 0; i < vg->numOfEps; ++i) { + epSet->port[i] = vg->epAddr[i].port; + strcpy(epSet->fqdn[i], vg->epAddr[i].fqdn); + } + return; +} + +static uint64_t splitSubplanByTable(SPlanContext* pCxt, SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable) { + SVgroupsInfo* vgroupList = pTable->pMeta->vgroupList; + for (int32_t i = 0; i < pTable->pMeta->vgroupList->numOfVgroups; ++i) { + STORE_CURRENT_SUBPLAN(pCxt); + SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_SCAN); + vgroupToEpSet(&(pTable->pMeta->vgroupList->vgroups[i]), &subplan->execEpSet); + subplan->pNode = createMultiTableScanNode(pPlanNode, pTable); + RECOVERY_CURRENT_SUBPLAN(pCxt); + } + return pCxt->nextId.templateId++; +} + +static SPhyNode* createExchangeNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode, uint64_t srcTemplateId) { + SExchangePhyNode* node = (SExchangePhyNode*)initPhyNode(pPlanNode, OP_Exchange, sizeof(SExchangePhyNode)); + node->srcTemplateId = srcTemplateId; + return (SPhyNode*)node; +} + +static bool needMultiNodeScan(SQueryTableInfo* pTable) { + // todo system table, for instance, user_tables + return (TSDB_SUPER_TABLE == pTable->pMeta->pTableMeta->tableType); +} + +static SPhyNode* createTableScanNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { + SQueryTableInfo* pTable = (SQueryTableInfo*)pPlanNode->pExtInfo; + if (needMultiNodeScan(pTable)) { + return createExchangeNode(pCxt, pPlanNode, splitSubplanByTable(pCxt, pPlanNode, pTable)); + } + return createSingleTableScanNode(pPlanNode, pTable); +} + +static SPhyNode* createPhyNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) { + SPhyNode* node = NULL; + switch (pPlanNode->info.type) { + case QNODE_TAGSCAN: + node = createTagScanNode(pPlanNode); + break; + case QNODE_TABLESCAN: + node = createTableScanNode(pCxt, pPlanNode); + break; + default: + assert(false); + } + if (pPlanNode->pChildren != NULL && taosArrayGetSize(pPlanNode->pChildren) > 0) { + node->pChildren = taosArrayInit(4, POINTER_BYTES); + size_t size = taosArrayGetSize(pPlanNode->pChildren); + for(int32_t i = 0; i < size; ++i) { + SPhyNode* child = createPhyNode(pCxt, taosArrayGet(pPlanNode->pChildren, i)); + child->pParent = node; + taosArrayPush(node->pChildren, &child); + } + } + return node; +} + +static void createSubplanByLevel(SPlanContext* pCxt, SQueryPlanNode* pRoot) { + SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_MERGE); + ++(pCxt->nextId.templateId); + subplan->pNode = createPhyNode(pCxt, pRoot); + SArray* l0 = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); + taosArrayPush(l0, &subplan); + taosArrayPush(pCxt->pDag->pSubplans, &l0); + // todo deal subquery +} + +int32_t createDag(SQueryPlanNode* pQueryNode, struct SCatalog* pCatalog, SQueryDag** pDag) { + SPlanContext context = { + .pCatalog = pCatalog, + .pDag = calloc(1, sizeof(SQueryDag)), + .pCurrentSubplan = NULL, + .nextId = {0} // todo queryid + }; + if (NULL == context.pDag) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + context.pDag->pSubplans = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); + createSubplanByLevel(&context, pQueryNode); + *pDag = context.pDag; + return TSDB_CODE_SUCCESS; +} + +int32_t subPlanToString(struct SSubplan *pPhyNode, char** str) { + return TSDB_CODE_SUCCESS; +} diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index 79c7691698..744a849e2d 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -13,623 +13,31 @@ * along with this program. If not, see . */ -#include "function.h" -#include "os.h" #include "parser.h" #include "plannerInt.h" -#define QNODE_TAGSCAN 1 -#define QNODE_TABLESCAN 2 -#define QNODE_PROJECT 3 -#define QNODE_AGGREGATE 4 -#define QNODE_GROUPBY 5 -#define QNODE_LIMIT 6 -#define QNODE_JOIN 7 -#define QNODE_DISTINCT 8 -#define QNODE_SORT 9 -#define QNODE_UNION 10 -#define QNODE_TIMEWINDOW 11 -#define QNODE_SESSIONWINDOW 12 -#define QNODE_STATEWINDOW 13 -#define QNODE_FILL 14 - -typedef struct SFillEssInfo { - int32_t fillType; // fill type - int64_t *val; // fill value -} SFillEssInfo; - -typedef struct SJoinCond { - bool tagExists; // denote if tag condition exists or not - SColumn *tagCond[2]; - SColumn *colCond[2]; -} SJoinCond; - -static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo); -static void doDestroyQueryNode(SQueryPlanNode* pQueryNode); - -int32_t printExprInfo(const char* buf, const SQueryPlanNode* pQueryNode, int32_t len); -int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode) { - return 0; +void qDestroyQueryDag(struct SQueryDag* pDag) { + // todo } -int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode) { - SArray* upstream = createQueryPlanImpl((struct SQueryStmtInfo*) pQueryInfo); - assert(taosArrayGetSize(upstream) == 1); - - *pQueryNode = taosArrayGetP(upstream, 0); - - taosArrayDestroy(upstream); +int32_t qCreateQueryDag(const struct SQueryStmtInfo* pQueryInfo, struct SEpSet* pQnode, struct SQueryDag** pDag) { + SQueryPlanNode* logicPlan; + int32_t code = createQueryPlan(pQueryInfo, &logicPlan); + if (TSDB_CODE_SUCCESS != code) { + destroyQueryPlan(logicPlan); + return code; + } + code = optimizeQueryPlan(logicPlan); + if (TSDB_CODE_SUCCESS != code) { + destroyQueryPlan(logicPlan); + return code; + } + code = createDag(logicPlan, NULL, pDag); + if (TSDB_CODE_SUCCESS != code) { + destroyQueryPlan(logicPlan); + qDestroyQueryDag(*pDag); + return code; + } + destroyQueryPlan(logicPlan); return TSDB_CODE_SUCCESS; } - -int32_t qQueryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql) { - return 0; -} - -int32_t qCreatePhysicalPlan(struct SQueryPlanNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode) { - return 0; -} - -int32_t qPhyPlanToString(struct SQueryDistPlanNode *pPhyNode, char** str) { - return 0; -} - -void* qDestroyQueryPlan(SQueryPlanNode* pQueryNode) { - if (pQueryNode == NULL) { - return NULL; - } - - doDestroyQueryNode(pQueryNode); - return NULL; -} - -void* qDestroyQueryPhyPlan(struct SQueryDistPlanNode* pQueryPhyNode) { - return NULL; -} - -int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQueryJob** pJob) { - return 0; -} - -//====================================================================================================================== - -static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** prev, int32_t numOfPrev, - SExprInfo** pExpr, int32_t numOfOutput, void* pExtInfo) { - SQueryPlanNode* pNode = calloc(1, sizeof(SQueryPlanNode)); - - pNode->info.type = type; - pNode->info.name = strdup(name); - - pNode->numOfExpr = numOfOutput; - pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); - - for(int32_t i = 0; i < numOfOutput; ++i) { - taosArrayPush(pNode->pExpr, &pExpr[i]); - } - - pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES); - for(int32_t i = 0; i < numOfPrev; ++i) { - taosArrayPush(pNode->pPrevNodes, &prev[i]); - } - - switch(type) { - case QNODE_TABLESCAN: { - SQueryTableInfo* info = calloc(1, sizeof(SQueryTableInfo)); - memcpy(info, pExtInfo, sizeof(SQueryTableInfo)); - info->tableName = strdup(((SQueryTableInfo*) pExtInfo)->tableName); - pNode->pExtInfo = info; - break; - } - - case QNODE_TIMEWINDOW: { - SInterval* pInterval = calloc(1, sizeof(SInterval)); - pNode->pExtInfo = pInterval; - memcpy(pInterval, pExtInfo, sizeof(SInterval)); - break; - } - - case QNODE_STATEWINDOW: { - SColumn* psw = calloc(1, sizeof(SColumn)); - pNode->pExtInfo = psw; - memcpy(psw, pExtInfo, sizeof(SColumn)); - break; - } - - case QNODE_SESSIONWINDOW: { - SSessionWindow *pSessionWindow = calloc(1, sizeof(SSessionWindow)); - pNode->pExtInfo = pSessionWindow; - memcpy(pSessionWindow, pExtInfo, sizeof(struct SSessionWindow)); - break; - } - - case QNODE_GROUPBY: { - SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo; - - SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr)); - pGroupbyExpr->groupbyTag = p->groupbyTag; - pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo); - - pNode->pExtInfo = pGroupbyExpr; - break; - } - - case QNODE_FILL: { // todo !! - pNode->pExtInfo = pExtInfo; - break; - } - - case QNODE_LIMIT: { - pNode->pExtInfo = calloc(1, sizeof(SLimit)); - memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimit)); - break; - } - - case QNODE_SORT: { - pNode->pExtInfo = taosArrayDup(pExtInfo); - break; - } - - default: - break; - } - - return pNode; -} - -static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info, - SArray* pExprs, SArray* tableCols) { - if (pQueryInfo->info.onlyTagQuery) { - int32_t num = (int32_t) taosArrayGetSize(pExprs); - SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, NULL); - - if (pQueryInfo->info.distinct) { - pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, NULL); - } - - return pNode; - } - - SQueryPlanNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0, info); - - if (pQueryInfo->info.projectionQuery) { - int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs); - pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, NULL); - } else { - STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0); - - // table source column projection, generate the projection expr - int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols); - SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES); - for (int32_t i = 0; i < numOfCols; ++i) { - SColumn* pCol = taosArrayGetP(tableCols, i); - - SSourceParam param = {0}; - addIntoSourceParam(¶m, NULL, pCol); - SSchema s = createSchema(pCol->info.type, pCol->info.bytes, pCol->info.colId, pCol->name); - SExprInfo* p = createExprInfo(pTableMetaInfo1, "project", ¶m, &s, 0); - pExpr[i] = p; - } - - pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, NULL); - tfree(pExpr); - } - - return pNode; -} - -static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(SQueryStmtInfo* pQueryInfo, SQueryPlanNode* pNode, SQueryTableInfo* info) { - // group by column not by tag - size_t numOfGroupCols = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo); - - // check for aggregation - int32_t level = getExprFunctionLevel(pQueryInfo); - - for(int32_t i = level - 1; i >= 0; --i) { - SArray* p = pQueryInfo->exprList[i]; - size_t num = taosArrayGetSize(p); - - bool aggregateFunc = false; - for(int32_t j = 0; j < num; ++j) { - SExprInfo* pExpr = (SExprInfo*)taosArrayGetP(p, 0); - if (pExpr->pExpr->nodeType != TEXPR_FUNCTION_NODE) { - continue; - } - - aggregateFunc = qIsAggregateFunction(pExpr->pExpr->_function.functionName); - if (aggregateFunc) { - break; - } - } - - if (aggregateFunc) { - if (pQueryInfo->interval.interval > 0) { - pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->interval); - } else if (pQueryInfo->sessionWindow.gap > 0) { - pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->sessionWindow); - } else if (pQueryInfo->stateWindow.col.info.colId > 0) { - pNode = createQueryNode(QNODE_STATEWINDOW, "StateWindowAgg", &pNode, 1, p->pData, num, &pQueryInfo->stateWindow); - } else if (numOfGroupCols != 0 && !pQueryInfo->groupbyExpr.groupbyTag) { - pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, p->pData, num, &pQueryInfo->groupbyExpr); - } else { - pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, p->pData, num, NULL); - } - } else { - pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, num, NULL); - } - } - - if (pQueryInfo->havingFieldNum > 0) { -// int32_t numOfExpr = (int32_t)taosArrayGetSize(pQueryInfo->exprList1); -// pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, NULL); - } - - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo)); - pInfo->fillType = pQueryInfo->fillType; - pInfo->val = calloc(pNode->numOfExpr, sizeof(int64_t)); - memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfExpr); - - SArray* p = pQueryInfo->exprList[0]; // top expression in select clause - pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, p, taosArrayGetSize(p), pInfo); - } - - if (pQueryInfo->order != NULL) { - SArray* pList = pQueryInfo->exprList[0]; - pNode = createQueryNode(QNODE_SORT, "Sort", &pNode, 1, pList->pData, taosArrayGetSize(pList), pQueryInfo->order); - } - - if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) { - pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, &pQueryInfo->limit); - } - - return pNode; -} - -static SQueryPlanNode* doCreateQueryPlanForSingleTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs, - SArray* tableCols) { - char name[TSDB_TABLE_FNAME_LEN] = {0}; - tstrncpy(name, pTableMetaInfo->name.tname, TSDB_TABLE_FNAME_LEN); - - SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; - - // handle the only tag query - SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols); - if (pQueryInfo->info.onlyTagQuery) { - tfree(info.tableName); - return pNode; - } - - SQueryPlanNode* pNode1 = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info); - tfree(info.tableName); - return pNode1; -} - -static bool isAllAggExpr(SArray* pList) { - assert(pList != NULL); - - for (int32_t k = 0; k < taosArrayGetSize(pList); ++k) { - SExprInfo* p = taosArrayGetP(pList, k); - if (p->pExpr->nodeType != TEXPR_FUNCTION_NODE || !qIsAggregateFunction(p->pExpr->_function.functionName)) { - return false; - } - } - - return true; -} - -SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) { - SArray* upstream = NULL; - - if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause - upstream = taosArrayInit(4, POINTER_BYTES); - - size_t size = taosArrayGetSize(pQueryInfo->pUpstream); - for(int32_t i = 0; i < size; ++i) { - SQueryStmtInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i); - SArray* p = createQueryPlanImpl(pq); - taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p)); - } - } - - if (pQueryInfo->numOfTables > 1) { // it is a join query - // 1. separate the select clause according to table - taosArrayDestroy(upstream); - upstream = taosArrayInit(5, POINTER_BYTES); - - for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i]; - uint64_t uid = pTableMetaInfo->pTableMeta->uid; - - SArray* exprList = taosArrayInit(4, POINTER_BYTES); - if (copyExprInfoList(exprList, pQueryInfo->exprList[0], uid, true) != 0) { - terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; -// dropAllExprInfo(exprList); - exit(-1); - } - - // 2. create the query execution node - char name[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, name); - SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,}; - - // 3. get the required table column list - SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn)); - columnListCopy(tableColumnList, pQueryInfo->colList, uid); - - // 4. add the projection query node - SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList); - columnListDestroy(tableColumnList); -// dropAllExprInfo(exprList); - taosArrayPush(upstream, &pNode); - } - - // 3. add the join node here - SQueryTableInfo info = {0}; - int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList[0]); - SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables, - pQueryInfo->exprList[0]->pData, num, NULL); - - // 4. add the aggregation or projection execution node - pNode = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info); - upstream = taosArrayInit(5, POINTER_BYTES); - taosArrayPush(upstream, &pNode); - } else { // only one table, normal query process - STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; - SQueryPlanNode* pNode = doCreateQueryPlanForSingleTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList[0], pQueryInfo->colList); - upstream = taosArrayInit(5, POINTER_BYTES); - taosArrayPush(upstream, &pNode); - } - - return upstream; -} - -static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) { - tfree(pQueryNode->pExtInfo); - tfree(pQueryNode->pSchema); - tfree(pQueryNode->info.name); -// dropAllExprInfo(pQueryNode->pExpr); - - if (pQueryNode->pPrevNodes != NULL) { - int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes); - for(int32_t i = 0; i < size; ++i) { - SQueryPlanNode* p = taosArrayGetP(pQueryNode->pPrevNodes, i); - doDestroyQueryNode(p); - } - - taosArrayDestroy(pQueryNode->pPrevNodes); - } - - tfree(pQueryNode); -} - -static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) { - if (level > 0) { - sprintf(buf + totalLen, "%*c", level, ' '); - totalLen += level; - } - - int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name); - int32_t len = len1 + totalLen; - - switch(pQueryNode->info.type) { - case QNODE_TABLESCAN: { - SQueryTableInfo* pInfo = (SQueryTableInfo*)pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64, pInfo->tableName, pInfo->uid, - pInfo->window.skey, pInfo->window.ekey); - assert(len1 > 0); - len += len1; - - for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { - SColumn* pCol = taosArrayGetP(pQueryNode->pExpr, i); - len1 = sprintf(buf + len, " [%s #%d] ", pCol->name, pCol->info.colId); - - assert(len1 > 0); - len += len1; - } - - len1 = sprintf(buf + len, "\n"); - assert(len1 > 0); - - len += len1; - break; - } - - case QNODE_PROJECT: { - len1 = sprintf(buf + len, "cols:"); - assert(len1 > 0); - len += len1; - - len = printExprInfo(buf, pQueryNode, len); - len1 = sprintf(buf + len, ")"); - len += len1; - - // todo print filter info - len1 = sprintf(buf + len, " filters:(nil)\n"); - len += len1; - break; - } - - case QNODE_AGGREGATE: { - len = printExprInfo(buf, pQueryNode, len); - len1 = sprintf(buf + len, ")\n"); - len += len1; - - break; - } - - case QNODE_TIMEWINDOW: { - len = printExprInfo(buf, pQueryNode, len); - len1 = sprintf(buf + len, ") "); - len += len1; - - SInterval* pInterval = pQueryNode->pExtInfo; - - // todo dynamic return the time precision - len1 = sprintf(buf + len, "interval:%" PRId64 "(%s), sliding:%" PRId64 "(%s), offset:%" PRId64 "(%s)\n", - pInterval->interval, TSDB_TIME_PRECISION_MILLI_STR, pInterval->sliding, - TSDB_TIME_PRECISION_MILLI_STR, pInterval->offset, TSDB_TIME_PRECISION_MILLI_STR); - len += len1; - - break; - } - - case QNODE_STATEWINDOW: { - len = printExprInfo(buf, pQueryNode, len); - len1 = sprintf(buf + len, ") "); - len += len1; - - SColumn* pCol = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "col:%s #%d\n", pCol->name, pCol->info.colId); - len += len1; - break; - } - - case QNODE_SESSIONWINDOW: { - len = printExprInfo(buf, pQueryNode, len); - - len1 = sprintf(buf + len, ") "); - len += len1; - - struct SSessionWindow* ps = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "col:[%s #%d], gap:%" PRId64 " (ms) \n", ps->col.name, ps->col.info.colId, ps->gap); - len += len1; - break; - } - - case QNODE_GROUPBY: { - len = printExprInfo(buf, pQueryNode, len); - - SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, ") groupby_col: "); - len += len1; - - for (int32_t i = 0; i < taosArrayGetSize(pGroupbyExpr->columnInfo); ++i) { - SColumn* pCol = taosArrayGet(pGroupbyExpr->columnInfo, i); - len1 = sprintf(buf + len, "[%s #%d] ", pCol->name, pCol->info.colId); - len += len1; - } - - len += sprintf(buf + len, "\n"); - break; - } - - case QNODE_FILL: { - SFillEssInfo* pEssInfo = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "%d", pEssInfo->fillType); - len += len1; - - if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) { - len1 = sprintf(buf + len, ", val:"); - len += len1; - - // todo get the correct fill data type - for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { - len1 = sprintf(buf + len, "%" PRId64, pEssInfo->val[i]); - len += len1; - - if (i < pQueryNode->numOfExpr - 1) { - len1 = sprintf(buf + len, ", "); - len += len1; - } - } - } - - len1 = sprintf(buf + len, ")\n"); - len += len1; - break; - } - - case QNODE_LIMIT: { - SLimit* pVal = pQueryNode->pExtInfo; - len1 = sprintf(buf + len, "limit: %" PRId64 ", offset: %" PRId64 ")\n", pVal->limit, pVal->offset); - len += len1; - break; - } - - case QNODE_DISTINCT: - case QNODE_TAGSCAN: { - len1 = sprintf(buf + len, "cols: "); - len += len1; - - len = printExprInfo(buf, pQueryNode, len); - - len1 = sprintf(buf + len, ")\n"); - len += len1; - - break; - } - - case QNODE_SORT: { - len1 = sprintf(buf + len, "cols:"); - len += len1; - - SArray* pSort = pQueryNode->pExtInfo; - for (int32_t i = 0; i < taosArrayGetSize(pSort); ++i) { - SOrder* p = taosArrayGet(pSort, i); - len1 = sprintf(buf + len, " [%s #%d %s]", p->col.name, p->col.info.colId, p->order == TSDB_ORDER_ASC? "ASC":"DESC"); - - len += len1; - } - - len1 = sprintf(buf + len, ")\n"); - len += len1; - break; - } - - case QNODE_JOIN: { - // print join condition - len1 = sprintf(buf + len, ")\n"); - len += len1; - break; - } - } - - return len; -} - -int32_t printExprInfo(const char* buf, const SQueryPlanNode* pQueryNode, int32_t len) { - int32_t len1 = 0; - - for (int32_t i = 0; i < pQueryNode->numOfExpr; ++i) { - SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i); - - SSqlExpr* pExpr = &pExprInfo->base; - len1 = sprintf(buf + len, "%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); - assert(len1 > 0); - - len += len1; - if (i < pQueryNode->numOfExpr - 1) { - len1 = sprintf(buf + len, ", "); - len += len1; - } - } - - return len; -} - -int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) { - int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen); - - for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pPrevNodes); ++i) { - SQueryPlanNode* p1 = taosArrayGetP(pQueryNode->pPrevNodes, i); - int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len); - len = len1; - } - - return len; -} - -int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) { - assert(pQueryNode); - - *str = calloc(1, 4096); - - int32_t len = sprintf(*str, "===== logic plan =====\n"); - queryPlanToStringImpl(*str, pQueryNode, 0, len); - - return TSDB_CODE_SUCCESS; -} - -SQueryPlanNode* queryPlanFromString() { - return NULL; -} diff --git a/source/libs/planner/test/CMakeLists.txt b/source/libs/planner/test/CMakeLists.txt index a83d7a39d9..f00adfaeb2 100644 --- a/source/libs/planner/test/CMakeLists.txt +++ b/source/libs/planner/test/CMakeLists.txt @@ -8,7 +8,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) ADD_EXECUTABLE(plannerTest ${SOURCE_LIST}) TARGET_LINK_LIBRARIES( plannerTest - PUBLIC os util common planner parser catalog transport gtest function + PUBLIC os util common planner parser catalog transport gtest function query ) TARGET_INCLUDE_DIRECTORIES( diff --git a/source/libs/query/CMakeLists.txt b/source/libs/query/CMakeLists.txt new file mode 100644 index 0000000000..579a4b279c --- /dev/null +++ b/source/libs/query/CMakeLists.txt @@ -0,0 +1,12 @@ +aux_source_directory(src QUERY_SRC) +add_library(query ${QUERY_SRC}) +target_include_directories( + query + PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/query" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" +) + +target_link_libraries( + query + PRIVATE os util common transport +) diff --git a/source/libs/query/inc/queryInt.h b/source/libs/query/inc/queryInt.h new file mode 100644 index 0000000000..f3204b3785 --- /dev/null +++ b/source/libs/query/inc/queryInt.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#ifndef _TD_QUERY_INT_H_ +#define _TD_QUERY_INT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "tlog.h" + +extern int32_t qDebugFlag; + +#define qFatal(...) do { if (qDebugFlag & DEBUG_FATAL) { taosPrintLog("QRY FATAL ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qError(...) do { if (qDebugFlag & DEBUG_ERROR) { taosPrintLog("QRY ERROR ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qWarn(...) do { if (qDebugFlag & DEBUG_WARN) { taosPrintLog("QRY WARN ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qInfo(...) do { if (qDebugFlag & DEBUG_INFO) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qDebug(...) do { if (qDebugFlag & DEBUG_DEBUG) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qTrace(...) do { if (qDebugFlag & DEBUG_TRACE) { taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) +#define qDebugL(...) do { if (qDebugFlag & DEBUG_DEBUG) { taosPrintLongString("QRY ", qDebugFlag, __VA_ARGS__); }} while(0) + +#ifdef __cplusplus +} +#endif + +#endif /*_TD_QUERY_INT_H_*/ diff --git a/source/libs/query/src/querymsg.c b/source/libs/query/src/querymsg.c new file mode 100644 index 0000000000..9d99b568a5 --- /dev/null +++ b/source/libs/query/src/querymsg.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include "taosmsg.h" +#include "queryInt.h" +#include "query.h" + +int32_t (*queryBuildMsg[TSDB_MSG_TYPE_MAX])(void* input, char **msg, int32_t msgSize, int32_t *msgLen) = {0}; + +int32_t (*queryProcessMsgRsp[TSDB_MSG_TYPE_MAX])(void* output, char *msg, int32_t msgSize) = {0}; + +int32_t queryBuildTableMetaReqMsg(void* input, char **msg, int32_t msgSize, int32_t *msgLen) { + if (NULL == input || NULL == msg || NULL == msgLen) { + return TSDB_CODE_TSC_INVALID_INPUT; + } + + SBuildTableMetaInput* bInput = (SBuildTableMetaInput *)input; + + int32_t estimateSize = sizeof(STableInfoMsg); + if (NULL == *msg || msgSize < estimateSize) { + tfree(*msg); + *msg = calloc(1, estimateSize); + if (NULL == *msg) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + } + + STableInfoMsg *bMsg = (STableInfoMsg *)*msg; + + bMsg->msgHead.vgId = bInput->vgId; + + strncpy(bMsg->tableFname, bInput->tableFullName, sizeof(bMsg->tableFname)); + bMsg->tableFname[sizeof(bMsg->tableFname) - 1] = 0; + + *msgLen = (int32_t)sizeof(*bMsg); + + return TSDB_CODE_SUCCESS; +} + +int32_t queryBuildUseDbMsg(void* input, char **msg, int32_t msgSize, int32_t *msgLen) { + if (NULL == input || NULL == msg || NULL == msgLen) { + return TSDB_CODE_TSC_INVALID_INPUT; + } + + SBuildUseDBInput* bInput = (SBuildUseDBInput *)input; + + int32_t estimateSize = sizeof(SUseDbMsg); + if (NULL == *msg || msgSize < estimateSize) { + tfree(*msg); + *msg = calloc(1, estimateSize); + if (NULL == *msg) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + } + + SUseDbMsg *bMsg = (SUseDbMsg *)*msg; + + strncpy(bMsg->db, bInput->db, sizeof(bMsg->db)); + bMsg->db[sizeof(bMsg->db) - 1] = 0; + + bMsg->vgVersion = bInput->vgVersion; + + *msgLen = (int32_t)sizeof(*bMsg); + + return TSDB_CODE_SUCCESS; +} + + +int32_t queryProcessUseDBRsp(void* output, char *msg, int32_t msgSize) { + if (NULL == output || NULL == msg || msgSize <= 0) { + return TSDB_CODE_TSC_INVALID_INPUT; + } + + SUseDbRsp *pRsp = (SUseDbRsp *)msg; + SUseDbOutput *pOut = (SUseDbOutput *)output; + int32_t code = 0; + + if (msgSize <= sizeof(*pRsp)) { + qError("invalid use db rsp msg size, msgSize:%d", msgSize); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + + pRsp->vgVersion = htonl(pRsp->vgVersion); + pRsp->vgNum = htonl(pRsp->vgNum); + + if (pRsp->vgNum < 0) { + qError("invalid db[%s] vgroup number[%d]", pRsp->db, pRsp->vgNum); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + int32_t expectSize = pRsp->vgNum * sizeof(pRsp->vgroupInfo[0]) + sizeof(*pRsp); + if (msgSize != expectSize) { + qError("use db rsp size mis-match, msgSize:%d, expected:%d, vgnumber:%d", msgSize, expectSize, pRsp->vgNum); + return TSDB_CODE_TSC_VALUE_OUT_OF_RANGE; + } + + pOut->dbVgroup.vgVersion = pRsp->vgVersion; + pOut->dbVgroup.hashMethod = pRsp->hashMethod; + pOut->dbVgroup.vgInfo = taosHashInit(pRsp->vgNum, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); + if (NULL == pOut->dbVgroup.vgInfo) { + qError("hash init[%d] failed", pRsp->vgNum); + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pRsp->vgNum; ++i) { + pRsp->vgroupInfo[i].vgId = htonl(pRsp->vgroupInfo[i].vgId); + pRsp->vgroupInfo[i].hashBegin = htonl(pRsp->vgroupInfo[i].hashBegin); + pRsp->vgroupInfo[i].hashEnd = htonl(pRsp->vgroupInfo[i].hashEnd); + + for (int32_t n = 0; n < pRsp->vgroupInfo[i].numOfEps; ++n) { + pRsp->vgroupInfo[i].epAddr[n].port = htonl(pRsp->vgroupInfo[i].epAddr[n].port); + } + + if (0 != taosHashPut(pOut->dbVgroup.vgInfo, &pRsp->vgroupInfo[i].vgId, sizeof(pRsp->vgroupInfo[i].vgId), &pRsp->vgroupInfo[i], sizeof(pRsp->vgroupInfo[i]))) { + qError("hash push failed"); + goto _return; + } + } + + memcpy(pOut->db, pRsp->db, sizeof(pOut->db)); + + return code; + +_return: + if (pOut) { + tfree(pOut->dbVgroup.vgInfo); + } + + return code; +} + +static int32_t queryConvertTableMetaMsg(STableMetaMsg* pMetaMsg) { + pMetaMsg->numOfTags = htonl(pMetaMsg->numOfTags); + pMetaMsg->numOfColumns = htonl(pMetaMsg->numOfColumns); + pMetaMsg->sversion = htonl(pMetaMsg->sversion); + pMetaMsg->tversion = htonl(pMetaMsg->tversion); + pMetaMsg->tuid = htobe64(pMetaMsg->tuid); + pMetaMsg->suid = htobe64(pMetaMsg->suid); + pMetaMsg->vgId = htonl(pMetaMsg->vgId); + + if (pMetaMsg->numOfTags < 0 || pMetaMsg->numOfTags > TSDB_MAX_TAGS) { + qError("invalid numOfTags[%d] in table meta rsp msg", pMetaMsg->numOfTags); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if (pMetaMsg->numOfColumns > TSDB_MAX_COLUMNS || pMetaMsg->numOfColumns <= 0) { + qError("invalid numOfColumns[%d] in table meta rsp msg", pMetaMsg->numOfColumns); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if (pMetaMsg->tableType != TSDB_SUPER_TABLE && pMetaMsg->tableType != TSDB_CHILD_TABLE && pMetaMsg->tableType != TSDB_NORMAL_TABLE) { + qError("invalid tableType[%d] in table meta rsp msg", pMetaMsg->tableType); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if (pMetaMsg->sversion < 0) { + qError("invalid sversion[%d] in table meta rsp msg", pMetaMsg->sversion); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if (pMetaMsg->tversion < 0) { + qError("invalid tversion[%d] in table meta rsp msg", pMetaMsg->tversion); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + SSchema* pSchema = pMetaMsg->pSchema; + + int32_t numOfTotalCols = pMetaMsg->numOfColumns + pMetaMsg->numOfTags; + for (int i = 0; i < numOfTotalCols; ++i) { + pSchema->bytes = htonl(pSchema->bytes); + pSchema->colId = htonl(pSchema->colId); + + pSchema++; + } + + if (pMetaMsg->pSchema[0].colId != PRIMARYKEY_TIMESTAMP_COL_ID) { + qError("invalid colId[%d] for the first column in table meta rsp msg", pMetaMsg->pSchema[0].colId); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t queryCreateTableMetaFromMsg(STableMetaMsg* msg, bool isSuperTable, STableMeta **pMeta) { + int32_t total = msg->numOfColumns + msg->numOfTags; + int32_t metaSize = sizeof(STableMeta) + sizeof(SSchema) * total; + + STableMeta* pTableMeta = calloc(1, metaSize); + if (NULL == pTableMeta) { + qError("calloc size[%d] failed", metaSize); + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + pTableMeta->tableType = isSuperTable ? TSDB_SUPER_TABLE : msg->tableType; + pTableMeta->uid = msg->suid; + pTableMeta->suid = msg->suid; + pTableMeta->sversion = msg->sversion; + pTableMeta->tversion = msg->tversion; + + pTableMeta->tableInfo.numOfTags = msg->numOfTags; + pTableMeta->tableInfo.precision = msg->precision; + pTableMeta->tableInfo.numOfColumns = msg->numOfColumns; + + for(int32_t i = 0; i < msg->numOfColumns; ++i) { + pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes; + } + + memcpy(pTableMeta->schema, msg->pSchema, sizeof(SSchema) * total); + + *pMeta = pTableMeta; + + return TSDB_CODE_SUCCESS; +} + + +int32_t queryProcessTableMetaRsp(void* output, char *msg, int32_t msgSize) { + STableMetaMsg *pMetaMsg = (STableMetaMsg *)msg; + int32_t code = queryConvertTableMetaMsg(pMetaMsg); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + STableMetaOutput *pOut = (STableMetaOutput *)output; + + if (!tIsValidSchema(pMetaMsg->pSchema, pMetaMsg->numOfColumns, pMetaMsg->numOfTags)) { + qError("validate table meta schema in rsp msg failed"); + return TSDB_CODE_TSC_INVALID_VALUE; + } + + if (pMetaMsg->tableType == TSDB_CHILD_TABLE) { + pOut->metaNum = 2; + + memcpy(pOut->ctbFname, pMetaMsg->tbFname, sizeof(pOut->ctbFname)); + memcpy(pOut->tbFname, pMetaMsg->stbFname, sizeof(pOut->tbFname)); + + pOut->ctbMeta.vgId = pMetaMsg->vgId; + pOut->ctbMeta.tableType = pMetaMsg->tableType; + pOut->ctbMeta.uid = pMetaMsg->tuid; + pOut->ctbMeta.suid = pMetaMsg->suid; + + code = queryCreateTableMetaFromMsg(pMetaMsg, true, &pOut->tbMeta); + } else { + pOut->metaNum = 1; + + memcpy(pOut->tbFname, pMetaMsg->tbFname, sizeof(pOut->tbFname)); + + code = queryCreateTableMetaFromMsg(pMetaMsg, false, &pOut->tbMeta); + } + + return code; +} + + +void msgInit() { + queryBuildMsg[TSDB_MSG_TYPE_TABLE_META] = queryBuildTableMetaReqMsg; + queryBuildMsg[TSDB_MSG_TYPE_USE_DB] = queryBuildUseDbMsg; + + queryProcessMsgRsp[TSDB_MSG_TYPE_TABLE_META] = queryProcessTableMetaRsp; + queryProcessMsgRsp[TSDB_MSG_TYPE_USE_DB] = queryProcessUseDBRsp; + +/* + tscBuildMsg[TSDB_SQL_SELECT] = tscBuildQueryMsg; + tscBuildMsg[TSDB_SQL_INSERT] = tscBuildSubmitMsg; + tscBuildMsg[TSDB_SQL_FETCH] = tscBuildFetchMsg; + + tscBuildMsg[TSDB_SQL_CREATE_DB] = tscBuildCreateDbMsg; + tscBuildMsg[TSDB_SQL_CREATE_USER] = tscBuildUserMsg; + tscBuildMsg[TSDB_SQL_CREATE_FUNCTION] = tscBuildCreateFuncMsg; + + tscBuildMsg[TSDB_SQL_CREATE_ACCT] = tscBuildAcctMsg; + tscBuildMsg[TSDB_SQL_ALTER_ACCT] = tscBuildAcctMsg; + + tscBuildMsg[TSDB_SQL_CREATE_TABLE] = tscBuildCreateTableMsg; + tscBuildMsg[TSDB_SQL_DROP_USER] = tscBuildDropUserAcctMsg; + tscBuildMsg[TSDB_SQL_DROP_ACCT] = tscBuildDropUserAcctMsg; + tscBuildMsg[TSDB_SQL_DROP_DB] = tscBuildDropDbMsg; + tscBuildMsg[TSDB_SQL_DROP_FUNCTION] = tscBuildDropFuncMsg; + tscBuildMsg[TSDB_SQL_SYNC_DB_REPLICA] = tscBuildSyncDbReplicaMsg; + tscBuildMsg[TSDB_SQL_DROP_TABLE] = tscBuildDropTableMsg; + tscBuildMsg[TSDB_SQL_ALTER_USER] = tscBuildUserMsg; + tscBuildMsg[TSDB_SQL_CREATE_DNODE] = tscBuildCreateDnodeMsg; + tscBuildMsg[TSDB_SQL_DROP_DNODE] = tscBuildDropDnodeMsg; + tscBuildMsg[TSDB_SQL_CFG_DNODE] = tscBuildCfgDnodeMsg; + tscBuildMsg[TSDB_SQL_ALTER_TABLE] = tscBuildAlterTableMsg; + tscBuildMsg[TSDB_SQL_UPDATE_TAGS_VAL] = tscBuildUpdateTagMsg; + tscBuildMsg[TSDB_SQL_ALTER_DB] = tscAlterDbMsg; + tscBuildMsg[TSDB_SQL_COMPACT_VNODE] = tscBuildCompactMsg; + + tscBuildMsg[TSDB_SQL_CONNECT] = tscBuildConnectMsg; + tscBuildMsg[TSDB_SQL_USE_DB] = tscBuildUseDbMsg; + tscBuildMsg[TSDB_SQL_STABLEVGROUP] = tscBuildSTableVgroupMsg; + tscBuildMsg[TSDB_SQL_RETRIEVE_FUNC] = tscBuildRetrieveFuncMsg; + + tscBuildMsg[TSDB_SQL_HB] = tscBuildHeartBeatMsg; + tscBuildMsg[TSDB_SQL_SHOW] = tscBuildShowMsg; + tscBuildMsg[TSDB_SQL_RETRIEVE] = tscBuildRetrieveFromMgmtMsg; + tscBuildMsg[TSDB_SQL_KILL_QUERY] = tscBuildKillMsg; + tscBuildMsg[TSDB_SQL_KILL_STREAM] = tscBuildKillMsg; + tscBuildMsg[TSDB_SQL_KILL_CONNECTION] = tscBuildKillMsg; + + tscProcessMsgRsp[TSDB_SQL_SELECT] = tscProcessQueryRsp; + tscProcessMsgRsp[TSDB_SQL_FETCH] = tscProcessRetrieveRspFromNode; + + tscProcessMsgRsp[TSDB_SQL_DROP_DB] = tscProcessDropDbRsp; + tscProcessMsgRsp[TSDB_SQL_DROP_TABLE] = tscProcessDropTableRsp; + tscProcessMsgRsp[TSDB_SQL_CONNECT] = tscProcessConnectRsp; + tscProcessMsgRsp[TSDB_SQL_USE_DB] = tscProcessUseDbRsp; + tscProcessMsgRsp[TSDB_SQL_META] = tscProcessTableMetaRsp; + tscProcessMsgRsp[TSDB_SQL_STABLEVGROUP] = tscProcessSTableVgroupRsp; + tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiTableMetaRsp; + tscProcessMsgRsp[TSDB_SQL_RETRIEVE_FUNC] = tscProcessRetrieveFuncRsp; + + tscProcessMsgRsp[TSDB_SQL_SHOW] = tscProcessShowRsp; + tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromNode; // rsp handled by same function. + tscProcessMsgRsp[TSDB_SQL_DESCRIBE_TABLE] = tscProcessDescribeTableRsp; + + tscProcessMsgRsp[TSDB_SQL_CURRENT_DB] = tscProcessLocalRetrieveRsp; + tscProcessMsgRsp[TSDB_SQL_CURRENT_USER] = tscProcessLocalRetrieveRsp; + tscProcessMsgRsp[TSDB_SQL_SERV_VERSION] = tscProcessLocalRetrieveRsp; + tscProcessMsgRsp[TSDB_SQL_CLI_VERSION] = tscProcessLocalRetrieveRsp; + tscProcessMsgRsp[TSDB_SQL_SERV_STATUS] = tscProcessLocalRetrieveRsp; + + tscProcessMsgRsp[TSDB_SQL_RETRIEVE_EMPTY_RESULT] = tscProcessEmptyResultRsp; + + tscProcessMsgRsp[TSDB_SQL_RETRIEVE_GLOBALMERGE] = tscProcessRetrieveGlobalMergeRsp; + + tscProcessMsgRsp[TSDB_SQL_ALTER_TABLE] = tscProcessAlterTableMsgRsp; + tscProcessMsgRsp[TSDB_SQL_ALTER_DB] = tscProcessAlterDbMsgRsp; + tscProcessMsgRsp[TSDB_SQL_COMPACT_VNODE] = tscProcessCompactRsp; + + tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp; + tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_STABLE] = tscProcessShowCreateRsp; + tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp; +*/ +} + + + + + diff --git a/source/libs/scheduler/CMakeLists.txt b/source/libs/scheduler/CMakeLists.txt index 770a6b02c2..fd00085381 100644 --- a/source/libs/scheduler/CMakeLists.txt +++ b/source/libs/scheduler/CMakeLists.txt @@ -9,5 +9,5 @@ target_include_directories( target_link_libraries( scheduler - PRIVATE os util planner + PRIVATE os util planner common ) \ No newline at end of file diff --git a/source/libs/transport/src/rpcMain.c b/source/libs/transport/src/rpcMain.c index c54415860a..2f710f3efd 100644 --- a/source/libs/transport/src/rpcMain.c +++ b/source/libs/transport/src/rpcMain.c @@ -411,7 +411,7 @@ void rpcSendRequest(void *shandle, const SEpSet *pEpSet, SRpcMsg *pMsg, int64_t // for TDengine, all the query, show commands shall have TCP connection char type = pMsg->msgType; if (type == TSDB_MSG_TYPE_QUERY || type == TSDB_MSG_TYPE_SHOW_RETRIEVE - || type == TSDB_MSG_TYPE_FETCH || type == TSDB_MSG_TYPE_STB_VGROUP + || type == TSDB_MSG_TYPE_FETCH || type == TSDB_MSG_TYPE_VGROUP_LIST || type == TSDB_MSG_TYPE_TABLES_META || type == TSDB_MSG_TYPE_TABLE_META || type == TSDB_MSG_TYPE_SHOW || type == TSDB_MSG_TYPE_STATUS || type == TSDB_MSG_TYPE_ALTER_TABLE) pContext->connType = RPC_CONN_TCPC; diff --git a/source/libs/wal/inc/walInt.h b/source/libs/wal/inc/walInt.h index e546a87326..819afcc411 100644 --- a/source/libs/wal/inc/walInt.h +++ b/source/libs/wal/inc/walInt.h @@ -33,12 +33,10 @@ typedef struct WalFileInfo { int64_t fileSize; } WalFileInfo; -#pragma pack(push,1) typedef struct WalIdxEntry { int64_t ver; int64_t offset; } WalIdxEntry; -#pragma pack(pop) static inline int32_t compareWalFileInfo(const void* pLeft, const void* pRight) { WalFileInfo* pInfoLeft = (WalFileInfo*)pLeft; @@ -107,10 +105,26 @@ static inline uint32_t walCalcBodyCksum(const void* body, uint32_t len) { return taosCalcChecksum(0, (uint8_t*)body, len); } -int walReadMeta(SWal* pWal); -int walWriteMeta(SWal* pWal); +static inline int64_t walGetVerIdxOffset(SWal* pWal, int64_t ver) { + return (ver - walGetCurFileFirstVer(pWal)) * sizeof(WalIdxEntry); +} + +static inline void walResetVer(SWalVer* pVer) { + pVer->firstVer = -1; + pVer->verInSnapshotting = -1; + pVer->snapshotVer = -1; + pVer->commitVer = -1; + pVer->lastVer = -1; +} + +int walLoadMeta(SWal* pWal); +int walSaveMeta(SWal* pWal); int walRollFileInfo(SWal* pWal); +int walCheckAndRepairMeta(SWal* pWal); + +int walCheckAndRepairIdx(SWal* pWal); + char* walMetaSerialize(SWal* pWal); int walMetaDeserialize(SWal* pWal, const char* bytes); //meta section end diff --git a/source/libs/wal/src/walMeta.c b/source/libs/wal/src/walMeta.c index 49f4fde3a0..e86a2b6221 100644 --- a/source/libs/wal/src/walMeta.c +++ b/source/libs/wal/src/walMeta.c @@ -14,41 +14,79 @@ */ #define _DEFAULT_SOURCE +#include "cJSON.h" #include "os.h" #include "taoserror.h" -#include "tref.h" #include "tfile.h" -#include "cJSON.h" +#include "tref.h" #include "walInt.h" #include #include -int64_t walGetFirstVer(SWal *pWal) { - return pWal->vers.firstVer; +int64_t inline walGetFirstVer(SWal* pWal) { return pWal->vers.firstVer; } + +int64_t inline walGetSnaphostVer(SWal* pWal) { return pWal->vers.snapshotVer; } + +int64_t inline walGetLastVer(SWal* pWal) { return pWal->vers.lastVer; } + +static inline int walBuildMetaName(SWal* pWal, int metaVer, char* buf) { + return sprintf(buf, "%s/meta-ver%d", pWal->path, metaVer); } -int64_t walGetSnaphostVer(SWal *pWal) { - return pWal->vers.snapshotVer; +int walCheckAndRepairMeta(SWal* pWal) { + // load log files, get first/snapshot/last version info + const char* logPattern = "^[0-9]+.log$"; + const char* idxPattern = "^[0-9]+.idx$"; + regex_t logRegPattern; + regex_t idxRegPattern; + SArray* pLogArray = taosArrayInit(8, sizeof(int64_t)); + + regcomp(&logRegPattern, logPattern, REG_EXTENDED); + regcomp(&idxRegPattern, idxPattern, REG_EXTENDED); + + DIR* dir = opendir(pWal->path); + if (dir == NULL) { + wError("vgId:%d, path:%s, failed to open since %s", pWal->cfg.vgId, pWal->path, strerror(errno)); + return -1; + } + + struct dirent* ent; + while ((ent = readdir(dir)) != NULL) { + char* name = basename(ent->d_name); + int code = regexec(&logRegPattern, name, 0, NULL, 0); + if (code == 0) { + int64_t firstVer; + sscanf(name, "%" PRId64 ".log", &firstVer); + taosArrayPush(pLogArray, &firstVer); + } + } + + // load meta + // if not match, or meta missing + // rebuild meta + return 0; } -int64_t walGetLastVer(SWal *pWal) { - return pWal->vers.lastVer; +int walCheckAndRepairIdx(SWal* pWal) { + // iterate all idx files + // check first and last entry of each idx file valid + return 0; } int walRollFileInfo(SWal* pWal) { int64_t ts = taosGetTimestampSec(); SArray* pArray = pWal->fileInfoSet; - if(taosArrayGetSize(pArray) != 0) { - WalFileInfo *pInfo = taosArrayGetLast(pArray); + if (taosArrayGetSize(pArray) != 0) { + WalFileInfo* pInfo = taosArrayGetLast(pArray); pInfo->lastVer = pWal->vers.lastVer; pInfo->closeTs = ts; } - //TODO: change to emplace back - WalFileInfo *pNewInfo = malloc(sizeof(WalFileInfo)); - if(pNewInfo == NULL) { + // TODO: change to emplace back + WalFileInfo* pNewInfo = malloc(sizeof(WalFileInfo)); + if (pNewInfo == NULL) { return -1; } pNewInfo->firstVer = pWal->vers.lastVer + 1; @@ -64,13 +102,13 @@ int walRollFileInfo(SWal* pWal) { char* walMetaSerialize(SWal* pWal) { char buf[30]; ASSERT(pWal->fileInfoSet); - int sz = pWal->fileInfoSet->size; + int sz = pWal->fileInfoSet->size; cJSON* pRoot = cJSON_CreateObject(); cJSON* pMeta = cJSON_CreateObject(); cJSON* pFiles = cJSON_CreateArray(); cJSON* pField; - if(pRoot == NULL || pMeta == NULL || pFiles == NULL) { - //TODO + if (pRoot == NULL || pMeta == NULL || pFiles == NULL) { + // TODO return NULL; } cJSON_AddItemToObject(pRoot, "meta", pMeta); @@ -85,15 +123,15 @@ char* walMetaSerialize(SWal* pWal) { cJSON_AddItemToObject(pRoot, "files", pFiles); WalFileInfo* pData = pWal->fileInfoSet->pData; - for(int i = 0; i < sz; i++) { + for (int i = 0; i < sz; i++) { WalFileInfo* pInfo = &pData[i]; cJSON_AddItemToArray(pFiles, pField = cJSON_CreateObject()); - if(pField == NULL) { + if (pField == NULL) { cJSON_Delete(pRoot); return NULL; } - //cjson only support int32_t or double - //string are used to prohibit the loss of precision + // cjson only support int32_t or double + // string are used to prohibit the loss of precision sprintf(buf, "%" PRId64, pInfo->firstVer); cJSON_AddStringToObject(pField, "firstVer", buf); sprintf(buf, "%" PRId64, pInfo->lastVer); @@ -126,12 +164,12 @@ int walMetaDeserialize(SWal* pWal, const char* bytes) { pFiles = cJSON_GetObjectItem(pRoot, "files"); int sz = cJSON_GetArraySize(pFiles); - //deserialize + // deserialize SArray* pArray = pWal->fileInfoSet; taosArrayEnsureCap(pArray, sz); - WalFileInfo *pData = pArray->pData; - for(int i = 0; i < sz; i++) { - cJSON* pInfoJson = cJSON_GetArrayItem(pFiles, i); + WalFileInfo* pData = pArray->pData; + for (int i = 0; i < sz; i++) { + cJSON* pInfoJson = cJSON_GetArrayItem(pFiles, i); WalFileInfo* pInfo = &pData[i]; pField = cJSON_GetObjectItem(pInfoJson, "firstVer"); pInfo->firstVer = atoll(cJSON_GetStringValue(pField)); @@ -150,29 +188,25 @@ int walMetaDeserialize(SWal* pWal, const char* bytes) { return 0; } -static inline int walBuildMetaName(SWal* pWal, int metaVer, char* buf) { - return sprintf(buf, "%s/meta-ver%d", pWal->path, metaVer); -} - static int walFindCurMetaVer(SWal* pWal) { - const char * pattern = "^meta-ver[0-9]+$"; - regex_t walMetaRegexPattern; + const char* pattern = "^meta-ver[0-9]+$"; + regex_t walMetaRegexPattern; regcomp(&walMetaRegexPattern, pattern, REG_EXTENDED); - DIR *dir = opendir(pWal->path); - if(dir == NULL) { + DIR* dir = opendir(pWal->path); + if (dir == NULL) { wError("vgId:%d, path:%s, failed to open since %s", pWal->cfg.vgId, pWal->path, strerror(errno)); return -1; } struct dirent* ent; - //find existing meta-ver[x].json + // find existing meta-ver[x].json int metaVer = -1; - while((ent = readdir(dir)) != NULL) { - char *name = basename(ent->d_name); - int code = regexec(&walMetaRegexPattern, name, 0, NULL, 0); - if(code == 0) { + while ((ent = readdir(dir)) != NULL) { + char* name = basename(ent->d_name); + int code = regexec(&walMetaRegexPattern, name, 0, NULL, 0); + if (code == 0) { sscanf(name, "meta-ver%d", &metaVer); break; } @@ -182,24 +216,24 @@ static int walFindCurMetaVer(SWal* pWal) { return metaVer; } -int walWriteMeta(SWal* pWal) { - int metaVer = walFindCurMetaVer(pWal); +int walSaveMeta(SWal* pWal) { + int metaVer = walFindCurMetaVer(pWal); char fnameStr[WAL_FILE_LEN]; - walBuildMetaName(pWal, metaVer+1, fnameStr); + walBuildMetaName(pWal, metaVer + 1, fnameStr); int metaTfd = tfOpenCreateWrite(fnameStr); - if(metaTfd < 0) { + if (metaTfd < 0) { return -1; } char* serialized = walMetaSerialize(pWal); - int len = strlen(serialized); - if(len != tfWrite(metaTfd, serialized, len)) { - //TODO:clean file + int len = strlen(serialized); + if (len != tfWrite(metaTfd, serialized, len)) { + // TODO:clean file return -1; } - + tfClose(metaTfd); - //delete old file - if(metaVer > -1) { + // delete old file + if (metaVer > -1) { walBuildMetaName(pWal, metaVer, fnameStr); remove(fnameStr); } @@ -207,32 +241,32 @@ int walWriteMeta(SWal* pWal) { return 0; } -int walReadMeta(SWal* pWal) { +int walLoadMeta(SWal* pWal) { ASSERT(pWal->fileInfoSet->size == 0); - //find existing meta file + // find existing meta file int metaVer = walFindCurMetaVer(pWal); - if(metaVer == -1) { + if (metaVer == -1) { return 0; } char fnameStr[WAL_FILE_LEN]; walBuildMetaName(pWal, metaVer, fnameStr); - //read metafile + // read metafile struct stat statbuf; stat(fnameStr, &statbuf); - int size = statbuf.st_size; + int size = statbuf.st_size; char* buf = malloc(size + 5); - if(buf == NULL) { + if (buf == NULL) { return -1; } - memset(buf, 0, size+5); + memset(buf, 0, size + 5); int tfd = tfOpenRead(fnameStr); - if(tfRead(tfd, buf, size) != size) { + if (tfRead(tfd, buf, size) != size) { free(buf); return -1; } - //load into fileInfoSet + // load into fileInfoSet int code = walMetaDeserialize(pWal, buf); - if(code != 0) { + if (code != 0) { free(buf); return -1; } diff --git a/source/libs/wal/src/walMgmt.c b/source/libs/wal/src/walMgmt.c index 629451a722..5b6a8c6b29 100644 --- a/source/libs/wal/src/walMgmt.c +++ b/source/libs/wal/src/walMgmt.c @@ -14,42 +14,34 @@ */ #define _DEFAULT_SOURCE +#include "compare.h" #include "os.h" #include "taoserror.h" -#include "tref.h" #include "tfile.h" -#include "compare.h" +#include "tref.h" #include "walInt.h" -//internal -int32_t walGetNextFile(SWal *pWal, int64_t *nextFileId); -int32_t walGetOldFile(SWal *pWal, int64_t curFileId, int32_t minDiff, int64_t *oldFileId); -int32_t walGetNewFile(SWal *pWal, int64_t *newFileId); - typedef struct { - int32_t refSetId; - uint32_t seq; int8_t stop; int8_t inited; + uint32_t seq; + int32_t refSetId; pthread_t thread; } SWalMgmt; static SWalMgmt tsWal = {0, .seq = 1}; static int32_t walCreateThread(); static void walStopThread(); -static int32_t walInitObj(SWal *pWal); static void walFreeObj(void *pWal); -int64_t walGetSeq() { - return (int64_t)atomic_load_32(&tsWal.seq); -} +int64_t walGetSeq() { return (int64_t)atomic_load_32(&tsWal.seq); } int32_t walInit() { int8_t old = atomic_val_compare_exchange_8(&tsWal.inited, 0, 1); - if(old == 1) return 0; + if (old == 1) return 0; int code = tfInit(); - if(code != 0) { + if (code != 0) { wError("failed to init tfile since %s", tstrerror(code)); atomic_store_8(&tsWal.inited, 0); return code; @@ -68,8 +60,8 @@ int32_t walInit() { } void walCleanUp() { - int old = atomic_val_compare_exchange_8(&tsWal.inited, 1, 0); - if(old == 0) { + int8_t old = atomic_val_compare_exchange_8(&tsWal.inited, 1, 0); + if (old == 0) { return; } walStopThread(); @@ -83,50 +75,65 @@ SWal *walOpen(const char *path, SWalCfg *pCfg) { terrno = TAOS_SYSTEM_ERROR(errno); return NULL; } - memset(pWal, 0, sizeof(SWal)); - pWal->writeLogTfd = -1; - pWal->writeIdxTfd = -1; - pWal->writeCur = -1; - //set config + // set config memcpy(&pWal->cfg, pCfg, sizeof(SWalCfg)); - - //init version info - pWal->vers.firstVer = -1; - pWal->vers.commitVer = -1; - pWal->vers.snapshotVer = -1; - pWal->vers.lastVer = -1; - - pWal->vers.verInSnapshotting = -1; - - pWal->totSize = 0; - - //init status - pWal->lastRollSeq = -1; - - //init write buffer - memset(&pWal->writeHead, 0, sizeof(SWalHead)); - pWal->writeHead.head.sver = 0; - - tstrncpy(pWal->path, path, sizeof(pWal->path)); - pthread_mutex_init(&pWal->mutex, NULL); - pWal->fsyncSeq = pCfg->fsyncPeriod / 1000; if (pWal->fsyncSeq <= 0) pWal->fsyncSeq = 1; - if (walInitObj(pWal) != 0) { - walFreeObj(pWal); + tstrncpy(pWal->path, path, sizeof(pWal->path)); + if (taosMkDir(pWal->path) != 0) { + wError("vgId:%d, path:%s, failed to create directory since %s", pWal->cfg.vgId, pWal->path, strerror(errno)); return NULL; } - pWal->refId = taosAddRef(tsWal.refSetId, pWal); - if (pWal->refId < 0) { - walFreeObj(pWal); + // open meta + walResetVer(&pWal->vers); + pWal->writeLogTfd = -1; + pWal->writeIdxTfd = -1; + pWal->writeCur = -1; + pWal->fileInfoSet = taosArrayInit(8, sizeof(WalFileInfo)); + if (pWal->fileInfoSet == NULL) { + wError("vgId:%d, path:%s, failed to init taosArray %s", pWal->cfg.vgId, pWal->path, strerror(errno)); + free(pWal); return NULL; } - walReadMeta(pWal); - wDebug("vgId:%d, wal:%p is opened, level:%d fsyncPeriod:%d", pWal->cfg.vgId, pWal, pWal->cfg.level, pWal->cfg.fsyncPeriod); + // init status + pWal->totSize = 0; + pWal->lastRollSeq = -1; + + // init write buffer + memset(&pWal->writeHead, 0, sizeof(SWalHead)); + pWal->writeHead.head.headVer = WAL_HEAD_VER; + + if (pthread_mutex_init(&pWal->mutex, NULL) < 0) { + taosArrayDestroy(pWal->fileInfoSet); + free(pWal); + return NULL; + } + + pWal->refId = taosAddRef(tsWal.refSetId, pWal); + if (pWal->refId < 0) { + pthread_mutex_destroy(&pWal->mutex); + taosArrayDestroy(pWal->fileInfoSet); + free(pWal); + return NULL; + } + + if (walLoadMeta(pWal) < 0 && walCheckAndRepairMeta(pWal) < 0) { + taosRemoveRef(tsWal.refSetId, pWal->refId); + pthread_mutex_destroy(&pWal->mutex); + taosArrayDestroy(pWal->fileInfoSet); + free(pWal); + return NULL; + } + + if (walCheckAndRepairIdx(pWal) < 0) { + } + + wDebug("vgId:%d, wal:%p is opened, level:%d fsyncPeriod:%d", pWal->cfg.vgId, pWal, pWal->cfg.level, + pWal->cfg.fsyncPeriod); return pWal; } @@ -152,43 +159,23 @@ int32_t walAlter(SWal *pWal, SWalCfg *pCfg) { } void walClose(SWal *pWal) { - if (pWal == NULL) return; - pthread_mutex_lock(&pWal->mutex); tfClose(pWal->writeLogTfd); pWal->writeLogTfd = -1; tfClose(pWal->writeIdxTfd); pWal->writeIdxTfd = -1; - walWriteMeta(pWal); + walSaveMeta(pWal); taosArrayDestroy(pWal->fileInfoSet); pWal->fileInfoSet = NULL; pthread_mutex_unlock(&pWal->mutex); + taosRemoveRef(tsWal.refSetId, pWal->refId); } -static int32_t walInitObj(SWal *pWal) { - if (taosMkDir(pWal->path) != 0) { - wError("vgId:%d, path:%s, failed to create directory since %s", pWal->cfg.vgId, pWal->path, strerror(errno)); - return TAOS_SYSTEM_ERROR(errno); - } - pWal->fileInfoSet = taosArrayInit(8, sizeof(WalFileInfo)); - if(pWal->fileInfoSet == NULL) { - wError("vgId:%d, path:%s, failed to init taosArray %s", pWal->cfg.vgId, pWal->path, strerror(errno)); - return TAOS_SYSTEM_ERROR(errno); - } - - wDebug("vgId:%d, object is initialized", pWal->cfg.vgId); - return 0; -} - static void walFreeObj(void *wal) { SWal *pWal = wal; wDebug("vgId:%d, wal:%p is freed", pWal->cfg.vgId, pWal); - tfClose(pWal->writeLogTfd); - tfClose(pWal->writeIdxTfd); - taosArrayDestroy(pWal->fileInfoSet); - pWal->fileInfoSet = NULL; pthread_mutex_destroy(&pWal->mutex); tfree(pWal); } @@ -214,10 +201,12 @@ static void walFsyncAll() { SWal *pWal = taosIterateRef(tsWal.refSetId, 0); while (pWal) { if (walNeedFsync(pWal)) { - wTrace("vgId:%d, do fsync, level:%d seq:%d rseq:%d", pWal->cfg.vgId, pWal->cfg.level, pWal->fsyncSeq, atomic_load_32(&tsWal.seq)); + wTrace("vgId:%d, do fsync, level:%d seq:%d rseq:%d", pWal->cfg.vgId, pWal->cfg.level, pWal->fsyncSeq, + atomic_load_32(&tsWal.seq)); int32_t code = tfFsync(pWal->writeLogTfd); if (code != 0) { - wError("vgId:%d, file:%"PRId64".log, failed to fsync since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), strerror(code)); + wError("vgId:%d, file:%" PRId64 ".log, failed to fsync since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), + strerror(code)); } } pWal = taosIterateRef(tsWal.refSetId, pWal->refId); diff --git a/source/libs/wal/src/walRead.c b/source/libs/wal/src/walRead.c index b6aafedea3..b6e232fa5c 100644 --- a/source/libs/wal/src/walRead.c +++ b/source/libs/wal/src/walRead.c @@ -13,12 +13,12 @@ * along with this program. If not, see . */ -#include "walInt.h" #include "tfile.h" +#include "walInt.h" -SWalReadHandle* walOpenReadHandle(SWal* pWal) { +SWalReadHandle *walOpenReadHandle(SWal *pWal) { SWalReadHandle *pRead = malloc(sizeof(SWalReadHandle)); - if(pRead == NULL) { + if (pRead == NULL) { return NULL; } pRead->pWal = pWal; @@ -29,7 +29,7 @@ SWalReadHandle* walOpenReadHandle(SWal* pWal) { pRead->capacity = 0; pRead->status = 0; pRead->pHead = malloc(sizeof(SWalHead)); - if(pRead->pHead == NULL) { + if (pRead->pHead == NULL) { free(pRead); return NULL; } @@ -43,27 +43,25 @@ void walCloseReadHandle(SWalReadHandle *pRead) { free(pRead); } -int32_t walRegisterRead(SWalReadHandle *pRead, int64_t ver) { - return 0; -} +int32_t walRegisterRead(SWalReadHandle *pRead, int64_t ver) { return 0; } static int32_t walReadSeekFilePos(SWalReadHandle *pRead, int64_t fileFirstVer, int64_t ver) { int code = 0; int64_t idxTfd = pRead->readIdxTfd; int64_t logTfd = pRead->readLogTfd; - - //seek position - int64_t offset = (ver - fileFirstVer) * WAL_IDX_ENTRY_SIZE; + + // seek position + int64_t offset = (ver - fileFirstVer) * sizeof(WalIdxEntry); code = tfLseek(idxTfd, offset, SEEK_SET); - if(code < 0) { + if (code < 0) { return -1; } WalIdxEntry entry; - if(tfRead(idxTfd, &entry, sizeof(WalIdxEntry)) != sizeof(WalIdxEntry)) { + if (tfRead(idxTfd, &entry, sizeof(WalIdxEntry)) != sizeof(WalIdxEntry)) { return -1; } - //TODO:deserialize + // TODO:deserialize ASSERT(entry.ver == ver); code = tfLseek(logTfd, entry.offset, SEEK_SET); if (code < 0) { @@ -80,13 +78,13 @@ static int32_t walReadChangeFile(SWalReadHandle *pRead, int64_t fileFirstVer) { walBuildLogName(pRead->pWal, fileFirstVer, fnameStr); int64_t logTfd = tfOpenRead(fnameStr); - if(logTfd < 0) { + if (logTfd < 0) { return -1; } walBuildIdxName(pRead->pWal, fileFirstVer, fnameStr); int64_t idxTfd = tfOpenRead(fnameStr); - if(idxTfd < 0) { + if (idxTfd < 0) { return -1; } @@ -96,76 +94,75 @@ static int32_t walReadChangeFile(SWalReadHandle *pRead, int64_t fileFirstVer) { } static int32_t walReadSeekVer(SWalReadHandle *pRead, int64_t ver) { - int code; + int code; SWal *pWal = pRead->pWal; - if(ver == pRead->curVersion) { + if (ver == pRead->curVersion) { return 0; } - if(ver > pWal->vers.lastVer || ver < pWal->vers.firstVer) { + if (ver > pWal->vers.lastVer || ver < pWal->vers.firstVer) { return -1; } - if(ver < pWal->vers.snapshotVer) { - + if (ver < pWal->vers.snapshotVer) { } WalFileInfo tmpInfo; tmpInfo.firstVer = ver; - //bsearch in fileSet - WalFileInfo* pRet = taosArraySearch(pWal->fileInfoSet, &tmpInfo, compareWalFileInfo, TD_LE); + // bsearch in fileSet + WalFileInfo *pRet = taosArraySearch(pWal->fileInfoSet, &tmpInfo, compareWalFileInfo, TD_LE); ASSERT(pRet != NULL); - if(pRead->curFileFirstVer != pRet->firstVer) { + if (pRead->curFileFirstVer != pRet->firstVer) { code = walReadChangeFile(pRead, pRet->firstVer); - if(code < 0) { - //TODO: set error flag + if (code < 0) { + // TODO: set error flag return -1; } } code = walReadSeekFilePos(pRead, pRet->firstVer, ver); - if(code < 0) { + if (code < 0) { return -1; } pRead->curVersion = ver; - + return 0; } int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { int code; - //TODO: check wal life - if(pRead->curVersion != ver) { - code = walReadSeekVer(pRead, ver); - if(code != 0) { + // TODO: check wal life + if (pRead->curVersion != ver) { + code = walReadSeekVer(pRead, ver); + if (code != 0) { return -1; } } - if(!tfValid(pRead->readLogTfd)) return -1; + if (!tfValid(pRead->readLogTfd)) return -1; code = tfRead(pRead->readLogTfd, pRead->pHead, sizeof(SWalHead)); - if(code != sizeof(SWalHead)) { + if (code != sizeof(SWalHead)) { return -1; } code = walValidHeadCksum(pRead->pHead); - if(code != 0) { + if (code != 0) { return -1; } - if(pRead->capacity < pRead->pHead->head.len) { - void* ptr = realloc(pRead->pHead, sizeof(SWalHead) + pRead->pHead->head.len); - if(ptr == NULL) { + if (pRead->capacity < pRead->pHead->head.len) { + void *ptr = realloc(pRead->pHead, sizeof(SWalHead) + pRead->pHead->head.len); + if (ptr == NULL) { return -1; } pRead->pHead = ptr; pRead->capacity = pRead->pHead->head.len; } - if(pRead->pHead->head.len != tfRead(pRead->readLogTfd, pRead->pHead->head.body, pRead->pHead->head.len)) { + if (pRead->pHead->head.len != tfRead(pRead->readLogTfd, pRead->pHead->head.body, pRead->pHead->head.len)) { return -1; } /*code = walValidBodyCksum(pRead->pHead);*/ ASSERT(pRead->pHead->head.version == ver); - if(code != 0) { + if (code != 0) { return -1; } pRead->curVersion++; @@ -176,40 +173,40 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) { int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) { int code; code = walSeekVer(pWal, ver); - if(code != 0) { + if (code != 0) { return code; } - if(*ppHead == NULL) { - void* ptr = realloc(*ppHead, sizeof(SWalHead)); - if(ptr == NULL) { + if (*ppHead == NULL) { + void *ptr = realloc(*ppHead, sizeof(SWalHead)); + if (ptr == NULL) { return -1; } *ppHead = ptr; } - if(tfRead(pWal->writeLogTfd, *ppHead, sizeof(SWalHead)) != sizeof(SWalHead)) { + if (tfRead(pWal->writeLogTfd, *ppHead, sizeof(SWalHead)) != sizeof(SWalHead)) { return -1; } - //TODO: endian compatibility processing after read - if(walValidHeadCksum(*ppHead) != 0) { + // TODO: endian compatibility processing after read + if (walValidHeadCksum(*ppHead) != 0) { return -1; } - void* ptr = realloc(*ppHead, sizeof(SWalHead) + (*ppHead)->head.len); - if(ptr == NULL) { + void *ptr = realloc(*ppHead, sizeof(SWalHead) + (*ppHead)->head.len); + if (ptr == NULL) { free(*ppHead); *ppHead = NULL; return -1; } - if(tfRead(pWal->writeLogTfd, (*ppHead)->head.body, (*ppHead)->head.len) != (*ppHead)->head.len) { + if (tfRead(pWal->writeLogTfd, (*ppHead)->head.body, (*ppHead)->head.len) != (*ppHead)->head.len) { return -1; } - //TODO: endian compatibility processing after read - if(walValidBodyCksum(*ppHead) != 0) { + // TODO: endian compatibility processing after read + if (walValidBodyCksum(*ppHead) != 0) { return -1; } - + return 0; } -int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) { - return 0; -} +/*int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) {*/ +/*return 0;*/ +/*}*/ diff --git a/source/libs/wal/src/walSeek.c b/source/libs/wal/src/walSeek.c index 953aae703c..82c596d225 100644 --- a/source/libs/wal/src/walSeek.c +++ b/source/libs/wal/src/walSeek.c @@ -16,8 +16,8 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taoserror.h" -#include "tref.h" #include "tfile.h" +#include "tref.h" #include "walInt.h" static int walSeekFilePos(SWal* pWal, int64_t ver) { @@ -25,29 +25,29 @@ static int walSeekFilePos(SWal* pWal, int64_t ver) { int64_t idxTfd = pWal->writeIdxTfd; int64_t logTfd = pWal->writeLogTfd; - - //seek position - int64_t offset = (ver - walGetCurFileFirstVer(pWal)) * WAL_IDX_ENTRY_SIZE; - code = tfLseek(idxTfd, offset, SEEK_SET); - if(code != 0) { - return -1; - } - int64_t readBuf[2]; - code = tfRead(idxTfd, readBuf, sizeof(readBuf)); - if(code != 0) { - return -1; - } - //TODO:deserialize - ASSERT(readBuf[0] == ver); - code = tfLseek(logTfd, readBuf[1], SEEK_CUR); + + // seek position + int64_t idxOff = walGetVerIdxOffset(pWal, ver); + code = tfLseek(idxTfd, idxOff, SEEK_SET); if (code != 0) { return -1; } + WalIdxEntry entry; + // TODO:deserialize + code = tfRead(idxTfd, &entry, sizeof(WalIdxEntry)); + if (code != 0) { + return -1; + } + ASSERT(entry.ver == ver); + code = tfLseek(logTfd, entry.offset, SEEK_CUR); + if (code < 0) { + return -1; + } return code; } -int walChangeFileToLast(SWal *pWal) { - int64_t idxTfd, logTfd; +int walChangeFileToLast(SWal* pWal) { + int64_t idxTfd, logTfd; WalFileInfo* pRet = taosArrayGetLast(pWal->fileInfoSet); ASSERT(pRet != NULL); int64_t fileFirstVer = pRet->firstVer; @@ -55,51 +55,47 @@ int walChangeFileToLast(SWal *pWal) { char fnameStr[WAL_FILE_LEN]; walBuildIdxName(pWal, fileFirstVer, fnameStr); idxTfd = tfOpenReadWrite(fnameStr); - if(idxTfd < 0) { + if (idxTfd < 0) { return -1; } walBuildLogName(pWal, fileFirstVer, fnameStr); logTfd = tfOpenReadWrite(fnameStr); - if(logTfd < 0) { + if (logTfd < 0) { return -1; } - //switch file + // switch file pWal->writeIdxTfd = idxTfd; pWal->writeLogTfd = logTfd; - //change status - pWal->curStatus = WAL_CUR_FILE_WRITABLE; return 0; } -int walChangeFile(SWal *pWal, int64_t ver) { - int code = 0; +int walChangeFile(SWal* pWal, int64_t ver) { + int code = 0; int64_t idxTfd, logTfd; - char fnameStr[WAL_FILE_LEN]; + char fnameStr[WAL_FILE_LEN]; code = tfClose(pWal->writeLogTfd); - if(code != 0) { - //TODO + if (code != 0) { + // TODO return -1; } code = tfClose(pWal->writeIdxTfd); - if(code != 0) { - //TODO + if (code != 0) { + // TODO return -1; } WalFileInfo tmpInfo; tmpInfo.firstVer = ver; - //bsearch in fileSet + // bsearch in fileSet WalFileInfo* pRet = taosArraySearch(pWal->fileInfoSet, &tmpInfo, compareWalFileInfo, TD_LE); ASSERT(pRet != NULL); int64_t fileFirstVer = pRet->firstVer; - //closed - if(taosArrayGetLast(pWal->fileInfoSet) != pRet) { - pWal->curStatus &= ~WAL_CUR_FILE_WRITABLE; + // closed + if (taosArrayGetLast(pWal->fileInfoSet) != pRet) { walBuildIdxName(pWal, fileFirstVer, fnameStr); idxTfd = tfOpenRead(fnameStr); walBuildLogName(pWal, fileFirstVer, fnameStr); logTfd = tfOpenRead(fnameStr); } else { - pWal->curStatus |= WAL_CUR_FILE_WRITABLE; walBuildIdxName(pWal, fileFirstVer, fnameStr); idxTfd = tfOpenReadWrite(fnameStr); walBuildLogName(pWal, fileFirstVer, fnameStr); @@ -111,27 +107,26 @@ int walChangeFile(SWal *pWal, int64_t ver) { return fileFirstVer; } -int walSeekVer(SWal *pWal, int64_t ver) { +int walSeekVer(SWal* pWal, int64_t ver) { int code; - if(ver == pWal->vers.lastVer) { + if (ver == pWal->vers.lastVer) { return 0; } - if(ver > pWal->vers.lastVer|| ver < pWal->vers.firstVer) { + if (ver > pWal->vers.lastVer || ver < pWal->vers.firstVer) { return -1; } - if(ver < pWal->vers.snapshotVer) { - + if (ver < pWal->vers.snapshotVer) { } - if(ver < walGetCurFileFirstVer(pWal) || (ver > walGetCurFileLastVer(pWal))) { + if (ver < walGetCurFileFirstVer(pWal) || (ver > walGetCurFileLastVer(pWal))) { code = walChangeFile(pWal, ver); - if(code != 0) { + if (code != 0) { return -1; } } code = walSeekFilePos(pWal, ver); - if(code != 0) { + if (code != 0) { return -1; } - + return 0; } diff --git a/source/libs/wal/src/walUtil.c b/source/libs/wal/src/walUtil.c deleted file mode 100644 index 849d0c3e51..0000000000 --- a/source/libs/wal/src/walUtil.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "walInt.h" - -#if 0 -int32_t walGetNextFile(SWal *pWal, int64_t *nextFileId) { - int64_t curFileId = *nextFileId; - int64_t minFileId = INT64_MAX; - - DIR *dir = opendir(pWal->path); - if (dir == NULL) { - wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno)); - return -1; - } - - struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - char *name = ent->d_name; - - if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) { - int64_t id = atoll(name + WAL_PREFIX_LEN); - if (id <= curFileId) continue; - - if (id < minFileId) { - minFileId = id; - } - } - } - closedir(dir); - - if (minFileId == INT64_MAX) return -1; - - *nextFileId = minFileId; - wTrace("vgId:%d, path:%s, curFileId:%" PRId64 " nextFileId:%" PRId64, pWal->vgId, pWal->path, curFileId, *nextFileId); - - return 0; -} - -int32_t walGetOldFile(SWal *pWal, int64_t curFileId, int32_t minDiff, int64_t *oldFileId) { - int64_t minFileId = INT64_MAX; - - DIR *dir = opendir(pWal->path); - if (dir == NULL) { - wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno)); - return -1; - } - - struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - char *name = ent->d_name; - - if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) { - int64_t id = atoll(name + WAL_PREFIX_LEN); - if (id >= curFileId) continue; - - minDiff--; - if (id < minFileId) { - minFileId = id; - } - } - } - closedir(dir); - - if (minFileId == INT64_MAX) return -1; - if (minDiff > 0) return -1; - - *oldFileId = minFileId; - wTrace("vgId:%d, path:%s, curFileId:%" PRId64 " oldFildId:%" PRId64, pWal->vgId, pWal->path, curFileId, *oldFileId); - - return 0; -} - -int32_t walGetNewFile(SWal *pWal, int64_t *newFileId) { - int64_t maxFileId = INT64_MIN; - - DIR *dir = opendir(pWal->path); - if (dir == NULL) { - wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno)); - return -1; - } - - struct dirent *ent; - while ((ent = readdir(dir)) != NULL) { - char *name = ent->d_name; - - if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) { - int64_t id = atoll(name + WAL_PREFIX_LEN); - if (id > maxFileId) { - maxFileId = id; - } - } - } - closedir(dir); - - if (maxFileId == INT64_MIN) { - *newFileId = 0; - } else { - *newFileId = maxFileId; - } - - wTrace("vgId:%d, path:%s, newFileId:%" PRId64, pWal->vgId, pWal->path, *newFileId); - - return 0; -} -#endif diff --git a/source/libs/wal/src/walWrite.c b/source/libs/wal/src/walWrite.c index 994b8fc333..c3a7ca5f4d 100644 --- a/source/libs/wal/src/walWrite.c +++ b/source/libs/wal/src/walWrite.c @@ -21,102 +21,10 @@ #include "tfile.h" #include "walInt.h" - -#if 0 -static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, char *name, int64_t fileId); - -int32_t walRenew(void *handle) { - if (handle == NULL) return 0; - - SWal * pWal = handle; - int32_t code = 0; - - /*if (pWal->stop) {*/ - /*wDebug("vgId:%d, do not create a new wal file", pWal->vgId);*/ - /*return 0;*/ - /*}*/ - - pthread_mutex_lock(&pWal->mutex); - - if (tfValid(pWal->logTfd)) { - tfClose(pWal->logTfd); - wDebug("vgId:%d, file:%s, it is closed while renew", pWal->vgId, pWal->logName); - } - - /*if (pWal->keep == TAOS_WAL_KEEP) {*/ - /*pWal->fileId = 0;*/ - /*} else {*/ - /*if (walGetNewFile(pWal, &pWal->fileId) != 0) pWal->fileId = 0;*/ - /*pWal->fileId++;*/ - /*}*/ - - snprintf(pWal->logName, sizeof(pWal->logName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, pWal->curFileId); - pWal->logTfd = tfOpenCreateWrite(pWal->logName); - - if (!tfValid(pWal->logTfd)) { - code = TAOS_SYSTEM_ERROR(errno); - wError("vgId:%d, file:%s, failed to open since %s", pWal->vgId, pWal->logName, strerror(errno)); - } else { - wDebug("vgId:%d, file:%s, it is created and open while renew", pWal->vgId, pWal->logName); - } - - pthread_mutex_unlock(&pWal->mutex); - - return code; -} - -void walRemoveOneOldFile(void *handle) { - SWal *pWal = handle; - if (pWal == NULL) return; - /*if (pWal->keep == TAOS_WAL_KEEP) return;*/ - if (!tfValid(pWal->logTfd)) return; - - pthread_mutex_lock(&pWal->mutex); - - // remove the oldest wal file - int64_t oldFileId = -1; - if (walGetOldFile(pWal, pWal->curFileId, WAL_FILE_NUM, &oldFileId) == 0) { - char walName[WAL_FILE_LEN] = {0}; - snprintf(walName, sizeof(walName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, oldFileId); - - if (remove(walName) < 0) { - wError("vgId:%d, file:%s, failed to remove since %s", pWal->vgId, walName, strerror(errno)); - } else { - wInfo("vgId:%d, file:%s, it is removed", pWal->vgId, walName); - } - } - - pthread_mutex_unlock(&pWal->mutex); -} - -void walRemoveAllOldFiles(void *handle) { - if (handle == NULL) return; - - SWal * pWal = handle; - int64_t fileId = -1; - - pthread_mutex_lock(&pWal->mutex); - - tfClose(pWal->logTfd); - wDebug("vgId:%d, file:%s, it is closed before remove all wals", pWal->vgId, pWal->logName); - - while (walGetNextFile(pWal, &fileId) >= 0) { - snprintf(pWal->logName, sizeof(pWal->logName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, fileId); - - if (remove(pWal->logName) < 0) { - wError("vgId:%d, wal:%p file:%s, failed to remove since %s", pWal->vgId, pWal, pWal->logName, strerror(errno)); - } else { - wInfo("vgId:%d, wal:%p file:%s, it is removed", pWal->vgId, pWal, pWal->logName); - } - } - pthread_mutex_unlock(&pWal->mutex); -} -#endif - int32_t walCommit(SWal *pWal, int64_t ver) { ASSERT(pWal->vers.commitVer >= pWal->vers.snapshotVer); ASSERT(pWal->vers.commitVer <= pWal->vers.lastVer); - if(ver < pWal->vers.commitVer || ver > pWal->vers.lastVer) { + if (ver < pWal->vers.commitVer || ver > pWal->vers.lastVer) { return -1; } pWal->vers.commitVer = ver; @@ -124,58 +32,57 @@ int32_t walCommit(SWal *pWal, int64_t ver) { } int32_t walRollback(SWal *pWal, int64_t ver) { - int code; + int code; char fnameStr[WAL_FILE_LEN]; - if(ver == pWal->vers.lastVer) { + if (ver == pWal->vers.lastVer) { return 0; } - if(ver > pWal->vers.lastVer || ver < pWal->vers.commitVer) { + if (ver > pWal->vers.lastVer || ver < pWal->vers.commitVer) { return -1; } pthread_mutex_lock(&pWal->mutex); - //find correct file - if(ver < walGetLastFileFirstVer(pWal)) { - //close current files + // find correct file + if (ver < walGetLastFileFirstVer(pWal)) { + // close current files tfClose(pWal->writeIdxTfd); tfClose(pWal->writeLogTfd); - //open old files + // open old files code = walChangeFile(pWal, ver); - if(code != 0) { + if (code != 0) { return -1; } - //delete files + // delete files int fileSetSize = taosArrayGetSize(pWal->fileInfoSet); - for(int i = pWal->writeCur; i < fileSetSize; i++) { - walBuildLogName(pWal, ((WalFileInfo*)taosArrayGet(pWal->fileInfoSet, i))->firstVer, fnameStr); + for (int i = pWal->writeCur; i < fileSetSize; i++) { + walBuildLogName(pWal, ((WalFileInfo *)taosArrayGet(pWal->fileInfoSet, i))->firstVer, fnameStr); remove(fnameStr); - walBuildIdxName(pWal, ((WalFileInfo*)taosArrayGet(pWal->fileInfoSet, i))->firstVer, fnameStr); + walBuildIdxName(pWal, ((WalFileInfo *)taosArrayGet(pWal->fileInfoSet, i))->firstVer, fnameStr); remove(fnameStr); } - //pop from fileInfoSet + // pop from fileInfoSet taosArraySetSize(pWal->fileInfoSet, pWal->writeCur + 1); } walBuildIdxName(pWal, walGetCurFileFirstVer(pWal), fnameStr); int64_t idxTfd = tfOpenReadWrite(fnameStr); - //change to deserialize function - - if(idxTfd < 0) { + // TODO:change to deserialize function + if (idxTfd < 0) { pthread_mutex_unlock(&pWal->mutex); return -1; } - int idxOff = (ver - walGetCurFileFirstVer(pWal)) * WAL_IDX_ENTRY_SIZE; + int64_t idxOff = walGetVerIdxOffset(pWal, ver); code = tfLseek(idxTfd, idxOff, SEEK_SET); - if(code < 0) { + if (code < 0) { pthread_mutex_unlock(&pWal->mutex); return -1; } - //read idx file and get log file pos - //TODO:change to deserialize function + // read idx file and get log file pos + // TODO:change to deserialize function WalIdxEntry entry; - if(tfRead(idxTfd, &entry, sizeof(WalIdxEntry)) != sizeof(WalIdxEntry)) { + if (tfRead(idxTfd, &entry, sizeof(WalIdxEntry)) != sizeof(WalIdxEntry)) { pthread_mutex_unlock(&pWal->mutex); return -1; } @@ -183,112 +90,112 @@ int32_t walRollback(SWal *pWal, int64_t ver) { walBuildLogName(pWal, walGetCurFileFirstVer(pWal), fnameStr); int64_t logTfd = tfOpenReadWrite(fnameStr); - if(logTfd < 0) { - //TODO + if (logTfd < 0) { + // TODO pthread_mutex_unlock(&pWal->mutex); return -1; } code = tfLseek(logTfd, entry.offset, SEEK_SET); - if(code < 0) { - //TODO + if (code < 0) { + // TODO pthread_mutex_unlock(&pWal->mutex); return -1; } - //validate offset + // validate offset SWalHead head; ASSERT(tfValid(logTfd)); int size = tfRead(logTfd, &head, sizeof(SWalHead)); - if(size != sizeof(SWalHead)) { + if (size != sizeof(SWalHead)) { return -1; } code = walValidHeadCksum(&head); ASSERT(code == 0); - if(code != 0) { + if (code != 0) { return -1; } - if(head.head.version != ver) { - //TODO + if (head.head.version != ver) { + // TODO return -1; } - //truncate old files + // truncate old files code = tfFtruncate(logTfd, entry.offset); - if(code < 0) { + if (code < 0) { return -1; } code = tfFtruncate(idxTfd, idxOff); - if(code < 0) { + if (code < 0) { return -1; } pWal->vers.lastVer = ver - 1; - ((WalFileInfo*)taosArrayGetLast(pWal->fileInfoSet))->lastVer = ver - 1; - ((WalFileInfo*)taosArrayGetLast(pWal->fileInfoSet))->fileSize = entry.offset; + ((WalFileInfo *)taosArrayGetLast(pWal->fileInfoSet))->lastVer = ver - 1; + ((WalFileInfo *)taosArrayGetLast(pWal->fileInfoSet))->fileSize = entry.offset; - //unlock + // unlock pthread_mutex_unlock(&pWal->mutex); return 0; } -int32_t walBeginTakeSnapshot(SWal* pWal, int64_t ver) { +int32_t walBeginSnapshot(SWal *pWal, int64_t ver) { pWal->vers.verInSnapshotting = ver; - //check file rolling - if(pWal->cfg.retentionPeriod == 0) { + // check file rolling + if (pWal->cfg.retentionPeriod == 0) { walRoll(pWal); } return 0; } -int32_t walEndTakeSnapshot(SWal *pWal) { +int32_t walEndSnapshot(SWal *pWal) { int64_t ver = pWal->vers.verInSnapshotting; - if(ver == -1) return -1; + if (ver == -1) return -1; pWal->vers.snapshotVer = ver; int ts = taosGetTimestampSec(); - int deleteCnt = 0; - int64_t newTotSize = pWal->totSize; + int deleteCnt = 0; + int64_t newTotSize = pWal->totSize; WalFileInfo tmp; tmp.firstVer = ver; - //find files safe to delete - WalFileInfo* pInfo = taosArraySearch(pWal->fileInfoSet, &tmp, compareWalFileInfo, TD_LE); - if(ver >= pInfo->lastVer) { + // find files safe to delete + WalFileInfo *pInfo = taosArraySearch(pWal->fileInfoSet, &tmp, compareWalFileInfo, TD_LE); + if (ver >= pInfo->lastVer) { pInfo++; } - //iterate files, until the searched result - for(WalFileInfo* iter = pWal->fileInfoSet->pData; iter < pInfo; iter++) { - if(pWal->totSize > pWal->cfg.retentionSize || - iter->closeTs + pWal->cfg.retentionPeriod > ts) { - //delete according to file size or close time + // iterate files, until the searched result + for (WalFileInfo *iter = pWal->fileInfoSet->pData; iter < pInfo; iter++) { + if (pWal->totSize > pWal->cfg.retentionSize || iter->closeTs + pWal->cfg.retentionPeriod > ts) { + // delete according to file size or close time deleteCnt++; newTotSize -= iter->fileSize; } } char fnameStr[WAL_FILE_LEN]; - //remove file - for(int i = 0; i < deleteCnt; i++) { - WalFileInfo* pInfo = taosArrayGet(pWal->fileInfoSet, i); - walBuildLogName(pWal, pInfo->firstVer, fnameStr); + // remove file + for (int i = 0; i < deleteCnt; i++) { + WalFileInfo *pInfo = taosArrayGet(pWal->fileInfoSet, i); + walBuildLogName(pWal, pInfo->firstVer, fnameStr); remove(fnameStr); - walBuildIdxName(pWal, pInfo->firstVer, fnameStr); + walBuildIdxName(pWal, pInfo->firstVer, fnameStr); remove(fnameStr); } - //make new array, remove files - taosArrayPopFrontBatch(pWal->fileInfoSet, deleteCnt); - if(taosArrayGetSize(pWal->fileInfoSet) == 0) { + // make new array, remove files + taosArrayPopFrontBatch(pWal->fileInfoSet, deleteCnt); + if (taosArrayGetSize(pWal->fileInfoSet) == 0) { pWal->writeCur = -1; pWal->vers.firstVer = -1; } else { - pWal->vers.firstVer = ((WalFileInfo*)taosArrayGet(pWal->fileInfoSet, 0))->firstVer; + pWal->vers.firstVer = ((WalFileInfo *)taosArrayGet(pWal->fileInfoSet, 0))->firstVer; } - pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1;; + pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1; + ; pWal->totSize = newTotSize; pWal->vers.verInSnapshotting = -1; - //save snapshot ver, commit ver - int code = walWriteMeta(pWal); - if(code != 0) { + // save snapshot ver, commit ver + int code = walSaveMeta(pWal); + if (code != 0) { return -1; } @@ -297,56 +204,54 @@ int32_t walEndTakeSnapshot(SWal *pWal) { int walRoll(SWal *pWal) { int code = 0; - if(pWal->writeIdxTfd != -1) { + if (pWal->writeIdxTfd != -1) { code = tfClose(pWal->writeIdxTfd); - if(code != 0) { + if (code != 0) { return -1; } } - if(pWal->writeLogTfd != -1) { + if (pWal->writeLogTfd != -1) { code = tfClose(pWal->writeLogTfd); - if(code != 0) { + if (code != 0) { return -1; } } int64_t idxTfd, logTfd; - //create new file + // create new file int64_t newFileFirstVersion = pWal->vers.lastVer + 1; - char fnameStr[WAL_FILE_LEN]; + char fnameStr[WAL_FILE_LEN]; walBuildIdxName(pWal, newFileFirstVersion, fnameStr); - idxTfd = tfOpenCreateWrite(fnameStr); - if(idxTfd < 0) { + idxTfd = tfOpenCreateWriteAppend(fnameStr); + if (idxTfd < 0) { ASSERT(0); return -1; } walBuildLogName(pWal, newFileFirstVersion, fnameStr); - logTfd = tfOpenCreateWrite(fnameStr); - if(logTfd < 0) { + logTfd = tfOpenCreateWriteAppend(fnameStr); + if (logTfd < 0) { ASSERT(0); return -1; } code = walRollFileInfo(pWal); - if(code != 0) { + if (code != 0) { ASSERT(0); return -1; } - //switch file + // switch file pWal->writeIdxTfd = idxTfd; pWal->writeLogTfd = logTfd; pWal->writeCur = taosArrayGetSize(pWal->fileInfoSet) - 1; - //change status - pWal->curStatus = WAL_CUR_FILE_WRITABLE & WAL_CUR_POS_WRITABLE; pWal->lastRollSeq = walGetSeq(); return 0; } static int walWriteIndex(SWal *pWal, int64_t ver, int64_t offset) { - WalIdxEntry entry = { .ver = ver, .offset = offset }; - int size = tfWrite(pWal->writeIdxTfd, &entry, sizeof(WalIdxEntry)); - if(size != sizeof(WalIdxEntry)) { - //TODO truncate + WalIdxEntry entry = {.ver = ver, .offset = offset}; + int size = tfWrite(pWal->writeIdxTfd, &entry, sizeof(WalIdxEntry)); + if (size != sizeof(WalIdxEntry)) { + // TODO truncate return -1; } return 0; @@ -360,21 +265,21 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i if (pWal->cfg.level == TAOS_WAL_NOLOG) return 0; if (index == pWal->vers.lastVer + 1) { - if(taosArrayGetSize(pWal->fileInfoSet) == 0) { + if (taosArrayGetSize(pWal->fileInfoSet) == 0) { pWal->vers.firstVer = index; code = walRoll(pWal); ASSERT(code == 0); } else { int64_t passed = walGetSeq() - pWal->lastRollSeq; - if(pWal->cfg.rollPeriod != -1 && pWal->cfg.rollPeriod != 0 && passed > pWal->cfg.rollPeriod) { + if (pWal->cfg.rollPeriod != -1 && pWal->cfg.rollPeriod != 0 && passed > pWal->cfg.rollPeriod) { walRoll(pWal); - } else if(pWal->cfg.segSize != -1 && pWal->cfg.segSize != 0 && walGetLastFileSize(pWal) > pWal->cfg.segSize) { + } else if (pWal->cfg.segSize != -1 && pWal->cfg.segSize != 0 && walGetLastFileSize(pWal) > pWal->cfg.segSize) { walRoll(pWal); } } } else { - //reject skip log or rewrite log - //must truncate explicitly first + // reject skip log or rewrite log + // must truncate explicitly first return -1; } /*if (!tfValid(pWal->writeLogTfd)) return -1;*/ @@ -389,28 +294,30 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i pWal->writeHead.cksumBody = walCalcBodyCksum(body, bodyLen); if (tfWrite(pWal->writeLogTfd, &pWal->writeHead, sizeof(SWalHead)) != sizeof(SWalHead)) { - //ftruncate + // ftruncate code = TAOS_SYSTEM_ERROR(errno); - wError("vgId:%d, file:%"PRId64".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), strerror(errno)); + wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), + strerror(errno)); } - if (tfWrite(pWal->writeLogTfd, (char*)body, bodyLen) != bodyLen) { - //ftruncate + if (tfWrite(pWal->writeLogTfd, (char *)body, bodyLen) != bodyLen) { + // ftruncate code = TAOS_SYSTEM_ERROR(errno); - wError("vgId:%d, file:%"PRId64".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), strerror(errno)); + wError("vgId:%d, file:%" PRId64 ".log, failed to write since %s", pWal->cfg.vgId, walGetLastFileFirstVer(pWal), + strerror(errno)); } code = walWriteIndex(pWal, index, offset); - if(code != 0) { - //TODO + if (code != 0) { + // TODO return -1; } - //set status + // set status pWal->vers.lastVer = index; pWal->totSize += sizeof(SWalHead) + bodyLen; walGetCurFileInfo(pWal)->lastVer = index; walGetCurFileInfo(pWal)->fileSize += sizeof(SWalHead) + bodyLen; - + pthread_mutex_unlock(&pWal->mutex); return code; @@ -418,237 +325,34 @@ int64_t walWrite(SWal *pWal, int64_t index, uint8_t msgType, const void *body, i void walFsync(SWal *pWal, bool forceFsync) { if (forceFsync || (pWal->cfg.level == TAOS_WAL_FSYNC && pWal->cfg.fsyncPeriod == 0)) { - wTrace("vgId:%d, fileId:%"PRId64".log, do fsync", pWal->cfg.vgId, walGetCurFileFirstVer(pWal)); + wTrace("vgId:%d, fileId:%" PRId64 ".log, do fsync", pWal->cfg.vgId, walGetCurFileFirstVer(pWal)); if (tfFsync(pWal->writeLogTfd) < 0) { - wError("vgId:%d, file:%"PRId64".log, fsync failed since %s", pWal->cfg.vgId, walGetCurFileFirstVer(pWal), strerror(errno)); + wError("vgId:%d, file:%" PRId64 ".log, fsync failed since %s", pWal->cfg.vgId, walGetCurFileFirstVer(pWal), + strerror(errno)); } } } -#if 0 -int32_t walRestore(void *handle, void *pVnode, FWalWrite writeFp) { - if (handle == NULL) return -1; - - SWal * pWal = handle; - int32_t count = 0; - int32_t code = 0; - int64_t fileId = -1; - - while ((code = walGetNextFile(pWal, &fileId)) >= 0) { - /*if (fileId == pWal->curFileId) continue;*/ - - char walName[WAL_FILE_LEN]; - snprintf(walName, sizeof(pWal->logName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, fileId); - - wInfo("vgId:%d, file:%s, will be restored", pWal->vgId, walName); - code = walRestoreWalFile(pWal, pVnode, writeFp, walName, fileId); - if (code != TSDB_CODE_SUCCESS) { - wError("vgId:%d, file:%s, failed to restore since %s", pWal->vgId, walName, tstrerror(code)); - continue; - } - - wInfo("vgId:%d, file:%s, restore success, wver:%" PRIu64, pWal->vgId, walName, pWal->curVersion); - - count++; - } - - /*if (pWal->keep != TAOS_WAL_KEEP) return TSDB_CODE_SUCCESS;*/ - - if (count == 0) { - wDebug("vgId:%d, wal file not exist, renew it", pWal->vgId); - return walRenew(pWal); - } else { - // open the existing WAL file in append mode - /*pWal->curFileId = 0;*/ - snprintf(pWal->logName, sizeof(pWal->logName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, pWal->curFileId); - pWal->logTfd = tfOpenCreateWriteAppend(pWal->logName); - if (!tfValid(pWal->logTfd)) { - wError("vgId:%d, file:%s, failed to open since %s", pWal->vgId, pWal->logName, strerror(errno)); - return TAOS_SYSTEM_ERROR(errno); - } - wDebug("vgId:%d, file:%s, it is created and open while restore", pWal->vgId, pWal->logName); - } - - return TSDB_CODE_SUCCESS; -} - -int32_t walGetWalFile(void *handle, char *fileName, int64_t *fileId) { - if (handle == NULL) return -1; - SWal *pWal = handle; - - if (*fileId == 0) *fileId = -1; - - pthread_mutex_lock(&(pWal->mutex)); - - int32_t code = walGetNextFile(pWal, fileId); - if (code >= 0) { - sprintf(fileName, "wal/%s%" PRId64, WAL_PREFIX, *fileId); - /*code = (*fileId == pWal->curFileId) ? 0 : 1;*/ - } - - wDebug("vgId:%d, get wal file, code:%d curId:%" PRId64 " outId:%" PRId64, pWal->vgId, code, pWal->curFileId, *fileId); - pthread_mutex_unlock(&(pWal->mutex)); - - return code; -} -#endif - /*static int walValidateOffset(SWal* pWal, int64_t ver) {*/ - /*int code = 0;*/ - /*SWalHead *pHead = NULL;*/ - /*code = (int)walRead(pWal, &pHead, ver);*/ - /*if(pHead->head.version != ver) {*/ - /*return -1;*/ - /*}*/ - /*return 0;*/ +/*int code = 0;*/ +/*SWalHead *pHead = NULL;*/ +/*code = (int)walRead(pWal, &pHead, ver);*/ +/*if(pHead->head.version != ver) {*/ +/*return -1;*/ +/*}*/ +/*return 0;*/ /*}*/ /*static int64_t walGetOffset(SWal* pWal, int64_t ver) {*/ - /*int code = walSeekVer(pWal, ver);*/ - /*if(code != 0) {*/ - /*return -1;*/ - /*}*/ - - /*code = walValidateOffset(pWal, ver);*/ - /*if(code != 0) {*/ - /*return -1;*/ - /*}*/ - - /*return 0;*/ +/*int code = walSeekVer(pWal, ver);*/ +/*if(code != 0) {*/ +/*return -1;*/ /*}*/ -#if 0 -static int32_t walSkipCorruptedRecord(SWal *pWal, SWalHead *pHead, int64_t tfd, int64_t *offset) { - int64_t pos = *offset; - while (1) { - pos++; +/*code = walValidateOffset(pWal, ver);*/ +/*if(code != 0) {*/ +/*return -1;*/ +/*}*/ - if (tfLseek(tfd, pos, SEEK_SET) < 0) { - wError("vgId:%d, failed to seek from corrupted wal file since %s", pWal->vgId, strerror(errno)); - return TSDB_CODE_WAL_FILE_CORRUPTED; - } - - if (tfRead(tfd, pHead, sizeof(SWalHead)) <= 0) { - wError("vgId:%d, read to end of corrupted wal file, offset:%" PRId64, pWal->vgId, pos); - return TSDB_CODE_WAL_FILE_CORRUPTED; - } - - if (pHead->signature != WAL_SIGNATURE) { - continue; - } - - if (pHead->sver >= 1) { - if (tfRead(tfd, pHead->cont, pHead->len) < pHead->len) { - wError("vgId:%d, read to end of corrupted wal file, offset:%" PRId64, pWal->vgId, pos); - return TSDB_CODE_WAL_FILE_CORRUPTED; - } - - if (walValidateChecksum(pHead)) { - wInfo("vgId:%d, wal whole cksum check passed, offset:%" PRId64, pWal->vgId, pos); - *offset = pos; - return TSDB_CODE_SUCCESS; - } - } - } - - return TSDB_CODE_WAL_FILE_CORRUPTED; -} - -static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, char *name, int64_t fileId) { - int32_t size = WAL_MAX_SIZE; - void * buffer = malloc(size); - if (buffer == NULL) { - wError("vgId:%d, file:%s, failed to open for restore since %s", pWal->vgId, name, strerror(errno)); - return TAOS_SYSTEM_ERROR(errno); - } - - int64_t tfd = tfOpenReadWrite(name); - if (!tfValid(tfd)) { - wError("vgId:%d, file:%s, failed to open for restore since %s", pWal->vgId, name, strerror(errno)); - tfree(buffer); - return TAOS_SYSTEM_ERROR(errno); - } else { - wDebug("vgId:%d, file:%s, open for restore", pWal->vgId, name); - } - - int32_t code = TSDB_CODE_SUCCESS; - int64_t offset = 0; - SWalHead *pHead = buffer; - - while (1) { - int32_t ret = (int32_t)tfRead(tfd, pHead, sizeof(SWalHead)); - if (ret == 0) break; - - if (ret < 0) { - wError("vgId:%d, file:%s, failed to read wal head since %s", pWal->vgId, name, strerror(errno)); - code = TAOS_SYSTEM_ERROR(errno); - break; - } - - if (ret < sizeof(SWalHead)) { - wError("vgId:%d, file:%s, failed to read wal head, ret is %d", pWal->vgId, name, ret); - walFtruncate(pWal, tfd, offset); - break; - } - - if ((pHead->sver == 0 && !walValidateChecksum(pHead)) || pHead->sver < 0 || pHead->sver > 2) { - wError("vgId:%d, file:%s, wal head cksum is messed up, hver:%" PRIu64 " len:%d offset:%" PRId64, pWal->vgId, name, - pHead->version, pHead->len, offset); - code = walSkipCorruptedRecord(pWal, pHead, tfd, &offset); - if (code != TSDB_CODE_SUCCESS) { - walFtruncate(pWal, tfd, offset); - break; - } - } - - if (pHead->len < 0 || pHead->len > size - sizeof(SWalHead)) { - wError("vgId:%d, file:%s, wal head len out of range, hver:%" PRIu64 " len:%d offset:%" PRId64, pWal->vgId, name, - pHead->version, pHead->len, offset); - code = walSkipCorruptedRecord(pWal, pHead, tfd, &offset); - if (code != TSDB_CODE_SUCCESS) { - walFtruncate(pWal, tfd, offset); - break; - } - } - - ret = (int32_t)tfRead(tfd, pHead->cont, pHead->len); - if (ret < 0) { - wError("vgId:%d, file:%s, failed to read wal body since %s", pWal->vgId, name, strerror(errno)); - code = TAOS_SYSTEM_ERROR(errno); - break; - } - - if (ret < pHead->len) { - wError("vgId:%d, file:%s, failed to read wal body, ret:%d len:%d", pWal->vgId, name, ret, pHead->len); - offset += sizeof(SWalHead); - continue; - } - - if ((pHead->sver >= 1) && !walValidateChecksum(pHead)) { - wError("vgId:%d, file:%s, wal whole cksum is messed up, hver:%" PRIu64 " len:%d offset:%" PRId64, pWal->vgId, name, - pHead->version, pHead->len, offset); - code = walSkipCorruptedRecord(pWal, pHead, tfd, &offset); - if (code != TSDB_CODE_SUCCESS) { - walFtruncate(pWal, tfd, offset); - break; - } - } - - offset = offset + sizeof(SWalHead) + pHead->len; - - wTrace("vgId:%d, restore wal, fileId:%" PRId64 " hver:%" PRIu64 " wver:%" PRIu64 " len:%d offset:%" PRId64, - pWal->vgId, fileId, pHead->version, pWal->curVersion, pHead->len, offset); - - pWal->curVersion = pHead->version; - - // wInfo("writeFp: %ld", offset); - (*writeFp)(pVnode, pHead); - } - - tfClose(tfd); - tfree(buffer); - - wDebug("vgId:%d, file:%s, it is closed after restore", pWal->vgId, name); - return code; -} -#endif +/*return 0;*/ +/*}*/ diff --git a/source/libs/wal/test/walMetaTest.cpp b/source/libs/wal/test/walMetaTest.cpp index 200bf39c5a..cd082a3a43 100644 --- a/source/libs/wal/test/walMetaTest.cpp +++ b/source/libs/wal/test/walMetaTest.cpp @@ -6,111 +6,105 @@ #include "walInt.h" const char* ranStr = "tvapq02tcp"; -const int ranStrLen = strlen(ranStr); +const int ranStrLen = strlen(ranStr); class WalCleanEnv : public ::testing::Test { - protected: - static void SetUpTestCase() { - int code = walInit(); - ASSERT(code == 0); - } + protected: + static void SetUpTestCase() { + int code = walInit(); + ASSERT(code == 0); + } - static void TearDownTestCase() { - walCleanUp(); - } + static void TearDownTestCase() { walCleanUp(); } - void SetUp() override { - taosRemoveDir(pathName); - SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); - memset(pCfg, 0, sizeof(SWalCfg)); - pCfg->rollPeriod = -1; - pCfg->segSize = -1; - pCfg->retentionPeriod = 0; - pCfg->retentionSize = 0; - pCfg->level = TAOS_WAL_FSYNC; - pWal = walOpen(pathName, pCfg); - free(pCfg); - ASSERT(pWal != NULL); - } + void SetUp() override { + taosRemoveDir(pathName); + SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); + memset(pCfg, 0, sizeof(SWalCfg)); + pCfg->rollPeriod = -1; + pCfg->segSize = -1; + pCfg->retentionPeriod = 0; + pCfg->retentionSize = 0; + pCfg->level = TAOS_WAL_FSYNC; + pWal = walOpen(pathName, pCfg); + free(pCfg); + ASSERT(pWal != NULL); + } - void TearDown() override { - walClose(pWal); - pWal = NULL; - } + void TearDown() override { + walClose(pWal); + pWal = NULL; + } - SWal* pWal = NULL; - const char* pathName = "/tmp/wal_test"; + SWal* pWal = NULL; + const char* pathName = "/tmp/wal_test"; }; class WalCleanDeleteEnv : public ::testing::Test { - protected: - static void SetUpTestCase() { - int code = walInit(); - ASSERT(code == 0); - } + protected: + static void SetUpTestCase() { + int code = walInit(); + ASSERT(code == 0); + } - static void TearDownTestCase() { - walCleanUp(); - } + static void TearDownTestCase() { walCleanUp(); } - void SetUp() override { - taosRemoveDir(pathName); - SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); - memset(pCfg, 0, sizeof(SWalCfg)); - pCfg->retentionPeriod = 0; - pCfg->retentionSize = 0; - pCfg->level = TAOS_WAL_FSYNC; - pWal = walOpen(pathName, pCfg); - free(pCfg); - ASSERT(pWal != NULL); - } + void SetUp() override { + taosRemoveDir(pathName); + SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); + memset(pCfg, 0, sizeof(SWalCfg)); + pCfg->retentionPeriod = 0; + pCfg->retentionSize = 0; + pCfg->level = TAOS_WAL_FSYNC; + pWal = walOpen(pathName, pCfg); + free(pCfg); + ASSERT(pWal != NULL); + } - void TearDown() override { - walClose(pWal); - pWal = NULL; - } + void TearDown() override { + walClose(pWal); + pWal = NULL; + } - SWal* pWal = NULL; - const char* pathName = "/tmp/wal_test"; + SWal* pWal = NULL; + const char* pathName = "/tmp/wal_test"; }; class WalKeepEnv : public ::testing::Test { - protected: - static void SetUpTestCase() { - int code = walInit(); - ASSERT(code == 0); - } + protected: + static void SetUpTestCase() { + int code = walInit(); + ASSERT(code == 0); + } - static void TearDownTestCase() { - walCleanUp(); - } + static void TearDownTestCase() { walCleanUp(); } - void walResetEnv() { - TearDown(); - taosRemoveDir(pathName); - SetUp(); - } + void walResetEnv() { + TearDown(); + taosRemoveDir(pathName); + SetUp(); + } - void SetUp() override { - SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); - memset(pCfg, 0, sizeof(SWalCfg)); - pCfg->rollPeriod = -1; - pCfg->segSize = -1; - pCfg->retentionPeriod = 0; - pCfg->retentionSize = 0; - pCfg->level = TAOS_WAL_FSYNC; - pWal = walOpen(pathName, pCfg); - free(pCfg); - ASSERT(pWal != NULL); - } + void SetUp() override { + SWalCfg* pCfg = (SWalCfg*)malloc(sizeof(SWalCfg)); + memset(pCfg, 0, sizeof(SWalCfg)); + pCfg->rollPeriod = -1; + pCfg->segSize = -1; + pCfg->retentionPeriod = 0; + pCfg->retentionSize = 0; + pCfg->level = TAOS_WAL_FSYNC; + pWal = walOpen(pathName, pCfg); + free(pCfg); + ASSERT(pWal != NULL); + } - void TearDown() override { - walClose(pWal); - pWal = NULL; - } + void TearDown() override { + walClose(pWal); + pWal = NULL; + } - SWal* pWal = NULL; - const char* pathName = "/tmp/wal_test"; + SWal* pWal = NULL; + const char* pathName = "/tmp/wal_test"; }; TEST_F(WalCleanEnv, createNew) { @@ -139,10 +133,10 @@ TEST_F(WalCleanEnv, serialize) { ASSERT(code == 0); code = walRollFileInfo(pWal); ASSERT(code == 0); - char*ss = walMetaSerialize(pWal); + char* ss = walMetaSerialize(pWal); printf("%s\n", ss); free(ss); - code = walWriteMeta(pWal); + code = walSaveMeta(pWal); ASSERT(code == 0); } @@ -150,11 +144,11 @@ TEST_F(WalCleanEnv, removeOldMeta) { int code = walRollFileInfo(pWal); ASSERT(code == 0); ASSERT(pWal->fileInfoSet != NULL); - code = walWriteMeta(pWal); + code = walSaveMeta(pWal); ASSERT(code == 0); code = walRollFileInfo(pWal); ASSERT(code == 0); - code = walWriteMeta(pWal); + code = walSaveMeta(pWal); ASSERT(code == 0); } @@ -162,11 +156,11 @@ TEST_F(WalKeepEnv, readOldMeta) { walResetEnv(); int code; - for(int i = 0; i < 10; i++) { - code = walWrite(pWal, i, i+1, (void*)ranStr, ranStrLen); + for (int i = 0; i < 10; i++) { + code = walWrite(pWal, i, i + 1, (void*)ranStr, ranStrLen); ASSERT_EQ(code, 0); ASSERT_EQ(pWal->vers.lastVer, i); - code = walWrite(pWal, i+2, i, (void*)ranStr, ranStrLen); + code = walWrite(pWal, i + 2, i, (void*)ranStr, ranStrLen); ASSERT_EQ(code, -1); ASSERT_EQ(pWal->vers.lastVer, i); } @@ -182,7 +176,7 @@ TEST_F(WalKeepEnv, readOldMeta) { int len = strlen(oldss); ASSERT_EQ(len, strlen(newss)); - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { EXPECT_EQ(oldss[i], newss[i]); } free(oldss); @@ -191,22 +185,22 @@ TEST_F(WalKeepEnv, readOldMeta) { TEST_F(WalCleanEnv, write) { int code; - for(int i = 0; i < 10; i++) { - code = walWrite(pWal, i, i+1, (void*)ranStr, ranStrLen); + for (int i = 0; i < 10; i++) { + code = walWrite(pWal, i, i + 1, (void*)ranStr, ranStrLen); ASSERT_EQ(code, 0); ASSERT_EQ(pWal->vers.lastVer, i); - code = walWrite(pWal, i+2, i, (void*)ranStr, ranStrLen); + code = walWrite(pWal, i + 2, i, (void*)ranStr, ranStrLen); ASSERT_EQ(code, -1); ASSERT_EQ(pWal->vers.lastVer, i); } - code = walWriteMeta(pWal); + code = walSaveMeta(pWal); ASSERT_EQ(code, 0); } TEST_F(WalCleanEnv, rollback) { int code; - for(int i = 0; i < 10; i++) { - code = walWrite(pWal, i, i+1, (void*)ranStr, ranStrLen); + for (int i = 0; i < 10; i++) { + code = walWrite(pWal, i, i + 1, (void*)ranStr, ranStrLen); ASSERT_EQ(code, 0); ASSERT_EQ(pWal->vers.lastVer, i); } @@ -216,14 +210,14 @@ TEST_F(WalCleanEnv, rollback) { code = walRollback(pWal, 3); ASSERT_EQ(code, 0); ASSERT_EQ(pWal->vers.lastVer, 2); - code = walWriteMeta(pWal); + code = walSaveMeta(pWal); ASSERT_EQ(code, 0); } TEST_F(WalCleanDeleteEnv, roll) { int code; int i; - for(i = 0; i < 100; i++) { + for (i = 0; i < 100; i++) { code = walWrite(pWal, i, 0, (void*)ranStr, ranStrLen); ASSERT_EQ(code, 0); ASSERT_EQ(pWal->vers.lastVer, i); @@ -231,60 +225,60 @@ TEST_F(WalCleanDeleteEnv, roll) { ASSERT_EQ(pWal->vers.commitVer, i); } - walBeginTakeSnapshot(pWal, i-1); - ASSERT_EQ(pWal->vers.verInSnapshotting, i-1); - walEndTakeSnapshot(pWal); - ASSERT_EQ(pWal->vers.snapshotVer, i-1); + walBeginSnapshot(pWal, i - 1); + ASSERT_EQ(pWal->vers.verInSnapshotting, i - 1); + walEndSnapshot(pWal); + ASSERT_EQ(pWal->vers.snapshotVer, i - 1); ASSERT_EQ(pWal->vers.verInSnapshotting, -1); code = walWrite(pWal, 5, 0, (void*)ranStr, ranStrLen); ASSERT_NE(code, 0); - for(; i < 200; i++) { + for (; i < 200; i++) { code = walWrite(pWal, i, 0, (void*)ranStr, ranStrLen); ASSERT_EQ(code, 0); code = walCommit(pWal, i); ASSERT_EQ(pWal->vers.commitVer, i); } - code = walBeginTakeSnapshot(pWal, i - 1); + code = walBeginSnapshot(pWal, i - 1); ASSERT_EQ(code, 0); - code = walEndTakeSnapshot(pWal); + code = walEndSnapshot(pWal); ASSERT_EQ(code, 0); } TEST_F(WalKeepEnv, readHandleRead) { walResetEnv(); - int code; + int code; SWalReadHandle* pRead = walOpenReadHandle(pWal); ASSERT(pRead != NULL); - int i ; - for(i = 0; i < 100; i++) { + int i; + for (i = 0; i < 100; i++) { char newStr[100]; sprintf(newStr, "%s-%d", ranStr, i); int len = strlen(newStr); code = walWrite(pWal, i, 0, newStr, len); ASSERT_EQ(code, 0); } - for(int i = 0; i < 1000; i++) { + for (int i = 0; i < 1000; i++) { int ver = rand() % 100; code = walReadWithHandle(pRead, ver); ASSERT_EQ(code, 0); - //printf("rrbody: \n"); - //for(int i = 0; i < pRead->pHead->head.len; i++) { - //printf("%d ", pRead->pHead->head.body[i]); + // printf("rrbody: \n"); + // for(int i = 0; i < pRead->pHead->head.len; i++) { + // printf("%d ", pRead->pHead->head.body[i]); //} - //printf("\n"); + // printf("\n"); ASSERT_EQ(pRead->pHead->head.version, ver); - ASSERT_EQ(pRead->curVersion, ver+1); + ASSERT_EQ(pRead->curVersion, ver + 1); char newStr[100]; sprintf(newStr, "%s-%d", ranStr, ver); int len = strlen(newStr); ASSERT_EQ(pRead->pHead->head.len, len); - for(int j = 0; j < len; j++) { + for (int j = 0; j < len; j++) { EXPECT_EQ(newStr[j], pRead->pHead->head.body[j]); } } diff --git a/source/util/src/tarray.c b/source/util/src/tarray.c index 581a797343..cc8d6646b6 100644 --- a/source/util/src/tarray.c +++ b/source/util/src/tarray.c @@ -17,7 +17,7 @@ #include "tarray.h" #include "talgo.h" -void* taosArrayInit(size_t size, size_t elemSize) { +SArray* taosArrayInit(size_t size, size_t elemSize) { assert(elemSize > 0); if (size < TARRAY_MIN_SIZE) { diff --git a/source/util/src/terror.c b/source/util/src/terror.c index ceb344ffe8..70a3dc622f 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -127,8 +127,10 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DUP_TAG_NAMES, "duplicated tag names" TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON, "Invalid JSON format") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_JSON_TYPE, "Invalid JSON data type") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_VALUE_OUT_OF_RANGE, "Value out of range") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_INPUT, "Invalid tsc input") -// mnode +// mnode-common +TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_READY, "Cluster not ready") TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_IN_PROGRESS, "Message is progressing") TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACTION_NEED_REPROCESSED, "Message need to be reprocessed") @@ -139,7 +141,11 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_MSG_VERSION, "Incompatible protocol TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_MSG_LEN, "Invalid message length") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_MSG_TYPE, "Invalid message type") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_SHELL_CONNS, "Too many connections") + +// mnode-show TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_SHOWOBJ, "Data expired") + +// mnode-profile TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, "Invalid query id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, "Invalid stream id") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, "Invalid connection id") @@ -149,6 +155,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_START_SYNC, "failed to start sync" TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_CREATE_DIR, "failed to create mnode dir") TAOS_DEFINE_ERROR(TSDB_CODE_MND_FAILED_TO_INIT_STEP, "failed to init components") +// mnode-sdb TAOS_DEFINE_ERROR(TSDB_CODE_SDB_APP_ERROR, "Unexpected generic error in sdb") TAOS_DEFINE_ERROR(TSDB_CODE_SDB_OBJ_ALREADY_THERE, "Object already there") TAOS_DEFINE_ERROR(TSDB_CODE_SDB_OBJ_NOT_THERE, "Object not there") @@ -163,36 +170,50 @@ TAOS_DEFINE_ERROR(TSDB_CODE_SDB_INVALID_DATA_LEN, "Invalid raw data len" TAOS_DEFINE_ERROR(TSDB_CODE_SDB_INVALID_DATA_CONTENT, "Invalid raw data content") // mnode-dnode -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ALREADY_EXIST, "DNode already exists") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_EXIST, "DNode does not exist") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_DNODES, "Out of DNodes") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ALREADY_EXIST, "Dnode already exists") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_EXIST, "Dnode does not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DNODES, "Too many dnodes") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_DNODES, "Out of dnodes") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_CFG, "Cluster cfg inconsistent") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CLUSTER_ID, "Cluster id not match") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DNODE_CFG, "Invalid dnode cfg") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DNODE_EP, "Invalid dnode end point") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DNODE_ID, "Invalid dnode id") -// mnode-vgroup -TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, "VGroup does not exist") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_IN_DNODE, "Vgroup not in dnode") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE, "Vgroup already in dnode") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_READY, "Cluster not ready") +// mnode-mnode +TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_ALREADY_EXIST, "Mnode already exists") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_NOT_EXIST, "Mnode not there") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_MNODES, "Too many mnodes") // mnode-acct TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_ALREADY_EXIST, "Account already exists") TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_NOT_EXIST, "Invalid account") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_ACCTS, "Too many accounts") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ACCT_OPTION, "Invalid account options") TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_EXPIRED, "Account authorization has expired") +// mnode-user TAOS_DEFINE_ERROR(TSDB_CODE_MND_USER_ALREADY_EXIST, "User already exists") TAOS_DEFINE_ERROR(TSDB_CODE_MND_USER_NOT_EXIST, "Invalid user") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_USERS, "Too many users") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_USER_FORMAT, "Invalid user format") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_PASS_FORMAT, "Invalid password format") TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_USER_FROM_CONN, "Can not get user from conn") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_USERS, "Too many users") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_ALREADY_EXIST, "Mnode already exists") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_NOT_EXIST, "Mnode not there") +// mnode-db +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ALREADY_EXIST, "Database already exists") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_EXIST, "Database not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DATABASES, "Too many databases for account") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_SELECTED, "Database not specified or available") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB, "Invalid database name") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION, "Invalid database options") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_ACCT, "Invalid database account") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_OPTION_UNCHANGED, "Database options not changed") + +// mnode-vgroup +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE, "Vgroup already in dnode") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_IN_DNODE, "Vgroup not in dnode") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, "VGroup does not exist") // mnode-stable TAOS_DEFINE_ERROR(TSDB_CODE_MND_STB_ALREADY_EXIST, "Stable already exists") @@ -202,7 +223,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TABLE_TYPE, "Invalid table type in TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_TAGS, "Too many tags") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_COLUMNS, "Too many columns") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_TIMESERIES, "Too many time series") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_SUPER_TABLE, "Not super table") // operation only available for super table +TAOS_DEFINE_ERROR(TSDB_CODE_MND_NOT_SUPER_TABLE, "Not super table") TAOS_DEFINE_ERROR(TSDB_CODE_MND_COL_NAME_TOO_LONG, "Tag name too long") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TAG_ALREAY_EXIST, "Tag already exists") TAOS_DEFINE_ERROR(TSDB_CODE_MND_TAG_NOT_EXIST, "Tag does not exist") @@ -223,31 +244,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_FUNC_BUFSIZE, "Invalid func bufSize" TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_TAG_LENGTH, "invalid tag length") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_COLUMN_LENGTH, "invalid column length") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_SELECTED, "Database not specified or available") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_NOT_EXIST, "Database not exist") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ALREADY_EXIST, "Database already exists") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB, "Invalid database name") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION, "Invalid database options") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_CACHE_SIZE, "Invalid database cache block size option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_TOTAL_BLOCKS, "Invalid database total blocks option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_DAYS, "Invalid database days option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_KEEP0, "Invalid database keep0 option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_KEEP1, "Invalid database keep1 option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_KEEP2, "Invalid database keep2 option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_MIN_ROWS, "Invalid database min rows option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_MAX_ROWS, "Invalid database max rows option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_COMMIT_TIME, "Invalid database commit time option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_FSYNC_PERIOD, "Invalid database fsync periodoptions") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_WAL_LEVEL, "Invalid database wal level option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_PRECISION, "Invalid database precisin option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_COMP, "Invalid database compression option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_REPLICA, "Invalid database replication option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_QUORUM, "Invalid database quorum option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_UPDATE, "Invalid database update option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_CACHE_LAST, "Invalid database cache last option") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_OPTION_UNCHANGED, "Database options not changed") -TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DATABASES, "Too many databases for account") - // dnode TAOS_DEFINE_ERROR(TSDB_CODE_DND_ACTION_IN_PROGRESS, "Action in progress") TAOS_DEFINE_ERROR(TSDB_CODE_DND_EXITING, "Dnode is exiting") @@ -497,6 +493,15 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FS_FILE_ALREADY_EXISTS, "tfs file already exis TAOS_DEFINE_ERROR(TSDB_CODE_FS_INVLD_LEVEL, "tfs invalid level") TAOS_DEFINE_ERROR(TSDB_CODE_FS_NO_VALID_DISK, "tfs no valid disk") +// catalog +TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INTERNAL_ERROR, "catalog interval error") +TAOS_DEFINE_ERROR(TSDB_CODE_CTG_INVALID_INPUT, "invalid catalog input parameters") +TAOS_DEFINE_ERROR(TSDB_CODE_CTG_NOT_READY, "catalog is not ready") +TAOS_DEFINE_ERROR(TSDB_CODE_CTG_MEM_ERROR, "catalog memory error") +TAOS_DEFINE_ERROR(TSDB_CODE_CTG_SYS_ERROR, "catalog system error") + + + #ifdef TAOS_ERROR_C }; #endif @@ -545,4 +550,4 @@ const char* tstrerror(int32_t err) { return ""; } -const char* terrstr() { return tstrerror(terrno); } \ No newline at end of file +const char* terrstr() { return tstrerror(terrno); } diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index 24293fe9d3..23a923a315 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -81,15 +81,11 @@ int32_t writeInterval = DEFAULT_LOG_INTERVAL; // log int32_t tsNumOfLogLines = 10000000; int32_t mDebugFlag = 131; -int32_t sdbDebugFlag = 131; int32_t dDebugFlag = 135; int32_t vDebugFlag = 135; int32_t cDebugFlag = 131; int32_t jniDebugFlag = 131; int32_t odbcDebugFlag = 131; -int32_t httpDebugFlag = 131; -int32_t mqttDebugFlag = 131; -int32_t monDebugFlag = 131; int32_t qDebugFlag = 131; int32_t rpcDebugFlag = 131; int32_t uDebugFlag = 131; @@ -99,6 +95,8 @@ int32_t wDebugFlag = 135; int32_t tsdbDebugFlag = 131; int32_t cqDebugFlag = 131; int32_t fsDebugFlag = 135; +int32_t ctgDebugFlag = 131; + int64_t dbgEmptyW = 0; int64_t dbgWN = 0; diff --git a/src/balance/CMakeLists.txt b/src/balance/CMakeLists.txt deleted file mode 100644 index bffa415deb..0000000000 --- a/src/balance/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -PROJECT(TDengine) - -INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc) -INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/dnode/inc) -INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/tsdb/inc) -INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc) -INCLUDE_DIRECTORIES(inc) -AUX_SOURCE_DIRECTORY(src SRC) - -ADD_LIBRARY(balance ${SRC}) diff --git a/src/balance/inc/bnInt.h b/src/balance/inc/bnInt.h deleted file mode 100644 index e924776ff1..0000000000 --- a/src/balance/inc/bnInt.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_BALANCE_INT_H -#define TDENGINE_BALANCE_INT_H - -#ifdef __cplusplus -extern "C" { -#endif -#include "mnodeInt.h" -#include "mnodeDef.h" -#include "mnodeDnode.h" - -typedef struct { - int32_t size; - int32_t maxSize; - SDnodeObj **list; -} SBnDnodes; - -typedef struct { - void * timer; - bool stop; - pthread_mutex_t mutex; - pthread_cond_t cond; - pthread_t thread; -} SBnThread; - -typedef struct { - pthread_mutex_t mutex; -} SBnMgmt; - -int32_t bnInit(); -void bnCleanUp(); -bool bnStart(); -void bnCheckStatus(); -void bnCheckModules(); - -extern SBnDnodes tsBnDnodes; -extern void *tsMnodeTmr; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/balance/inc/bnScore.h b/src/balance/inc/bnScore.h deleted file mode 100644 index a28c4459dd..0000000000 --- a/src/balance/inc/bnScore.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_BALANCE_SCORE_H -#define TDENGINE_BALANCE_SCORE_H - -#ifdef __cplusplus -extern "C" { -#endif -#include "bnInt.h" - -void bnInitDnodes(); -void bnCleanupDnodes(); -void bnAccquireDnodes(); -void bnReleaseDnodes(); -float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extraVnode); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/balance/inc/bnThread.h b/src/balance/inc/bnThread.h deleted file mode 100644 index 74a761299d..0000000000 --- a/src/balance/inc/bnThread.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_BALANCE_THREAD_H -#define TDENGINE_BALANCE_THREAD_H - -#ifdef __cplusplus -extern "C" { -#endif -#include "bnInt.h" - -int32_t bnInitThread(); -void bnCleanupThread(); -void bnNotify(); -void bnStartTimer(int32_t mseconds); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/balance/src/bnMain.c b/src/balance/src/bnMain.c deleted file mode 100644 index 9997d44ca5..0000000000 --- a/src/balance/src/bnMain.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "tref.h" -#include "tsync.h" -#include "tglobal.h" -#include "dnode.h" -#include "bnInt.h" -#include "bnScore.h" -#include "bnThread.h" -#include "mnodeDb.h" -#include "mnodeMnode.h" -#include "mnodeSdb.h" -#include "mnodeShow.h" -#include "mnodeUser.h" -#include "mnodeVgroup.h" - -extern int64_t tsDnodeRid; -extern int32_t tsSdbRid; -static SBnMgmt tsBnMgmt; -static void bnMonitorDnodeModule(); - -static void bnLock() { - pthread_mutex_lock(&tsBnMgmt.mutex); -} - -static void bnUnLock() { - pthread_mutex_unlock(&tsBnMgmt.mutex); -} - -static bool bnCheckFree(SDnodeObj *pDnode) { - if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) { - mError("dnode:%d, status:%s not available", pDnode->dnodeId, dnodeStatus[pDnode->status]); - return false; - } - - if (pDnode->openVnodes >= TSDB_MAX_VNODES) { - mError("dnode:%d, openVnodes:%d maxVnodes:%d not available", pDnode->dnodeId, pDnode->openVnodes, TSDB_MAX_VNODES); - return false; - } - - if (pDnode->diskAvailable <= tsMinimalDataDirGB) { - mError("dnode:%d, disk space:%fGB, not available", pDnode->dnodeId, pDnode->diskAvailable); - return false; - } - - if (pDnode->alternativeRole == TAOS_DN_ALTERNATIVE_ROLE_MNODE) { - mDebug("dnode:%d, alternative role is master, can't alloc vnodes in this dnode", pDnode->dnodeId); - return false; - } - - return true; -} - -static void bnSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) { - SVnodeGid tmp = *pVnodeGid1; - *pVnodeGid1 = *pVnodeGid2; - *pVnodeGid2 = tmp; -} - -static void bnAdjustVnodeIndex(SVgObj *pInVg) { - int32_t d0Id = pInVg->vnodeGid[0].dnodeId; - int32_t d1Id = pInVg->vnodeGid[1].dnodeId; - int32_t d2Id = pInVg->vnodeGid[2].dnodeId; - - int32_t vgId = pInVg->vgId; - int32_t d0Num = 0; - int32_t d1Num = 0; - int32_t d2Num = 0; - - void *pIter = NULL; - while (1) { - SVgObj *pVgroup = NULL; - pIter = mnodeGetNextVgroup(pIter, &pVgroup); - if (pVgroup == NULL) break; - - if (pVgroup->vgId != vgId) { - if (pVgroup->vnodeGid[0].dnodeId == d0Id) d0Num++; - if (pVgroup->vnodeGid[0].dnodeId == d1Id) d1Num++; - if (pVgroup->vnodeGid[0].dnodeId == d2Id) d2Num++; - } - - mnodeDecVgroupRef(pVgroup); - } - - if (pInVg->numOfVnodes == 1) { - } - - if (pInVg->numOfVnodes == 2) { - mDebug("vgId:%d, dnode:%d num:%d dnode:%d num:%d", pInVg->vgId, d0Id, d0Num, d1Id, d1Num); - if (d0Num > d1Num) { - mDebug("vgId:%d, adjust vnode index 0 to 1", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[1]); - } - } - - if (pInVg->numOfVnodes >= 3) { - mDebug("vgId:%d, dnode:%d num:%d dnode:%d num:%d dnode:%d num:%d", pInVg->vgId, d0Id, d0Num, d1Id, d1Num, d2Id, d2Num); - if (d0Num <= d1Num && d0Num <= d2Num) { - if (d1Num > d2Num) { - mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]); - } - } else if (d1Num <= d2Num && d1Num <= d0Num) { - mDebug("vgId:%d, adjust vnode index 0 to 1", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[1]); - if (d0Num > d2Num) { - mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]); - } - } else { - mDebug("vgId:%d, adjust vnode index 0 to 2", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[0], &pInVg->vnodeGid[2]); - if (d1Num > d0Num) { - mDebug("vgId:%d, adjust vnode index 1 to 2", pInVg->vgId); - bnSwapVnodeGid(&pInVg->vnodeGid[1], &pInVg->vnodeGid[2]); - } - } - } - - for (int i = 0; i < pInVg->numOfVnodes; ++i) { - mDebug("vgId:%d index:%d dnodeId:%d", pInVg->vgId, i, pInVg->vnodeGid[i].dnodeId); - } -} - -static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) { - mDebug("vgId:%d, dnode:%d is dropping", pVgroup->vgId, pVnodeGid->dnodeId); - - SDnodeObj *pDnode = mnodeGetDnode(pVnodeGid->dnodeId); - if (pDnode != NULL) { - atomic_sub_fetch_32(&pDnode->openVnodes, 1); - mnodeDecDnodeRef(pDnode); - } - - SVnodeGid vnodeGid[TSDB_MAX_REPLICA]; memset(vnodeGid, 0, sizeof(vnodeGid)); /* = {0}; */ - int32_t numOfVnodes = 0; - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - SVnodeGid *pTmpVodeGid = pVgroup->vnodeGid + i; - if (pTmpVodeGid == pVnodeGid) { - continue; - } - vnodeGid[numOfVnodes] = *pTmpVodeGid; - ++numOfVnodes; - } - memcpy(pVgroup->vnodeGid, vnodeGid, TSDB_MAX_REPLICA * sizeof(SVnodeGid)); - pVgroup->numOfVnodes = numOfVnodes; - - bnAdjustVnodeIndex(pVgroup); - mnodeUpdateVgroup(pVgroup); -} - -int32_t bnAllocVnodes(SVgObj *pVgroup) { - int32_t dnode = 0; - int32_t vnodes = 0; - - bnLock(); - bnAccquireDnodes(); - - mDebug("db:%s, try alloc %d vnodes to vgroup, dnodes total:%d, avail:%d", pVgroup->dbName, pVgroup->numOfVnodes, - mnodeGetDnodesNum(), tsBnDnodes.size); - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - for (; dnode < tsBnDnodes.size; ++dnode) { - SDnodeObj *pDnode = tsBnDnodes.list[dnode]; - if (bnCheckFree(pDnode)) { - SVnodeGid *pVnodeGid = pVgroup->vnodeGid + i; - pVnodeGid->dnodeId = pDnode->dnodeId; - pVnodeGid->pDnode = pDnode; - dnode++; - vnodes++; - mDebug("dnode:%d, is selected, vnodeIndex:%d", pDnode->dnodeId, i); - break; - } else { - mDebug("dnode:%d, is not selected, status:%s vnodes:%d disk:%fGB role:%d", pDnode->dnodeId, - dnodeStatus[pDnode->status], pDnode->openVnodes, pDnode->diskAvailable, pDnode->alternativeRole); - } - } - } - - if (vnodes != pVgroup->numOfVnodes) { - bnReleaseDnodes(); - bnUnLock(); - - mDebug("db:%s, need vnodes:%d, but alloc:%d", pVgroup->dbName, pVgroup->numOfVnodes, vnodes); - - void * pIter = NULL; - SDnodeObj *pDnode = NULL; - while (1) { - pIter = mnodeGetNextDnode(pIter, &pDnode); - if (pDnode == NULL) break; - mDebug("dnode:%d, status:%s vnodes:%d disk:%fGB role:%d", pDnode->dnodeId, dnodeStatus[pDnode->status], - pDnode->openVnodes, pDnode->diskAvailable, pDnode->alternativeRole); - mnodeDecDnodeRef(pDnode); - } - - if (mnodeGetOnlineDnodesNum() == 0) { - return TSDB_CODE_MND_NOT_READY; - } else { - return TSDB_CODE_MND_NO_ENOUGH_DNODES; - } - } - - bnAdjustVnodeIndex(pVgroup); - bnReleaseDnodes(); - bnUnLock(); - return TSDB_CODE_SUCCESS; -} - -static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) { - int32_t rmVnodeVer = 0; - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - SVnodeGid *pVnode = pVgroup->vnodeGid + i; - if (pVnode == pRmVnode) { - rmVnodeVer = mnodeGetVgidVer(pVnode->vver); - mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d is watching", pVgroup->vgId, i, - pVnode->dnodeId, dnodeStatus[pVnode->pDnode->status], syncRole[pVnode->role], rmVnodeVer); - } - } - - bool isReady = false; - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - SVnodeGid *pVnode = pVgroup->vnodeGid + i; - SDnodeObj *pDnode = pVnode->pDnode; - if (pVnode == pRmVnode) continue; - int32_t vver = mnodeGetVgidVer(pVnode->vver); - - mTrace("vgId:%d, check vgroup status, vindex:%d dnode:%d status:%s role:%s vver:%d, rmvver:%d", pVgroup->vgId, i, - pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer); - if (pDnode->status == TAOS_DN_STATUS_DROPPING) continue; - if (pDnode->status == TAOS_DN_STATUS_OFFLINE) continue; - if (pVnode->role != TAOS_SYNC_ROLE_SLAVE && pVnode->role != TAOS_SYNC_ROLE_MASTER) continue; - - if (rmVnodeVer == 0 || vver >= rmVnodeVer) { - mInfo("vgId:%d, is ready for vindex:%d in dnode:%d status:%s role:%s vver:%d larger than rmvver:%d", - pVgroup->vgId, i, pVnode->dnodeId, dnodeStatus[pDnode->status], syncRole[pVnode->role], vver, rmVnodeVer); - isReady = true; - } - } - - return isReady; -} - -/** - * desc: remove one vnode from vgroup - * all vnodes in vgroup should in ready state, except the balancing one - **/ -static int32_t bnRemoveVnode(SVgObj *pVgroup) { - if (pVgroup->numOfVnodes <= 1) return -1; - - SVnodeGid *pSelVnode = &pVgroup->vnodeGid[pVgroup->numOfVnodes - 1]; - mDebug("vgId:%d, vnode in dnode:%d will be dropped", pVgroup->vgId, pSelVnode->dnodeId); - - if (!bnCheckVgroupReady(pVgroup, pSelVnode)) { - mDebug("vgId:%d, is not ready", pVgroup->vgId); - return -1; - } else { - mInfo("vgId:%d, is ready, discard dnode:%d", pVgroup->vgId, pSelVnode->dnodeId); - bnDiscardVnode(pVgroup, pSelVnode); - return TSDB_CODE_SUCCESS; - } -} - -static bool bnCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) { - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - SVnodeGid *pGid = &pVgroup->vnodeGid[i]; - if (pGid->dnodeId == 0) break; - if (pGid->dnodeId == pDnode->dnodeId) { - return true; - } - } - - return false; -} - -static SDnodeObj *bnGetAvailDnode(SVgObj *pVgroup) { - for (int32_t i = 0; i < tsBnDnodes.size; ++i) { - SDnodeObj *pDnode = tsBnDnodes.list[i]; - if (bnCheckDnodeInVgroup(pDnode, pVgroup)) continue; - if (!bnCheckFree(pDnode)) continue; - - mDebug("vgId:%d, add vnode to dnode:%d", pVgroup->vgId, pDnode->dnodeId); - return pDnode; - } - - return NULL; -} - -static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDestDnode) { - if (pDestDnode == NULL || pSrcDnode == pDestDnode) { - return TSDB_CODE_MND_DNODE_NOT_EXIST; - } - - SVnodeGid vnodeGids[TSDB_MAX_REPLICA]; - memcpy(&vnodeGids, &pVgroup->vnodeGid, sizeof(SVnodeGid) * TSDB_MAX_REPLICA); - - int32_t numOfVnodes = pVgroup->numOfVnodes; - vnodeGids[numOfVnodes].dnodeId = pDestDnode->dnodeId; - vnodeGids[numOfVnodes].pDnode = pDestDnode; - numOfVnodes++; - - // move the src vnode to the end - for (int32_t v = 0; v < numOfVnodes; ++v) { - if (pSrcDnode != NULL && pSrcDnode->dnodeId == vnodeGids[v].dnodeId) { - bnSwapVnodeGid(&vnodeGids[v], &vnodeGids[numOfVnodes - 1]); - pVgroup->lbDnodeId = pSrcDnode->dnodeId; - break; - } - } - - // adjust the vgroup postion - if (pSrcDnode == NULL) { - bnAdjustVnodeIndex(pVgroup); - } - - memcpy(&pVgroup->vnodeGid, &vnodeGids, sizeof(SVnodeGid) * TSDB_MAX_REPLICA); - pVgroup->numOfVnodes = numOfVnodes; - atomic_add_fetch_32(&pDestDnode->openVnodes, 1); - - mnodeUpdateVgroup(pVgroup); - - return TSDB_CODE_SUCCESS; -} - -static bool bnMonitorBalance() { - if (tsBnDnodes.size < 2) return false; - - mDebug("monitor dnodes for balance, avail:%d", tsBnDnodes.size); - for (int32_t src = tsBnDnodes.size - 1; src >= 0; --src) { - SDnodeObj *pDnode = tsBnDnodes.list[src]; - mDebug("%d-dnode:%d, state:%s, score:%.1f, cores:%d, vnodes:%d", tsBnDnodes.size - src - 1, pDnode->dnodeId, - dnodeStatus[pDnode->status], pDnode->score, pDnode->numOfCores, pDnode->openVnodes); - } - - float scoresDiff = tsBnDnodes.list[tsBnDnodes.size - 1]->score - tsBnDnodes.list[0]->score; - if (scoresDiff < 0.01) { - mDebug("all dnodes:%d is already balanced, scoreDiff:%.1f", tsBnDnodes.size, scoresDiff); - return false; - } - - for (int32_t src = tsBnDnodes.size - 1; src > 0; --src) { - SDnodeObj *pSrcDnode = tsBnDnodes.list[src]; - float srcScore = bnTryCalcDnodeScore(pSrcDnode, -1); - if (tsEnableBalance == 0 && pSrcDnode->status != TAOS_DN_STATUS_DROPPING) { - continue; - } - - void *pIter = NULL; - while (1) { - SVgObj *pVgroup; - pIter = mnodeGetNextVgroup(pIter, &pVgroup); - if (pVgroup == NULL) break; - - if (bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) { - for (int32_t dest = 0; dest < src; dest++) { - SDnodeObj *pDestDnode = tsBnDnodes.list[dest]; - if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) continue; - if (taosGetTimestampMs() - pDestDnode->createdTime < 2000) continue; - - float destScore = bnTryCalcDnodeScore(pDestDnode, 1); - if (srcScore + 0.0001 < destScore) continue; - if (!bnCheckFree(pDestDnode)) continue; - - mDebug("vgId:%d, balance from dnode:%d to dnode:%d, srcScore:%.1f:%.1f, destScore:%.1f:%.1f", - pVgroup->vgId, pSrcDnode->dnodeId, pDestDnode->dnodeId, pSrcDnode->score, - srcScore, pDestDnode->score, destScore); - bnAddVnode(pVgroup, pSrcDnode, pDestDnode); - mnodeDecVgroupRef(pVgroup); - mnodeCancelGetNextVgroup(pIter); - return true; - } - } - - mnodeDecVgroupRef(pVgroup); - } - } - - return false; -} - -// if mgmt changed to master -// 1. reset balanceAccessSquence to zero -// 2. reset state of dnodes to offline -// 3. reset lastAccess of dnodes to zero -void bnReset() { - void * pIter = NULL; - SDnodeObj *pDnode = NULL; - while (1) { - pIter = mnodeGetNextDnode(pIter, &pDnode); - if (pDnode == NULL) break; - - // while master change, should reset dnode to offline - mInfo("dnode:%d set access:%" PRId64 " to 0", pDnode->dnodeId, pDnode->lastAccess); - pDnode->lastAccess = 0; - if (pDnode->status != TAOS_DN_STATUS_DROPPING) { - pDnode->status = TAOS_DN_STATUS_OFFLINE; - pDnode->offlineReason = TAOS_DN_OFF_STATUS_NOT_RECEIVED; - } - - mnodeDecDnodeRef(pDnode); - } - - tsAccessSquence = 0; -} - -static bool bnMonitorVgroups() { - void * pIter = NULL; - SVgObj *pVgroup = NULL; - bool hasUpdatingVgroup = false; - - while (1) { - pIter = mnodeGetNextVgroup(pIter, &pVgroup); - if (pVgroup == NULL || pVgroup->pDb == NULL) break; - - int32_t dbReplica = pVgroup->pDb->cfg.replications; - int32_t vgReplica = pVgroup->numOfVnodes; - int32_t code = -1; - - if (vgReplica > dbReplica) { - mInfo("vgId:%d, replica:%d numOfVnodes:%d, try remove one vnode", pVgroup->vgId, dbReplica, vgReplica); - hasUpdatingVgroup = true; - code = bnRemoveVnode(pVgroup); - } else if (vgReplica < dbReplica) { - mInfo("vgId:%d, replica:%d numOfVnodes:%d, try add one vnode", pVgroup->vgId, dbReplica, vgReplica); - hasUpdatingVgroup = true; - - SDnodeObj *pAvailDnode = bnGetAvailDnode(pVgroup); - if (pAvailDnode == NULL) { - code = TSDB_CODE_MND_DNODE_NOT_EXIST; - } else { - code = bnAddVnode(pVgroup, NULL, pAvailDnode); - } - } - - mnodeDecVgroupRef(pVgroup); - if (code == TSDB_CODE_SUCCESS) { - mnodeCancelGetNextVgroup(pIter); - break; - } - } - - return hasUpdatingVgroup; -} - -static bool bnMonitorDnodeDropping(SDnodeObj *pDnode) { - mDebug("dnode:%d, in dropping state", pDnode->dnodeId); - - void * pIter = NULL; - bool hasThisDnode = false; - while (1) { - SVgObj *pVgroup = NULL; - pIter = mnodeGetNextVgroup(pIter, &pVgroup); - if (pVgroup == NULL) break; - - hasThisDnode = bnCheckDnodeInVgroup(pDnode, pVgroup); - mnodeDecVgroupRef(pVgroup); - - if (hasThisDnode) { - mnodeCancelGetNextVgroup(pIter); - break; - } - } - - if (!hasThisDnode) { - mInfo("dnode:%d, dropped for all vnodes are moving to other dnodes", pDnode->dnodeId); - mnodeDropDnode(pDnode, NULL); - return true; - } - - return false; -} - -static bool bnMontiorDropping() { - void *pIter = NULL; - SDnodeObj *pDnode = NULL; - - while (1) { - mnodeDecDnodeRef(pDnode); - pIter = mnodeGetNextDnode(pIter, &pDnode); - if (pDnode == NULL) break; - - if (pDnode->status == TAOS_DN_STATUS_OFFLINE) { - if (pDnode->lastAccess + tsOfflineThreshold > tsAccessSquence) continue; - if (dnodeIsMasterEp(pDnode->dnodeEp)) continue; - if (mnodeGetDnodesNum() <= 1) continue; - - mLInfo("dnode:%d, set to removing state for it offline:%" PRId64 " seconds", pDnode->dnodeId, - tsAccessSquence - pDnode->lastAccess); - - pDnode->status = TAOS_DN_STATUS_DROPPING; - mnodeUpdateDnode(pDnode); - mnodeDecDnodeRef(pDnode); - mnodeCancelGetNextDnode(pIter); - return true; - } - - if (pDnode->status == TAOS_DN_STATUS_DROPPING) { - bool ret = bnMonitorDnodeDropping(pDnode); - mnodeDecDnodeRef(pDnode); - mnodeCancelGetNextDnode(pIter); - return ret; - } - } - - return false; -} - -bool bnStart() { - if (!sdbIsMaster()) return false; - - bnLock(); - bnAccquireDnodes(); - - bnMonitorDnodeModule(); - - bool updateSoon = bnMontiorDropping(); - - if (!updateSoon) { - updateSoon = bnMonitorVgroups(); - } - - if (!updateSoon) { - updateSoon = bnMonitorBalance(); - } - - bnReleaseDnodes(); - bnUnLock(); - - return updateSoon; -} - -static void bnSetVgroupOffline(SDnodeObj* pDnode) { - void *pIter = NULL; - while (1) { - SVgObj *pVgroup; - pIter = mnodeGetNextVgroup(pIter, &pVgroup); - if (pVgroup == NULL) break; - - for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - if (pVgroup->vnodeGid[i].pDnode == pDnode) { - pVgroup->vnodeGid[i].role = TAOS_SYNC_ROLE_OFFLINE; - } - } - mnodeDecVgroupRef(pVgroup); - } -} - -void bnCheckStatus() { - void * pIter = NULL; - SDnodeObj *pDnode = NULL; - - void *dnodeSdb = taosAcquireRef(tsSdbRid, tsDnodeRid); - if (dnodeSdb == NULL) return; - - while (1) { - pIter = mnodeGetNextDnode(pIter, &pDnode); - if (pDnode == NULL) break; - if (tsAccessSquence - pDnode->lastAccess > 3) { - if (pDnode->status != TAOS_DN_STATUS_DROPPING && pDnode->status != TAOS_DN_STATUS_OFFLINE) { - pDnode->status = TAOS_DN_STATUS_OFFLINE; - pDnode->offlineReason = TAOS_DN_OFF_STATUS_MSG_TIMEOUT; - mInfo("dnode:%d, set to offline state, access seq:%" PRId64 " last seq:%" PRId64 " laststat:%d", pDnode->dnodeId, - tsAccessSquence, pDnode->lastAccess, pDnode->status); - bnSetVgroupOffline(pDnode); - bnStartTimer(3000); - } - } - mnodeDecDnodeRef(pDnode); - } - - taosReleaseRef(tsSdbRid, tsDnodeRid); -} - -void bnCheckModules() { - if (sdbIsMaster()) { - bnLock(); - bnAccquireDnodes(); - bnMonitorDnodeModule(); - bnReleaseDnodes(); - bnUnLock(); - } -} - -int32_t bnInit() { - pthread_mutex_init(&tsBnMgmt.mutex, NULL); - bnInitDnodes(); - bnInitThread(); - bnReset(); - - return 0; -} - -void bnCleanUp() { - bnCleanupThread(); - bnCleanupDnodes(); - pthread_mutex_destroy(&tsBnMgmt.mutex); -} - -int32_t bnDropDnode(SDnodeObj *pDnode) { - int32_t totalFreeVnodes = 0; - void * pIter = NULL; - SDnodeObj *pTempDnode = NULL; - - while (1) { - pIter = mnodeGetNextDnode(pIter, &pTempDnode); - if (pTempDnode == NULL) break; - - if (pTempDnode != pDnode && bnCheckFree(pTempDnode)) { - totalFreeVnodes += (TSDB_MAX_VNODES - pTempDnode->openVnodes); - } - - mnodeDecDnodeRef(pTempDnode); - } - - if (pDnode->openVnodes > totalFreeVnodes) { - mError("dnode:%d, openVnodes:%d totalFreeVnodes:%d no enough dnodes", pDnode->dnodeId, pDnode->openVnodes, totalFreeVnodes); - return TSDB_CODE_MND_NO_ENOUGH_DNODES; - } - - pDnode->status = TAOS_DN_STATUS_DROPPING; - mnodeUpdateDnode(pDnode); - - bnStartTimer(1100); - - return TSDB_CODE_SUCCESS; -} - -int32_t bnDnodeCanCreateMnode(struct SDnodeObj *pDnode) { - if (pDnode == NULL) - return 0; - - if (pDnode->isMgmt || pDnode->alternativeRole == TAOS_DN_ALTERNATIVE_ROLE_VNODE - || pDnode->status == TAOS_DN_STATUS_DROPPING - || pDnode->status == TAOS_DN_STATUS_OFFLINE) { - return 0; - } else { - return 1; - } -} - -static void bnMonitorDnodeModule() { - int32_t numOfMnodes = mnodeGetMnodesNum(); - if (numOfMnodes >= tsNumOfMnodes) return; - - for (int32_t i = 0; i < tsBnDnodes.size; ++i) { - SDnodeObj *pDnode = tsBnDnodes.list[i]; - if (pDnode == NULL) break; - - if (!bnDnodeCanCreateMnode(pDnode)) continue; - - mLInfo("dnode:%d, numOfMnodes:%d expect:%d, create mnode in this dnode", pDnode->dnodeId, numOfMnodes, tsNumOfMnodes); - mnodeCreateMnode(pDnode->dnodeId, pDnode->dnodeEp, true); - -#if 0 - // Only create one mnode each time - return; -#else - numOfMnodes = mnodeGetMnodesNum(); - if (numOfMnodes >= tsNumOfMnodes) return; -#endif - } -} - -int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnodeId) { - if (!sdbIsMaster()) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for self not master", pSrcDnode->dnodeId, vnodeId, dnodeId); - return TSDB_CODE_MND_DNODE_NOT_EXIST; - } - - if (tsEnableBalance != 0) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for balance enabled", pSrcDnode->dnodeId, vnodeId, dnodeId); - return TSDB_CODE_MND_BALANCE_ENABLED; - } - - SVgObj *pVgroup = mnodeGetVgroup(vnodeId); - if (pVgroup == NULL) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for vgroup not exist", pSrcDnode->dnodeId, vnodeId, dnodeId); - return TSDB_CODE_MND_VGROUP_NOT_EXIST; - } - - SDnodeObj *pDestDnode = mnodeGetDnode(dnodeId); - if (pDestDnode == NULL) { - mnodeDecVgroupRef(pVgroup); - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for dnode not exist", pSrcDnode->dnodeId, vnodeId, dnodeId); - return TSDB_CODE_MND_DNODE_NOT_EXIST; - } - - bnLock(); - bnAccquireDnodes(); - - int32_t code = TSDB_CODE_SUCCESS; - if (!bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup not in dnode:%d", pSrcDnode->dnodeId, vnodeId, - dnodeId, pSrcDnode->dnodeId); - code = TSDB_CODE_MND_VGROUP_NOT_IN_DNODE; - } else if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup already in dnode:%d", pSrcDnode->dnodeId, vnodeId, - dnodeId, dnodeId); - code = TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE; - } else if (!bnCheckFree(pDestDnode)) { - mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for dnode:%d not free", pSrcDnode->dnodeId, vnodeId, dnodeId, - dnodeId); - code = TSDB_CODE_MND_DNODE_NOT_FREE; - } else { - code = bnAddVnode(pVgroup, pSrcDnode, pDestDnode); - mInfo("dnode:%d, alter vgId:%d to dnode:%d, result:%s", pSrcDnode->dnodeId, vnodeId, dnodeId, tstrerror(code)); - } - - bnReleaseDnodes(); - bnUnLock(); - - mnodeDecVgroupRef(pVgroup); - mnodeDecDnodeRef(pDestDnode); - - return code; -} diff --git a/src/balance/src/bnScore.c b/src/balance/src/bnScore.c deleted file mode 100644 index 04a14357c9..0000000000 --- a/src/balance/src/bnScore.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "tglobal.h" -#include "mnodeShow.h" -#include "mnodeUser.h" -#include "bnScore.h" - -SBnDnodes tsBnDnodes; - -static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); -static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn); - -static int32_t bnCalcCpuScore(SDnodeObj *pDnode) { - if (pDnode->cpuAvgUsage < 80) - return 0; - else if (pDnode->cpuAvgUsage < 90) - return 10; - else - return 50; -} - -static int32_t bnCalcMemoryScore(SDnodeObj *pDnode) { - if (pDnode->memoryAvgUsage < 80) - return 0; - else if (pDnode->memoryAvgUsage < 90) - return 10; - else - return 50; -} - -static int32_t bnCalcDiskScore(SDnodeObj *pDnode) { - if (pDnode->diskAvgUsage < 80) - return 0; - else if (pDnode->diskAvgUsage < 90) - return 10; - else - return 50; -} - -static int32_t bnCalcBandScore(SDnodeObj *pDnode) { - if (pDnode->bandwidthUsage < 30) - return 0; - else if (pDnode->bandwidthUsage < 80) - return 10; - else - return 50; -} - -static float bnCalcModuleScore(SDnodeObj *pDnode) { - if (pDnode->numOfCores <= 0) return 0; - if (pDnode->isMgmt) { - return (float)tsMnodeEqualVnodeNum / pDnode->numOfCores; - } - return 0; -} - -static float bnCalcVnodeScore(SDnodeObj *pDnode, int32_t extra) { - if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) return 100000000; - if (pDnode->numOfCores <= 0) return 0; - return (float)(pDnode->openVnodes + extra) / pDnode->numOfCores; -} - -/** - * calc singe score, such as cpu/memory/disk/bandwitdh/vnode - * 1. get the score config - * 2. if the value is out of range, use border data - * 3. otherwise use interpolation method - **/ -static void bnCalcDnodeScore(SDnodeObj *pDnode) { - pDnode->score = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) + - bnCalcBandScore(pDnode) + bnCalcModuleScore(pDnode) + bnCalcVnodeScore(pDnode, 0) + - pDnode->customScore; -} - -float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extra) { - int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) + - bnCalcBandScore(pDnode); - float moduleScore = bnCalcModuleScore(pDnode); - float vnodeScore = bnCalcVnodeScore(pDnode, extra); - - float score = systemScore + moduleScore + vnodeScore + pDnode->customScore; - return score; -} - -void bnInitDnodes() { - mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_SCORES, bnGetScoresMeta); - mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_SCORES, bnRetrieveScores); - mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_SCORES, mnodeCancelGetNextDnode); - - memset(&tsBnDnodes, 0, sizeof(SBnDnodes)); - tsBnDnodes.maxSize = 16; - tsBnDnodes.list = calloc(tsBnDnodes.maxSize, sizeof(SDnodeObj *)); -} - -void bnCleanupDnodes() { - if (tsBnDnodes.list != NULL) { - free(tsBnDnodes.list); - tsBnDnodes.list = NULL; - } -} - -static void bnCheckDnodesSize(int32_t dnodesNum) { - if (tsBnDnodes.maxSize <= dnodesNum) { - int32_t maxSize = dnodesNum * 2; - SDnodeObj** list1 = NULL; - int32_t retry = 0; - - while(list1 == NULL && retry++ < 3) { - list1 = realloc(tsBnDnodes.list, maxSize * sizeof(SDnodeObj *)); - } - if(list1) { - tsBnDnodes.list = list1; - tsBnDnodes.maxSize = maxSize; - } - } -} - -void bnAccquireDnodes() { - int32_t dnodesNum = mnodeGetDnodesNum(); - bnCheckDnodesSize(dnodesNum); - - void * pIter = NULL; - SDnodeObj *pDnode = NULL; - int32_t dnodeIndex = 0; - - while (1) { - if (dnodeIndex >= dnodesNum) { - mnodeCancelGetNextDnode(pIter); - break; - } - - pIter = mnodeGetNextDnode(pIter, &pDnode); - if (pDnode == NULL) break; - if (pDnode->status == TAOS_DN_STATUS_OFFLINE) { - mnodeDecDnodeRef(pDnode); - continue; - } - - bnCalcDnodeScore(pDnode); - - int32_t orderIndex = dnodeIndex; - for (; orderIndex > 0; --orderIndex) { - if (pDnode->score > tsBnDnodes.list[orderIndex - 1]->score) { - break; - } - tsBnDnodes.list[orderIndex] = tsBnDnodes.list[orderIndex - 1]; - } - tsBnDnodes.list[orderIndex] = pDnode; - dnodeIndex++; - } - - tsBnDnodes.size = dnodeIndex; -} - -void bnReleaseDnodes() { - for (int32_t i = 0; i < tsBnDnodes.size; ++i) { - SDnodeObj *pDnode = tsBnDnodes.list[i]; - if (pDnode != NULL) { - mnodeDecDnodeRef(pDnode); - } - } -} - -static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { - SUserObj *pUser = mnodeGetUserFromConn(pConn); - if (pUser == NULL) return 0; - - if (strcmp(pUser->pAcct->user, "root") != 0) { - mnodeDecUserRef(pUser); - return TSDB_CODE_MND_NO_RIGHTS; - } - - int32_t cols = 0; - SSchema *pSchema = pMeta->schema; - - pShow->bytes[cols] = 2; - pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; - strcpy(pSchema[cols].name, "id"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_FLOAT; - strcpy(pSchema[cols].name, "system scores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_FLOAT; - strcpy(pSchema[cols].name, "custom scores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_FLOAT; - strcpy(pSchema[cols].name, "module scores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_FLOAT; - strcpy(pSchema[cols].name, "vnode scores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_FLOAT; - strcpy(pSchema[cols].name, "total scores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_INT; - strcpy(pSchema[cols].name, "open vnodes"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_INT; - strcpy(pSchema[cols].name, "cpu cores"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 18 + VARSTR_HEADER_SIZE; - pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "balance state"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pMeta->numOfColumns = htons(cols); - pShow->numOfColumns = cols; - - pShow->offset[0] = 0; - for (int32_t i = 1; i < cols; ++i) { - pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; - } - - pShow->numOfRows = mnodeGetDnodesNum(); - pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - pShow->pIter = NULL; - - mnodeDecUserRef(pUser); - - return 0; -} - -static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn) { - int32_t numOfRows = 0; - SDnodeObj *pDnode = NULL; - char * pWrite; - int32_t cols = 0; - - while (numOfRows < rows) { - pShow->pIter = mnodeGetNextDnode(pShow->pIter, &pDnode); - if (pDnode == NULL) break; - - int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) + bnCalcBandScore(pDnode); - float moduleScore = bnCalcModuleScore(pDnode); - float vnodeScore = bnCalcVnodeScore(pDnode, 0); - - cols = 0; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pDnode->dnodeId; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(float *)pWrite = (float)systemScore; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(float *)pWrite = (float)pDnode->customScore; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(float *)pWrite = (float)moduleScore; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(float *)pWrite = (float)vnodeScore; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(float *)pWrite = (float)(vnodeScore + moduleScore + pDnode->customScore + systemScore); - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int32_t *)pWrite = pDnode->openVnodes; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int32_t *)pWrite = pDnode->numOfCores; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - STR_TO_VARSTR(pWrite, dnodeStatus[pDnode->status]); - cols++; - - numOfRows++; - mnodeDecDnodeRef(pDnode); - } - - mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow); - pShow->numOfReads += numOfRows; - return numOfRows; -} diff --git a/src/balance/src/bnThread.c b/src/balance/src/bnThread.c deleted file mode 100644 index 20da83ccba..0000000000 --- a/src/balance/src/bnThread.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "ttimer.h" -#include "tglobal.h" -#include "mnodeSdb.h" -#include "bnThread.h" - -static SBnThread tsBnThread; - -static void *bnThreadFunc(void *arg) { - setThreadName("balance"); - - while (1) { - pthread_mutex_lock(&tsBnThread.mutex); - if (tsBnThread.stop) { - pthread_mutex_unlock(&tsBnThread.mutex); - break; - } - - pthread_cond_wait(&tsBnThread.cond, &tsBnThread.mutex); - mDebug("balance thread wakes up to work"); - bool updateSoon = bnStart(); - mDebug("balance thread finished this poll, updateSoon:%d", updateSoon); - - bnStartTimer(updateSoon ? 1000 : -1); - pthread_mutex_unlock(&(tsBnThread.mutex)); - } - - mDebug("balance thread is stopped"); - return NULL; -} - -int32_t bnInitThread() { - memset(&tsBnThread, 0, sizeof(SBnThread)); - tsBnThread.stop = false; - pthread_mutex_init(&tsBnThread.mutex, NULL); - pthread_cond_init(&tsBnThread.cond, NULL); - - pthread_attr_t thattr; - pthread_attr_init(&thattr); - pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); - int32_t ret = pthread_create(&tsBnThread.thread, &thattr, bnThreadFunc, NULL); - pthread_attr_destroy(&thattr); - - if (ret != 0) { - mError("failed to create balance thread since %s", strerror(ret)); - return -1; - } - - bnStartTimer(2000); - mDebug("balance thread is created"); - return 0; -} - -void bnCleanupThread() { - mDebug("balance thread will be cleanup"); - - if (tsBnThread.timer != NULL) { - taosTmrStopA(&tsBnThread.timer); - tsBnThread.timer = NULL; - mDebug("stop balance timer"); - } - - pthread_mutex_lock(&tsBnThread.mutex); - tsBnThread.stop = true; - pthread_cond_signal(&tsBnThread.cond); - pthread_mutex_unlock(&(tsBnThread.mutex)); - pthread_join(tsBnThread.thread, NULL); - - pthread_cond_destroy(&tsBnThread.cond); - pthread_mutex_destroy(&tsBnThread.mutex); -} - -static void bnPostSignal() { - if (tsBnThread.stop) return; - - pthread_mutex_lock(&tsBnThread.mutex); - pthread_cond_signal(&tsBnThread.cond); - pthread_mutex_unlock(&(tsBnThread.mutex)); -} - -/* - * once sdb work as mater, then tsAccessSquence reset to zero - * increase tsAccessSquence every balance interval - */ - -static void bnProcessTimer(void *handle, void *tmrId) { - if (!sdbIsMaster()) return; - if (tsBnThread.stop) return; - - tsBnThread.timer = NULL; - bnStartTimer(-1); - bnCheckStatus(); - - if (handle == NULL) { - ++tsAccessSquence; - - if (tsAccessSquence % tsBalanceInterval == 0) { - mDebug("balance function is scheduled by timer"); - bnPostSignal(); - } - } else { - int64_t mseconds = (int64_t)handle; - mDebug("balance function is scheduled by event for %" PRId64 " mseconds arrived", mseconds); - bnPostSignal(); - } -} - -void bnStartTimer(int32_t mseconds) { - if (tsBnThread.stop) return; - - if (mseconds != -1) { - mTrace("balance function will be called after %d ms", mseconds); - taosTmrReset(bnProcessTimer, mseconds, (void *)(int64_t)mseconds, tsMnodeTmr, &tsBnThread.timer); - } else { - taosTmrReset(bnProcessTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBnThread.timer); - } -} - -void bnNotify() { - bnStartTimer(500); -} diff --git a/src/inc/http.h b/src/inc/http.h deleted file mode 100644 index 0d4c386cbf..0000000000 --- a/src/inc/http.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_HTTP_H -#define TDENGINE_HTTP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -int32_t httpGetReqCount(); -int32_t httpInitSystem(); -int32_t httpStartSystem(); -void httpStopSystem(); -void httpCleanUpSystem(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/monitor.h b/src/inc/monitor.h deleted file mode 100644 index d2e5e06487..0000000000 --- a/src/inc/monitor.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_MONITOR_H -#define TDENGINE_MONITOR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef struct { - char * acctId; - int64_t currentPointsPerSecond; - int64_t maxPointsPerSecond; - int64_t totalTimeSeries; - int64_t maxTimeSeries; - int64_t totalStorage; - int64_t maxStorage; - int64_t totalQueryTime; - int64_t maxQueryTime; - int64_t totalInbound; - int64_t maxInbound; - int64_t totalOutbound; - int64_t maxOutbound; - int64_t totalDbs; - int64_t maxDbs; - int64_t totalUsers; - int64_t maxUsers; - int64_t totalStreams; - int64_t maxStreams; - int64_t totalConns; - int64_t maxConns; - int8_t accessState; -} SAcctMonitorObj; - -int32_t monInitSystem(); -int32_t monStartSystem(); -void monStopSystem(); -void monCleanupSystem(); -void monSaveAcctLog(SAcctMonitorObj *pMonObj); -void monSaveLog(int32_t level, const char *const format, ...); -void monExecuteSQL(char *sql); -typedef void (*MonExecuteSQLCbFP)(void *param, TAOS_RES *, int code); -void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/tacct.h b/src/inc/tacct.h deleted file mode 100644 index 52215fac52..0000000000 --- a/src/inc/tacct.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_ACCT_H -#define TDENGINE_ACCT_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - ACCT_GRANT_USER, - ACCT_GRANT_DB, - ACCT_GRANT_TABLE -} EAcctGrantType; - -int32_t acctInit(); -void acctCleanUp(); -int32_t acctCheck(void *pAcct, EAcctGrantType type); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/tbn.h b/src/inc/tbn.h deleted file mode 100644 index b35f90eb15..0000000000 --- a/src/inc/tbn.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_BALANCE_H -#define TDENGINE_BALANCE_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct SVgObj; -struct SDnodeObj; - -int32_t bnInit(); -void bnCleanUp(); -void bnNotify(); -void bnCheckModules(); -void bnReset(); -int32_t bnAllocVnodes(struct SVgObj *pVgroup); -int32_t bnAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId); -int32_t bnDropDnode(struct SDnodeObj *pDnode); -int32_t bnDnodeCanCreateMnode(struct SDnodeObj *pDnode); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/tgrant.h b/src/inc/tgrant.h deleted file mode 100644 index f62a521b6c..0000000000 --- a/src/inc/tgrant.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_GTANT_H -#define TDENGINE_GTANT_H - -#ifdef __cplusplus -"C" { -#endif - -typedef enum { - TSDB_GRANT_ALL, - TSDB_GRANT_TIME, - TSDB_GRANT_USER, - TSDB_GRANT_DB, - TSDB_GRANT_TIMESERIES, - TSDB_GRANT_DNODE, - TSDB_GRANT_ACCT, - TSDB_GRANT_STORAGE, - TSDB_GRANT_SPEED, - TSDB_GRANT_QUERY_TIME, - TSDB_GRANT_CONNS, - TSDB_GRANT_STREAMS, - TSDB_GRANT_CPU_CORES, -} EGrantType; - -int32_t grantInit(); -void grantCleanUp(); -void grantParseParameter(); -int32_t grantCheck(EGrantType grant); -void grantReset(EGrantType grant, uint64_t value); -void grantAdd(EGrantType grant, uint64_t value); -void grantRestore(EGrantType grant, uint64_t value); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/tmqtt.h b/src/inc/tmqtt.h deleted file mode 100644 index 256e61fbae..0000000000 --- a/src/inc/tmqtt.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_MQTT_H -#define TDENGINE_MQTT_H - -#ifdef __cplusplus -extern "C" { -#endif - -int32_t mqttInitSystem(); -int32_t mqttStartSystem(); -void mqttStopSystem(); -void mqttCleanUpSystem(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/inc/tsync.h b/src/inc/tsync.h deleted file mode 100644 index d1b68e3f5a..0000000000 --- a/src/inc/tsync.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef TDENGINE_SYNC_H -#define TDENGINE_SYNC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define TAOS_SYNC_MAX_REPLICA 5 -#define TAOS_SYNC_MAX_INDEX 0x7FFFFFFF - -typedef enum { - TAOS_SYNC_ROLE_OFFLINE = 0, - TAOS_SYNC_ROLE_UNSYNCED = 1, - TAOS_SYNC_ROLE_SYNCING = 2, - TAOS_SYNC_ROLE_SLAVE = 3, - TAOS_SYNC_ROLE_MASTER = 4 -} ESyncRole; - -typedef enum { - TAOS_SYNC_STATUS_INIT = 0, - TAOS_SYNC_STATUS_START = 1, - TAOS_SYNC_STATUS_FILE = 2, - TAOS_SYNC_STATUS_CACHE = 3 -} ESyncStatus; - -typedef struct { - uint32_t nodeId; // node ID assigned by TDengine - uint16_t nodePort; // node sync Port - char nodeFqdn[TSDB_FQDN_LEN]; // node FQDN -} SNodeInfo; - -typedef struct { - int8_t quorum; // number of confirms required, >=1 - int8_t replica; // number of replications, >=1 - SNodeInfo nodeInfo[TAOS_SYNC_MAX_REPLICA]; -} SSyncCfg; - -typedef struct { - int32_t selfIndex; - uint32_t nodeId[TAOS_SYNC_MAX_REPLICA]; - int32_t role[TAOS_SYNC_MAX_REPLICA]; -} SNodesRole; - -// get the wal file from index or after -// return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file -typedef int32_t (*FGetWalInfo)(int32_t vgId, char *fileName, int64_t *fileId); - -// when a forward pkt is received, call this to handle data -typedef int32_t (*FWriteToCache)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg); - -// when forward is confirmed by peer, master call this API to notify app -typedef void (*FConfirmForward)(int32_t vgId, void *mhandle, int32_t code); - -// when role is changed, call this to notify app -typedef void (*FNotifyRole)(int32_t vgId, int8_t role); - -// if a number of retrieving data failed, call this to start flow control -typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t level); - -// when data file is synced successfully, notity app -typedef void (*FStartSyncFile)(int32_t vgId); -typedef void (*FStopSyncFile)(int32_t vgId, uint64_t fversion); - -// get file version -typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver); - -typedef int32_t (*FSendFile)(void *tsdb, SOCKET socketFd); -typedef int32_t (*FRecvFile)(void *tsdb, SOCKET socketFd); - -typedef struct { - int32_t vgId; // vgroup ID - uint64_t version; // initial version - SSyncCfg syncCfg; // configuration from mgmt - char path[TSDB_FILENAME_LEN]; // path to the file - void * pTsdb; - FGetWalInfo getWalInfoFp; - FWriteToCache writeToCacheFp; - FConfirmForward confirmForward; - FNotifyRole notifyRoleFp; - FNotifyFlowCtrl notifyFlowCtrlFp; - FStartSyncFile startSyncFileFp; - FStopSyncFile stopSyncFileFp; - FGetVersion getVersionFp; - FSendFile sendFileFp; - FRecvFile recvFileFp; -} SSyncInfo; - -typedef void *tsync_h; - -int32_t syncInit(); -void syncCleanUp(); - -int64_t syncStart(const SSyncInfo *); -void syncStop(int64_t rid); -int32_t syncReconfig(int64_t rid, const SSyncCfg *); -int32_t syncForwardToPeer(int64_t rid, void *pHead, void *mhandle, int32_t qtype, bool force); -void syncConfirmForward(int64_t rid, uint64_t version, int32_t code, bool force); -void syncRecover(int64_t rid); // recover from other nodes: -int32_t syncGetNodesRole(int64_t rid, SNodesRole *); - -extern char *syncRole[]; - -//global configurable parameters -extern int32_t sDebugFlag; -extern char tsArbitrator[]; -extern uint16_t tsSyncPort; - -#ifdef __cplusplus -} -#endif - -#endif // TDENGINE_SYNC_H diff --git a/src/plugins/monitor/CMakeLists.txt b/src/plugins/monitor/CMakeLists.txt deleted file mode 100644 index 8a05d63e14..0000000000 --- a/src/plugins/monitor/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -PROJECT(TDengine) - -INCLUDE_DIRECTORIES(inc) -INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) -INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) -AUX_SOURCE_DIRECTORY(./src SRC) - -ADD_LIBRARY(monitor ${SRC}) - -IF (TD_SOMODE_STATIC) - TARGET_LINK_LIBRARIES(monitor taos_static) -ELSE () - TARGET_LINK_LIBRARIES(monitor taos) -ENDIF () diff --git a/src/plugins/monitor/src/monMain.c b/src/plugins/monitor/src/monMain.c deleted file mode 100644 index fea793fa86..0000000000 --- a/src/plugins/monitor/src/monMain.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "taosdef.h" -#include "taoserror.h" -#include "tlog.h" -#include "ttimer.h" -#include "tutil.h" -#include "tscUtil.h" -#include "tsclient.h" -#include "dnode.h" -#include "monitor.h" -#include "taoserror.h" - -#define monFatal(...) { if (monDebugFlag & DEBUG_FATAL) { taosPrintLog("MON FATAL ", 255, __VA_ARGS__); }} -#define monError(...) { if (monDebugFlag & DEBUG_ERROR) { taosPrintLog("MON ERROR ", 255, __VA_ARGS__); }} -#define monWarn(...) { if (monDebugFlag & DEBUG_WARN) { taosPrintLog("MON WARN ", 255, __VA_ARGS__); }} -#define monInfo(...) { if (monDebugFlag & DEBUG_INFO) { taosPrintLog("MON ", 255, __VA_ARGS__); }} -#define monDebug(...) { if (monDebugFlag & DEBUG_DEBUG) { taosPrintLog("MON ", monDebugFlag, __VA_ARGS__); }} -#define monTrace(...) { if (monDebugFlag & DEBUG_TRACE) { taosPrintLog("MON ", monDebugFlag, __VA_ARGS__); }} - -#define SQL_LENGTH 1030 -#define LOG_LEN_STR 512 -#define IP_LEN_STR TSDB_EP_LEN -#define CHECK_INTERVAL 1000 - -typedef enum { - MON_CMD_CREATE_DB, - MON_CMD_CREATE_TB_LOG, - MON_CMD_CREATE_MT_DN, - MON_CMD_CREATE_MT_ACCT, - MON_CMD_CREATE_TB_DN, - MON_CMD_CREATE_TB_ACCT_ROOT, - MON_CMD_CREATE_TB_SLOWQUERY, - MON_CMD_MAX -} EMonCmd; - -typedef enum { - MON_STATE_NOT_INIT, - MON_STATE_INITED -} EMonState; - -typedef struct { - pthread_t thread; - void * conn; - char ep[TSDB_EP_LEN]; - int8_t cmdIndex; - int8_t state; - int8_t start; // enable/disable by mnode - int8_t quiting; // taosd is quiting - char sql[SQL_LENGTH + 1]; -} SMonConn; - -static SMonConn tsMonitor = {0}; -static void monSaveSystemInfo(); -static void *monThreadFunc(void *param); -static void monBuildMonitorSql(char *sql, int32_t cmd); -extern int32_t (*monStartSystemFp)(); -extern void (*monStopSystemFp)(); -extern void (*monExecuteSQLFp)(char *sql); - -int32_t monInitSystem() { - if (tsMonitor.ep[0] == 0) { - strcpy(tsMonitor.ep, tsLocalEp); - } - - int32_t len = (int32_t)strlen(tsMonitor.ep); - for (int32_t i = 0; i < len; ++i) { - if (tsMonitor.ep[i] == ':' || tsMonitor.ep[i] == '-' || tsMonitor.ep[i] == '.') { - tsMonitor.ep[i] = '_'; - } - } - - pthread_attr_t thAttr; - pthread_attr_init(&thAttr); - pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE); - - if (pthread_create(&tsMonitor.thread, &thAttr, monThreadFunc, NULL)) { - monError("failed to create thread to for monitor module, reason:%s", strerror(errno)); - return -1; - } - - pthread_attr_destroy(&thAttr); - monDebug("monitor thread is launched"); - - monStartSystemFp = monStartSystem; - monStopSystemFp = monStopSystem; - return 0; -} - -int32_t monStartSystem() { - if (taos_init()) { - return -1; - } - tsMonitor.start = 1; - monExecuteSQLFp = monExecuteSQL; - monInfo("monitor module start"); - return 0; -} - -static void *monThreadFunc(void *param) { - monDebug("starting to initialize monitor module ..."); - setThreadName("monitor"); - - while (1) { - static int32_t accessTimes = 0; - accessTimes++; - taosMsleep(1000); - - if (tsMonitor.quiting) { - tsMonitor.state = MON_STATE_NOT_INIT; - monInfo("monitor thread will quit, for taosd is quiting"); - break; - } else { - taosGetDisk(); - } - - if (tsMonitor.start == 0) { - continue; - } - - if (dnodeGetDnodeId() <= 0) { - monDebug("dnode not initialized, waiting for 3000 ms to start monitor module"); - continue; - } - - if (tsMonitor.conn == NULL) { - tsMonitor.state = MON_STATE_NOT_INIT; - tsMonitor.conn = taos_connect(NULL, "monitor", tsInternalPass, "", 0); - if (tsMonitor.conn == NULL) { - monError("failed to connect to database, reason:%s", tstrerror(terrno)); - continue; - } else { - monDebug("connect to database success"); - } - } - - if (tsMonitor.state == MON_STATE_NOT_INIT) { - int32_t code = 0; - - for (; tsMonitor.cmdIndex < MON_CMD_MAX; ++tsMonitor.cmdIndex) { - monBuildMonitorSql(tsMonitor.sql, tsMonitor.cmdIndex); - void *res = taos_query(tsMonitor.conn, tsMonitor.sql); - code = taos_errno(res); - taos_free_result(res); - - if (code != 0) { - monError("failed to exec sql:%s, reason:%s", tsMonitor.sql, tstrerror(code)); - break; - } else { - monDebug("successfully to exec sql:%s", tsMonitor.sql); - } - } - - if (tsMonitor.start && code == 0) { - tsMonitor.state = MON_STATE_INITED; - } - } - - if (tsMonitor.state == MON_STATE_INITED) { - if (accessTimes % tsMonitorInterval == 0) { - monSaveSystemInfo(); - } - } - } - - monInfo("monitor thread is stopped"); - return NULL; -} - -static void monBuildMonitorSql(char *sql, int32_t cmd) { - memset(sql, 0, SQL_LENGTH); - -#ifdef _STORAGE - char *keepValue = "30,30,30"; -#else - char *keepValue = "30"; -#endif - - if (cmd == MON_CMD_CREATE_DB) { - snprintf(sql, SQL_LENGTH, - "create database if not exists %s replica 1 days 10 keep %s cache %d " - "blocks %d precision 'us'", - tsMonitorDbName, keepValue, TSDB_MIN_CACHE_BLOCK_SIZE, TSDB_MIN_TOTAL_BLOCKS); - } else if (cmd == MON_CMD_CREATE_MT_DN) { - snprintf(sql, SQL_LENGTH, - "create table if not exists %s.dn(ts timestamp" - ", cpu_taosd float, cpu_system float, cpu_cores int" - ", mem_taosd float, mem_system float, mem_total int" - ", disk_used float, disk_total int" - ", band_speed float" - ", io_read float, io_write float" - ", req_http int, req_select int, req_insert int" - ") tags (dnodeid int, fqdn binary(%d))", - tsMonitorDbName, TSDB_FQDN_LEN); - } else if (cmd == MON_CMD_CREATE_TB_DN) { - snprintf(sql, SQL_LENGTH, "create table if not exists %s.dn%d using %s.dn tags(%d, '%s')", tsMonitorDbName, - dnodeGetDnodeId(), tsMonitorDbName, dnodeGetDnodeId(), tsLocalEp); - } else if (cmd == MON_CMD_CREATE_MT_ACCT) { - snprintf(sql, SQL_LENGTH, - "create table if not exists %s.acct(ts timestamp " - ", currentPointsPerSecond bigint, maxPointsPerSecond bigint" - ", totalTimeSeries bigint, maxTimeSeries bigint" - ", totalStorage bigint, maxStorage bigint" - ", totalQueryTime bigint, maxQueryTime bigint" - ", totalInbound bigint, maxInbound bigint" - ", totalOutbound bigint, maxOutbound bigint" - ", totalDbs smallint, maxDbs smallint" - ", totalUsers smallint, maxUsers smallint" - ", totalStreams smallint, maxStreams smallint" - ", totalConns smallint, maxConns smallint" - ", accessState smallint" - ") tags (acctId binary(%d))", - tsMonitorDbName, TSDB_USER_LEN); - } else if (cmd == MON_CMD_CREATE_TB_ACCT_ROOT) { - snprintf(sql, SQL_LENGTH, "create table if not exists %s.acct_%s using %s.acct tags('%s')", tsMonitorDbName, TSDB_DEFAULT_USER, - tsMonitorDbName, TSDB_DEFAULT_USER); - } else if (cmd == MON_CMD_CREATE_TB_SLOWQUERY) { - snprintf(sql, SQL_LENGTH, - "create table if not exists %s.slowquery(ts timestamp, username " - "binary(%d), created_time timestamp, time bigint, sql binary(%d))", - tsMonitorDbName, TSDB_TABLE_FNAME_LEN - 1, TSDB_SLOW_QUERY_SQL_LEN); - } else if (cmd == MON_CMD_CREATE_TB_LOG) { - snprintf(sql, SQL_LENGTH, - "create table if not exists %s.log(ts timestamp, level tinyint, " - "content binary(%d), ipaddr binary(%d))", - tsMonitorDbName, LOG_LEN_STR, IP_LEN_STR); - } - - sql[SQL_LENGTH] = 0; -} - -void monStopSystem() { - tsMonitor.start = 0; - tsMonitor.state = MON_STATE_NOT_INIT; - monExecuteSQLFp = NULL; - monInfo("monitor module stopped"); -} - -void monCleanupSystem() { - tsMonitor.quiting = 1; - monStopSystem(); - if (taosCheckPthreadValid(tsMonitor.thread)) { - pthread_join(tsMonitor.thread, NULL); - } - - if (tsMonitor.conn != NULL) { - taos_close(tsMonitor.conn); - tsMonitor.conn = NULL; - } - monInfo("monitor module is cleaned up"); -} - -// unit is MB -static int32_t monBuildMemorySql(char *sql) { - float sysMemoryUsedMB = 0; - bool suc = taosGetSysMemory(&sysMemoryUsedMB); - if (!suc) { - monDebug("failed to get sys memory info"); - } - - float procMemoryUsedMB = 0; - suc = taosGetProcMemory(&procMemoryUsedMB); - if (!suc) { - monDebug("failed to get proc memory info"); - } - - return sprintf(sql, ", %f, %f, %d", procMemoryUsedMB, sysMemoryUsedMB, tsTotalMemoryMB); -} - -// unit is % -static int32_t monBuildCpuSql(char *sql) { - float sysCpuUsage = 0, procCpuUsage = 0; - bool suc = taosGetCpuUsage(&sysCpuUsage, &procCpuUsage); - if (!suc) { - monDebug("failed to get cpu usage"); - } - - if (sysCpuUsage <= procCpuUsage) { - sysCpuUsage = procCpuUsage + 0.1f; - } - - return sprintf(sql, ", %f, %f, %d", procCpuUsage, sysCpuUsage, tsNumOfCores); -} - -// unit is GB -static int32_t monBuildDiskSql(char *sql) { - return sprintf(sql, ", %f, %d", tsUsedDataDirGB, (int32_t)tsTotalDataDirGB); -} - -// unit is Kb -static int32_t monBuildBandSql(char *sql) { - float bandSpeedKb = 0; - bool suc = taosGetBandSpeed(&bandSpeedKb); - if (!suc) { - monDebug("failed to get bandwidth speed"); - } - - return sprintf(sql, ", %f", bandSpeedKb); -} - -static int32_t monBuildReqSql(char *sql) { - SStatisInfo info = dnodeGetStatisInfo(); - return sprintf(sql, ", %d, %d, %d)", info.httpReqNum, info.queryReqNum, info.submitReqNum); -} - -static int32_t monBuildIoSql(char *sql) { - float readKB = 0, writeKB = 0; - bool suc = taosGetProcIO(&readKB, &writeKB); - if (!suc) { - monDebug("failed to get io info"); - } - - return sprintf(sql, ", %f, %f", readKB, writeKB); -} - -static void monSaveSystemInfo() { - int64_t ts = taosGetTimestampUs(); - char * sql = tsMonitor.sql; - int32_t pos = snprintf(sql, SQL_LENGTH, "insert into %s.dn%d values(%" PRId64, tsMonitorDbName, dnodeGetDnodeId(), ts); - - pos += monBuildCpuSql(sql + pos); - pos += monBuildMemorySql(sql + pos); - pos += monBuildDiskSql(sql + pos); - pos += monBuildBandSql(sql + pos); - pos += monBuildIoSql(sql + pos); - pos += monBuildReqSql(sql + pos); - - void *res = taos_query(tsMonitor.conn, tsMonitor.sql); - int32_t code = taos_errno(res); - taos_free_result(res); - - if (code != 0) { - monError("failed to save system info, reason:%s, sql:%s", tstrerror(code), tsMonitor.sql); - } else { - monDebug("successfully to save system info, sql:%s", tsMonitor.sql); - } -} - -static void monExecSqlCb(void *param, TAOS_RES *result, int32_t code) { - int32_t c = taos_errno(result); - if (c != TSDB_CODE_SUCCESS) { - monError("save %s failed, reason:%s", (char *)param, tstrerror(c)); - } else { - int32_t rows = taos_affected_rows(result); - monDebug("save %s succ, rows:%d", (char *)param, rows); - } - - taos_free_result(result); -} - -void monSaveAcctLog(SAcctMonitorObj *pMon) { - if (tsMonitor.state != MON_STATE_INITED) return; - - char sql[1024] = {0}; - sprintf(sql, - "insert into %s.acct_%s using %s.acct tags('%s') values(now" - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %" PRId64 ", %" PRId64 - ", %d)", - tsMonitorDbName, pMon->acctId, tsMonitorDbName, pMon->acctId, - pMon->currentPointsPerSecond, pMon->maxPointsPerSecond, - pMon->totalTimeSeries, pMon->maxTimeSeries, - pMon->totalStorage, pMon->maxStorage, - pMon->totalQueryTime, pMon->maxQueryTime, - pMon->totalInbound, pMon->maxInbound, - pMon->totalOutbound, pMon->maxOutbound, - pMon->totalDbs, pMon->maxDbs, - pMon->totalUsers, pMon->maxUsers, - pMon->totalStreams, pMon->maxStreams, - pMon->totalConns, pMon->maxConns, - pMon->accessState); - - monDebug("save account info, sql:%s", sql); - taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "account info"); -} - -void monSaveLog(int32_t level, const char *const format, ...) { - if (tsMonitor.state != MON_STATE_INITED) return; - - va_list argpointer; - char sql[SQL_LENGTH] = {0}; - int32_t max_length = SQL_LENGTH - 30; - int32_t len = snprintf(sql, (size_t)max_length, "insert into %s.log values(%" PRId64 ", %d,'", tsMonitorDbName, - taosGetTimestampUs(), level); - - va_start(argpointer, format); - len += vsnprintf(sql + len, (size_t)(max_length - len), format, argpointer); - va_end(argpointer); - if (len > max_length) len = max_length; - - len += sprintf(sql + len, "', '%s')", tsLocalEp); - sql[len++] = 0; - - monDebug("save log, sql: %s", sql); - taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "log"); -} - -void monExecuteSQL(char *sql) { - if (tsMonitor.state != MON_STATE_INITED) return; - - monDebug("execute sql:%s", sql); - taos_query_a(tsMonitor.conn, sql, monExecSqlCb, "sql"); -} - -void monExecuteSQLWithResultCallback(char *sql, MonExecuteSQLCbFP callback, void* param) { - if (tsMonitor.conn == NULL) { - callback(param, NULL, TSDB_CODE_MON_CONNECTION_INVALID); - return; - } - - monDebug("execute sql:%s", sql); - taos_query_a(tsMonitor.conn, sql, callback, param); -} diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 4627377a8e..85f961b829 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -5142,22 +5142,22 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* assert(repeatTime > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pQueryHandle = pTsdbQueryHandle; - pInfo->times = repeatTime; - pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQueryAttr->order.order; - pInfo->current = 0; + pInfo->pQueryHandle = pTsdbQueryHandle; + pInfo->times = repeatTime; + pInfo->reverseTimes = 0; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; + pInfo->current = 0; // pInfo->prevGroupId = -1; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "TableScanOperator"; - pOperator->operatorType = OP_TableScan; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->exec = doTableScan; + pOperator->name = "TableScanOperator"; + pOperator->operatorType = OP_TableScan; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = doTableScan; return pOperator; } @@ -5174,14 +5174,14 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE pRuntimeEnv->enableGroupData = true; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "TableSeqScanOperator"; - pOperator->operatorType = OP_TableSeqScan; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->exec = doTableScanImpl; + pOperator->name = "TableSeqScanOperator"; + pOperator->operatorType = OP_TableSeqScan; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = doTableScanImpl; return pOperator; } @@ -5199,14 +5199,14 @@ SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRu taosArrayPush(pInfo->block.pDataBlock, &infoData); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "TableBlockInfoScanOperator"; - pOperator->operatorType = OP_TableBlockInfoScan; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; - pOperator->exec = doBlockInfoScan; + pOperator->name = "TableBlockInfoScanOperator"; + pOperator->operatorType = OP_TableBlockInfoScan; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; + pOperator->exec = doBlockInfoScan; return pOperator; } @@ -5271,11 +5271,11 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntime assert(repeatTime > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); - pInfo->pQueryHandle = pTsdbQueryHandle; - pInfo->times = repeatTime; - pInfo->reverseTimes = reverseTime; - pInfo->current = 0; - pInfo->order = pRuntimeEnv->pQueryAttr->order.order; + pInfo->pQueryHandle = pTsdbQueryHandle; + pInfo->times = repeatTime; + pInfo->reverseTimes = reverseTime; + pInfo->current = 0; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); pOptr->name = "DataBlocksOptimizedScanOperator"; @@ -5429,14 +5429,14 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MERGE_STAGE); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "GlobalAggregate"; - pOperator->operatorType = OP_GlobalAggregate; - pOperator->blockingOptr = true; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->name = "GlobalAggregate"; + pOperator->operatorType = OP_GlobalAggregate; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doGlobalAggregate; pOperator->cleanup = destroyGlobalAggOperatorInfo; @@ -5473,16 +5473,16 @@ SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SEx } SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "MultiwaySortOperator"; - pOperator->operatorType = OP_MultiwayMergeSort; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->numOfOutput = numOfOutput; - pOperator->pExpr = pExpr; - pOperator->exec = doMultiwayMergeSort; - pOperator->cleanup = destroyGlobalAggOperatorInfo; + pOperator->name = "MultiwaySortOperator"; + pOperator->operatorType = OP_MultiwayMergeSort; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->numOfOutput = numOfOutput; + pOperator->pExpr = pExpr; + pOperator->exec = doMultiwayMergeSort; + pOperator->cleanup = destroyGlobalAggOperatorInfo; return pOperator; } @@ -6543,14 +6543,14 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "TableAggregate"; - pOperator->operatorType = OP_Aggregate; - pOperator->blockingOptr = true; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->name = "TableAggregate"; + pOperator->operatorType = OP_Aggregate; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doAggregate; pOperator->cleanup = destroyAggOperatorInfo; @@ -6638,14 +6638,14 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SO initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)tableGroup, TSDB_DATA_TYPE_INT); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "MultiTableAggregate"; - pOperator->operatorType = OP_MultiTableAggregate; - pOperator->blockingOptr = true; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->name = "MultiTableAggregate"; + pOperator->operatorType = OP_MultiTableAggregate; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doSTableAggregate; pOperator->cleanup = destroyAggOperatorInfo; @@ -6668,14 +6668,14 @@ SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "ProjectOperator"; - pOperator->operatorType = OP_Project; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->name = "ProjectOperator"; + pOperator->operatorType = OP_Project; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doProjectOperation; pOperator->cleanup = destroyProjectOperatorInfo; @@ -6920,16 +6920,16 @@ SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "GroupbyAggOperator"; - pOperator->blockingOptr = true; - pOperator->status = OP_IN_EXECUTING; - pOperator->operatorType = OP_Groupby; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->exec = hashGroupbyAggregate; - pOperator->cleanup = destroyGroupbyOperatorInfo; + pOperator->name = "GroupbyAggOperator"; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->operatorType = OP_Groupby; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = hashGroupbyAggregate; + pOperator->cleanup = destroyGroupbyOperatorInfo; appendUpstream(pOperator, upstream); return pOperator; @@ -7163,16 +7163,16 @@ SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInf pInfo->curPos = 0; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "SeqTableTagScan"; - pOperator->operatorType = OP_TagScan; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->info = pInfo; - pOperator->exec = doTagScan; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->cleanup = destroyTagScanOperatorInfo; + pOperator->name = "SeqTableTagScan"; + pOperator->operatorType = OP_TagScan; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->exec = doTagScan; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->cleanup = destroyTagScanOperatorInfo; return pOperator; } @@ -7302,17 +7302,17 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - pOperator->name = "DistinctOperator"; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->operatorType = OP_Distinct; - pOperator->pExpr = pExpr; - pOperator->numOfOutput = numOfOutput; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->exec = hashDistinct; - pOperator->pExpr = pExpr; - pOperator->cleanup = destroyDistinctOperatorInfo; + pOperator->name = "DistinctOperator"; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->operatorType = OP_Distinct; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = hashDistinct; + pOperator->pExpr = pExpr; + pOperator->cleanup = destroyDistinctOperatorInfo; appendUpstream(pOperator, upstream); return pOperator; @@ -7587,20 +7587,20 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { for (int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { param->pExpr[i] = pExprMsg; - pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); - pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); - pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->colBytes = htons(pExprMsg->colBytes); - pExprMsg->colType = htons(pExprMsg->colType); + pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); + pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); + pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); + pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); - pExprMsg->resType = htons(pExprMsg->resType); - pExprMsg->resBytes = htons(pExprMsg->resBytes); - pExprMsg->interBytes = htonl(pExprMsg->interBytes); + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); + pExprMsg->interBytes = htonl(pExprMsg->interBytes); - pExprMsg->functionId = htons(pExprMsg->functionId); - pExprMsg->numOfParams = htons(pExprMsg->numOfParams); - pExprMsg->resColId = htons(pExprMsg->resColId); - pExprMsg->flist.numOfFilters = htons(pExprMsg->flist.numOfFilters); + pExprMsg->functionId = htons(pExprMsg->functionId); + pExprMsg->numOfParams = htons(pExprMsg->numOfParams); + pExprMsg->resColId = htons(pExprMsg->resColId); + pExprMsg->flist.numOfFilters = htons(pExprMsg->flist.numOfFilters); pMsg += sizeof(SSqlExpr); for (int32_t j = 0; j < pExprMsg->numOfParams; ++j) { @@ -7639,15 +7639,15 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { param->pSecExpr[i] = pExprMsg; pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); - pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); - pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->resType = htons(pExprMsg->resType); - pExprMsg->resBytes = htons(pExprMsg->resBytes); - pExprMsg->colBytes = htons(pExprMsg->colBytes); - pExprMsg->colType = htons(pExprMsg->colType); + pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); + pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); + pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); - pExprMsg->functionId = htons(pExprMsg->functionId); - pExprMsg->numOfParams = htons(pExprMsg->numOfParams); + pExprMsg->functionId = htons(pExprMsg->functionId); + pExprMsg->numOfParams = htons(pExprMsg->numOfParams); pMsg += sizeof(SSqlExpr); @@ -8422,40 +8422,40 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S SQueryAttr* pQueryAttr = &pQInfo->query; pQInfo->runtimeEnv.pQueryAttr = pQueryAttr; - pQueryAttr->tableGroupInfo = *pTableGroupInfo; - pQueryAttr->numOfCols = numOfCols; - pQueryAttr->numOfOutput = numOfOutput; - pQueryAttr->limit.limit = pQueryMsg->limit; - pQueryAttr->limit.offset = pQueryMsg->offset; - pQueryAttr->order.order = pQueryMsg->order; - pQueryAttr->order.orderColId = pQueryMsg->orderColId; - pQueryAttr->pExpr1 = pExprs; - pQueryAttr->pExpr2 = pSecExprs; - pQueryAttr->numOfExpr2 = pQueryMsg->secondStageOutput; - pQueryAttr->pGroupbyExpr = pGroupbyExpr; + pQueryAttr->tableGroupInfo = *pTableGroupInfo; + pQueryAttr->numOfCols = numOfCols; + pQueryAttr->numOfOutput = numOfOutput; + pQueryAttr->limit.limit = pQueryMsg->limit; + pQueryAttr->limit.offset = pQueryMsg->offset; + pQueryAttr->order.order = pQueryMsg->order; + pQueryAttr->order.orderColId = pQueryMsg->orderColId; + pQueryAttr->pExpr1 = pExprs; + pQueryAttr->pExpr2 = pSecExprs; + pQueryAttr->numOfExpr2 = pQueryMsg->secondStageOutput; + pQueryAttr->pGroupbyExpr = pGroupbyExpr; memcpy(&pQueryAttr->interval, &pQueryMsg->interval, sizeof(pQueryAttr->interval)); - pQueryAttr->fillType = pQueryMsg->fillType; - pQueryAttr->numOfTags = pQueryMsg->numOfTags; - pQueryAttr->tagColList = pTagCols; + pQueryAttr->fillType = pQueryMsg->fillType; + pQueryAttr->numOfTags = pQueryMsg->numOfTags; + pQueryAttr->tagColList = pTagCols; pQueryAttr->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit; - pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; - pQueryAttr->sw = pQueryMsg->sw; - pQueryAttr->vgId = vgId; + pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; + pQueryAttr->sw = pQueryMsg->sw; + pQueryAttr->vgId = vgId; - pQueryAttr->stableQuery = pQueryMsg->stableQuery; - pQueryAttr->topBotQuery = pQueryMsg->topBotQuery; - pQueryAttr->groupbyColumn = pQueryMsg->groupbyColumn; - pQueryAttr->hasTagResults = pQueryMsg->hasTagResults; + pQueryAttr->stableQuery = pQueryMsg->stableQuery; + pQueryAttr->topBotQuery = pQueryMsg->topBotQuery; + pQueryAttr->groupbyColumn = pQueryMsg->groupbyColumn; + pQueryAttr->hasTagResults = pQueryMsg->hasTagResults; pQueryAttr->timeWindowInterpo = pQueryMsg->timeWindowInterpo; - pQueryAttr->queryBlockDist = pQueryMsg->queryBlockDist; - pQueryAttr->stabledev = pQueryMsg->stabledev; - pQueryAttr->tsCompQuery = pQueryMsg->tsCompQuery; - pQueryAttr->simpleAgg = pQueryMsg->simpleAgg; - pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery; - pQueryAttr->needReverseScan = pQueryMsg->needReverseScan; - pQueryAttr->stateWindow = pQueryMsg->stateWindow; - pQueryAttr->vgId = vgId; - pQueryAttr->pFilters = pFilters; + pQueryAttr->queryBlockDist = pQueryMsg->queryBlockDist; + pQueryAttr->stabledev = pQueryMsg->stabledev; + pQueryAttr->tsCompQuery = pQueryMsg->tsCompQuery; + pQueryAttr->simpleAgg = pQueryMsg->simpleAgg; + pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery; + pQueryAttr->needReverseScan = pQueryMsg->needReverseScan; + pQueryAttr->stateWindow = pQueryMsg->stateWindow; + pQueryAttr->vgId = vgId; + pQueryAttr->pFilters = pFilters; pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); if (pQueryAttr->tableCols == NULL) { diff --git a/src/tsdb/inc/tsdbCommitQueue.h b/src/tsdb/inc/tsdbCommitQueue.h deleted file mode 100644 index b690e3bdc2..0000000000 --- a/src/tsdb/inc/tsdbCommitQueue.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef _TD_TSDB_COMMIT_QUEUE_H_ -#define _TD_TSDB_COMMIT_QUEUE_H_ - -typedef enum { COMMIT_REQ, COMPACT_REQ,COMMIT_CONFIG_REQ } TSDB_REQ_T; - -int tsdbScheduleCommit(STsdbRepo *pRepo, TSDB_REQ_T req); - -#endif /* _TD_TSDB_COMMIT_QUEUE_H_ */ \ No newline at end of file diff --git a/src/tsdb/inc/tsdbMemTable.h b/src/tsdb/inc/tsdbMemTable.h deleted file mode 100644 index 67e9976c70..0000000000 --- a/src/tsdb/inc/tsdbMemTable.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#ifndef _TD_TSDB_MEMTABLE_H_ -#define _TD_TSDB_MEMTABLE_H_ - -typedef struct { - int rowsInserted; - int rowsUpdated; - int rowsDeleteSucceed; - int rowsDeleteFailed; - int nOperations; - TSKEY keyFirst; - TSKEY keyLast; -} SMergeInfo; - -typedef struct { - STable * pTable; - SSkipListIterator *pIter; -} SCommitIter; - -struct STableData { - uint64_t uid; - TSKEY keyFirst; - TSKEY keyLast; - int64_t numOfRows; - SSkipList* pData; - T_REF_DECLARE() -}; - -enum { TSDB_UPDATE_META, TSDB_DROP_META }; - -#ifdef WINDOWS -#pragma pack(push ,1) -typedef struct { -#else -typedef struct __attribute__((packed)){ -#endif - char act; - uint64_t uid; -} SActObj; -#ifdef WINDOWS -#pragma pack(pop) -#endif - -typedef struct { - int len; - char cont[]; -} SActCont; - -int tsdbRefMemTable(STsdbRepo* pRepo, SMemTable* pMemTable); -int tsdbUnRefMemTable(STsdbRepo* pRepo, SMemTable* pMemTable); -int tsdbTakeMemSnapshot(STsdbRepo* pRepo, SMemSnapshot* pSnapshot, SArray* pATable); -void tsdbUnTakeMemSnapShot(STsdbRepo* pRepo, SMemSnapshot* pSnapshot); -void* tsdbAllocBytes(STsdbRepo* pRepo, int bytes); -int tsdbAsyncCommit(STsdbRepo* pRepo); -int tsdbSyncCommitConfig(STsdbRepo* pRepo); -int tsdbLoadDataFromCache(STable* pTable, SSkipListIterator* pIter, TSKEY maxKey, int maxRowsToRead, SDataCols* pCols, - TKEY* filterKeys, int nFilterKeys, bool keepDup, SMergeInfo* pMergeInfo); -void* tsdbCommitData(STsdbRepo* pRepo); - -static FORCE_INLINE SMemRow tsdbNextIterRow(SSkipListIterator* pIter) { - if (pIter == NULL) return NULL; - - SSkipListNode* node = tSkipListIterGet(pIter); - if (node == NULL) return NULL; - - return (SMemRow)SL_GET_NODE_DATA(node); -} - -static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator* pIter) { - SMemRow row = tsdbNextIterRow(pIter); - if (row == NULL) return TSDB_DATA_TIMESTAMP_NULL; - - return memRowKey(row); -} - -static FORCE_INLINE TKEY tsdbNextIterTKey(SSkipListIterator* pIter) { - SMemRow row = tsdbNextIterRow(pIter); - if (row == NULL) return TKEY_NULL; - - return memRowTKey(row); -} - -#endif /* _TD_TSDB_MEMTABLE_H_ */ \ No newline at end of file diff --git a/src/tsdb/src/tsdbBuffer.c b/src/tsdb/src/tsdbBuffer.c deleted file mode 100644 index 70589031f6..0000000000 --- a/src/tsdb/src/tsdbBuffer.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#include "tsdbint.h" -#include "tsdbHealth.h" - -#define POOL_IS_EMPTY(b) (listNEles((b)->bufBlockList) == 0) - -// ---------------- INTERNAL FUNCTIONS ---------------- -STsdbBufPool *tsdbNewBufPool() { - STsdbBufPool *pBufPool = (STsdbBufPool *)calloc(1, sizeof(*pBufPool)); - if (pBufPool == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - int code = pthread_cond_init(&(pBufPool->poolNotEmpty), NULL); - if (code != 0) { - terrno = TAOS_SYSTEM_ERROR(code); - goto _err; - } - - pBufPool->bufBlockList = tdListNew(sizeof(STsdbBufBlock *)); - if (pBufPool->bufBlockList == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - return pBufPool; - -_err: - tsdbFreeBufPool(pBufPool); - return NULL; -} - -void tsdbFreeBufPool(STsdbBufPool *pBufPool) { - if (pBufPool) { - if (pBufPool->bufBlockList) { - ASSERT(listNEles(pBufPool->bufBlockList) == 0); - tdListFree(pBufPool->bufBlockList); - } - - pthread_cond_destroy(&pBufPool->poolNotEmpty); - - free(pBufPool); - } -} - -int tsdbOpenBufPool(STsdbRepo *pRepo) { - STsdbCfg * pCfg = &(pRepo->config); - STsdbBufPool *pPool = pRepo->pPool; - - ASSERT(pPool != NULL); - pPool->bufBlockSize = pCfg->cacheBlockSize * 1024 * 1024; // MB - pPool->tBufBlocks = pCfg->totalBlocks; - pPool->nBufBlocks = 0; - pPool->nElasticBlocks = 0; - pPool->index = 0; - pPool->nRecycleBlocks = 0; - - for (int i = 0; i < pCfg->totalBlocks; i++) { - STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); - if (pBufBlock == NULL) goto _err; - - if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) { - tsdbFreeBufBlock(pBufBlock); - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - pPool->nBufBlocks++; - } - - tsdbDebug("vgId:%d buffer pool is opened! bufBlockSize:%d tBufBlocks:%d nBufBlocks:%d", REPO_ID(pRepo), - pPool->bufBlockSize, pPool->tBufBlocks, pPool->nBufBlocks); - - return 0; - -_err: - tsdbCloseBufPool(pRepo); - return -1; -} - -void tsdbCloseBufPool(STsdbRepo *pRepo) { - if (pRepo == NULL) return; - - STsdbBufPool * pBufPool = pRepo->pPool; - STsdbBufBlock *pBufBlock = NULL; - - if (pBufPool) { - SListNode *pNode = NULL; - while ((pNode = tdListPopHead(pBufPool->bufBlockList)) != NULL) { - tdListNodeGetData(pBufPool->bufBlockList, pNode, (void *)(&pBufBlock)); - tsdbFreeBufBlock(pBufBlock); - free(pNode); - } - } - - tsdbDebug("vgId:%d, buffer pool is closed", REPO_ID(pRepo)); -} - -SListNode *tsdbAllocBufBlockFromPool(STsdbRepo *pRepo) { - ASSERT(pRepo != NULL && pRepo->pPool != NULL); - ASSERT(IS_REPO_LOCKED(pRepo)); - - STsdbBufPool *pBufPool = pRepo->pPool; - - while (POOL_IS_EMPTY(pBufPool)) { - if(tsDeadLockKillQuery) { - // supply new Block - if(tsdbInsertNewBlock(pRepo) > 0) { - tsdbWarn("vgId:%d add new elastic block . elasticBlocks=%d cur free Blocks=%d", REPO_ID(pRepo), pBufPool->nElasticBlocks, pBufPool->bufBlockList->numOfEles); - break; - } else { - // no newBlock, kill query free - if(!tsdbUrgeQueryFree(pRepo)) - tsdbWarn("vgId:%d Urge query free thread start failed.", REPO_ID(pRepo)); - } - } - - pRepo->repoLocked = false; - pthread_cond_wait(&(pBufPool->poolNotEmpty), &(pRepo->mutex)); - pRepo->repoLocked = true; - } - - SListNode * pNode = tdListPopHead(pBufPool->bufBlockList); - ASSERT(pNode != NULL); - STsdbBufBlock *pBufBlock = NULL; - tdListNodeGetData(pBufPool->bufBlockList, pNode, (void *)(&pBufBlock)); - - pBufBlock->blockId = pBufPool->index++; - pBufBlock->offset = 0; - pBufBlock->remain = pBufPool->bufBlockSize; - - tsdbDebug("vgId:%d, buffer block is allocated, blockId:%" PRId64, REPO_ID(pRepo), pBufBlock->blockId); - return pNode; -} - -// ---------------- LOCAL FUNCTIONS ---------------- -STsdbBufBlock *tsdbNewBufBlock(int bufBlockSize) { - STsdbBufBlock *pBufBlock = (STsdbBufBlock *)malloc(sizeof(*pBufBlock) + bufBlockSize); - if (pBufBlock == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return NULL; - } - - pBufBlock->blockId = 0; - pBufBlock->offset = 0; - pBufBlock->remain = bufBlockSize; - - return pBufBlock; -} - - void tsdbFreeBufBlock(STsdbBufBlock *pBufBlock) { tfree(pBufBlock); } - -int tsdbExpandPool(STsdbRepo* pRepo, int32_t oldTotalBlocks) { - if (oldTotalBlocks == pRepo->config.totalBlocks) { - return TSDB_CODE_SUCCESS; - } - - int err = TSDB_CODE_SUCCESS; - - if (tsdbLockRepo(pRepo) < 0) return terrno; - STsdbBufPool* pPool = pRepo->pPool; - - if (pRepo->config.totalBlocks > oldTotalBlocks) { - for (int i = 0; i < pRepo->config.totalBlocks - oldTotalBlocks; i++) { - STsdbBufBlock *pBufBlock = tsdbNewBufBlock(pPool->bufBlockSize); - if (pBufBlock == NULL) goto err; - - if (tdListAppend(pPool->bufBlockList, (void *)(&pBufBlock)) < 0) { - tsdbFreeBufBlock(pBufBlock); - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - err = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto err; - } - - pPool->nBufBlocks++; - } - pthread_cond_signal(&pPool->poolNotEmpty); - } else { - pPool->nRecycleBlocks = oldTotalBlocks - pRepo->config.totalBlocks; - } - -err: - tsdbUnlockRepo(pRepo); - return err; -} - -void tsdbRecycleBufferBlock(STsdbBufPool* pPool, SListNode *pNode, bool bELastic) { - STsdbBufBlock *pBufBlock = NULL; - tdListNodeGetData(pPool->bufBlockList, pNode, (void *)(&pBufBlock)); - tsdbFreeBufBlock(pBufBlock); - free(pNode); - if(bELastic) - { - pPool->nElasticBlocks--; - tsdbWarn("pPool=%p elastic block reduce one . nElasticBlocks=%d cur free Blocks=%d", pPool, pPool->nElasticBlocks, pPool->bufBlockList->numOfEles); - } - else - pPool->nBufBlocks--; -} \ No newline at end of file diff --git a/src/tsdb/src/tsdbCommitQueue.c b/src/tsdb/src/tsdbCommitQueue.c deleted file mode 100644 index 59fb4f334d..0000000000 --- a/src/tsdb/src/tsdbCommitQueue.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#include "tsdbint.h" - -typedef struct { - bool stop; - pthread_mutex_t lock; - pthread_cond_t queueNotEmpty; - int nthreads; - int refCount; - SList * queue; - pthread_t * threads; -} SCommitQueue; - -typedef struct { - TSDB_REQ_T req; - STsdbRepo *pRepo; -} SReq; - -static void *tsdbLoopCommit(void *arg); - -static SCommitQueue tsCommitQueue = {0}; - -int tsdbInitCommitQueue() { - int nthreads = tsNumOfCommitThreads; - SCommitQueue *pQueue = &tsCommitQueue; - - if (nthreads < 1) nthreads = 1; - - pQueue->stop = false; - pQueue->nthreads = nthreads; - - pQueue->queue = tdListNew(0); - if (pQueue->queue == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - pQueue->threads = (pthread_t *)calloc(nthreads, sizeof(pthread_t)); - if (pQueue->threads == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tdListFree(pQueue->queue); - return -1; - } - - pthread_mutex_init(&(pQueue->lock), NULL); - pthread_cond_init(&(pQueue->queueNotEmpty), NULL); - - for (int i = 0; i < nthreads; i++) { - pthread_create(pQueue->threads + i, NULL, tsdbLoopCommit, NULL); - } - - return 0; -} - -void tsdbDestroyCommitQueue() { - SCommitQueue *pQueue = &tsCommitQueue; - - pthread_mutex_lock(&(pQueue->lock)); - - if (pQueue->stop) { - pthread_mutex_unlock(&(pQueue->lock)); - return; - } - - pQueue->stop = true; - pthread_cond_broadcast(&(pQueue->queueNotEmpty)); - - pthread_mutex_unlock(&(pQueue->lock)); - - for (size_t i = 0; i < pQueue->nthreads; i++) { - pthread_join(pQueue->threads[i], NULL); - } - - free(pQueue->threads); - tdListFree(pQueue->queue); - pthread_cond_destroy(&(pQueue->queueNotEmpty)); - pthread_mutex_destroy(&(pQueue->lock)); -} - -int tsdbScheduleCommit(STsdbRepo *pRepo, TSDB_REQ_T req) { - SCommitQueue *pQueue = &tsCommitQueue; - - SListNode *pNode = (SListNode *)calloc(1, sizeof(SListNode) + sizeof(SReq)); - if (pNode == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - ((SReq *)pNode->data)->req = req; - ((SReq *)pNode->data)->pRepo = pRepo; - - pthread_mutex_lock(&(pQueue->lock)); - - // ASSERT(pQueue->stop); - - tdListAppendNode(pQueue->queue, pNode); - pthread_cond_signal(&(pQueue->queueNotEmpty)); - - pthread_mutex_unlock(&(pQueue->lock)); - return 0; -} - -static void tsdbApplyRepoConfig(STsdbRepo *pRepo) { - pthread_mutex_lock(&pRepo->save_mutex); - - pRepo->config_changed = false; - STsdbCfg * pSaveCfg = &pRepo->save_config; - STsdbCfg oldCfg; - int32_t oldTotalBlocks = pRepo->config.totalBlocks; - - memcpy(&oldCfg, &(pRepo->config), sizeof(STsdbCfg)); - - pRepo->config.compression = pRepo->save_config.compression; - pRepo->config.keep = pRepo->save_config.keep; - pRepo->config.keep1 = pRepo->save_config.keep1; - pRepo->config.keep2 = pRepo->save_config.keep2; - pRepo->config.cacheLastRow = pRepo->save_config.cacheLastRow; - pRepo->config.totalBlocks = pRepo->save_config.totalBlocks; - - pthread_mutex_unlock(&pRepo->save_mutex); - - tsdbInfo("vgId:%d apply new config: compression(%d), keep(%d,%d,%d), totalBlocks(%d), cacheLastRow(%d->%d),totalBlocks(%d->%d)", - REPO_ID(pRepo), - pSaveCfg->compression, pSaveCfg->keep,pSaveCfg->keep1, pSaveCfg->keep2, - pSaveCfg->totalBlocks, oldCfg.cacheLastRow, pSaveCfg->cacheLastRow, oldTotalBlocks, pSaveCfg->totalBlocks); - - int err = tsdbExpandPool(pRepo, oldTotalBlocks); - if (!TAOS_SUCCEEDED(err)) { - tsdbError("vgId:%d expand pool from %d to %d fail,reason:%s", - REPO_ID(pRepo), oldTotalBlocks, pSaveCfg->totalBlocks, tstrerror(err)); - } - - if (oldCfg.cacheLastRow != pRepo->config.cacheLastRow) { - if (tsdbLockRepo(pRepo) < 0) return; - tsdbCacheLastData(pRepo, &oldCfg); - tsdbUnlockRepo(pRepo); - } - -} - -static void *tsdbLoopCommit(void *arg) { - SCommitQueue *pQueue = &tsCommitQueue; - SListNode * pNode = NULL; - STsdbRepo * pRepo = NULL; - TSDB_REQ_T req; - - setThreadName("tsdbCommit"); - - while (true) { - pthread_mutex_lock(&(pQueue->lock)); - - while (true) { - pNode = tdListPopHead(pQueue->queue); - if (pNode == NULL) { - if (pQueue->stop && pQueue->refCount <= 0) { - pthread_mutex_unlock(&(pQueue->lock)); - goto _exit; - } else { - pthread_cond_wait(&(pQueue->queueNotEmpty), &(pQueue->lock)); - } - } else { - break; - } - } - - pthread_mutex_unlock(&(pQueue->lock)); - - req = ((SReq *)pNode->data)->req; - pRepo = ((SReq *)pNode->data)->pRepo; - - if (req == COMMIT_REQ) { - tsdbCommitData(pRepo); - } else if (req == COMPACT_REQ) { - tsdbCompactImpl(pRepo); - } else if (req == COMMIT_CONFIG_REQ) { - ASSERT(pRepo->config_changed); - tsdbApplyRepoConfig(pRepo); - tsem_post(&(pRepo->readyToCommit)); - } else { - ASSERT(0); - } - - listNodeFree(pNode); - } - -_exit: - return NULL; -} - -void tsdbIncCommitRef(int vgId) { - int refCount = atomic_add_fetch_32(&tsCommitQueue.refCount, 1); - tsdbDebug("vgId:%d, inc commit queue ref to %d", vgId, refCount); -} - -void tsdbDecCommitRef(int vgId) { - int refCount = atomic_sub_fetch_32(&tsCommitQueue.refCount, 1); - pthread_cond_broadcast(&(tsCommitQueue.queueNotEmpty)); - tsdbDebug("vgId:%d, dec commit queue ref to %d", vgId, refCount); -} diff --git a/src/tsdb/src/tsdbMemTable.c b/src/tsdb/src/tsdbMemTable.c deleted file mode 100644 index 3890dca5b9..0000000000 --- a/src/tsdb/src/tsdbMemTable.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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 . - */ - -#include "tdataformat.h" -#include "tfunctional.h" -#include "tsdbint.h" -#include "tskiplist.h" -#include "tsdbRowMergeBuf.h" - -#define TSDB_DATA_SKIPLIST_LEVEL 5 -#define TSDB_MAX_INSERT_BATCH 512 - -typedef struct { - int32_t totalLen; - int32_t len; - SMemRow row; -} SSubmitBlkIter; - -typedef struct { - int32_t totalLen; - int32_t len; - void * pMsg; -} SSubmitMsgIter; - -static SMemTable * tsdbNewMemTable(STsdbRepo *pRepo); -static void tsdbFreeMemTable(SMemTable *pMemTable); -static STableData* tsdbNewTableData(STsdbCfg *pCfg, STable *pTable); -static void tsdbFreeTableData(STableData *pTableData); -static char * tsdbGetTsTupleKey(const void *data); -static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables); -static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row); -static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter); -static SMemRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter); -static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg); -static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *affectedrows); -static int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter); -static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock); -static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable); -static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row); - -static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey, - TSKEY now); - -int32_t tsdbInsertData(STsdbRepo *repo, SSubmitMsg *pMsg, SShellSubmitRspMsg *pRsp) { - STsdbRepo * pRepo = repo; - SSubmitMsgIter msgIter = {0}; - SSubmitBlk * pBlock = NULL; - int32_t affectedrows = 0; - - if (tsdbScanAndConvertSubmitMsg(pRepo, pMsg) < 0) { - if (terrno != TSDB_CODE_TDB_TABLE_RECONFIGURE) { - tsdbError("vgId:%d failed to insert data since %s", REPO_ID(pRepo), tstrerror(terrno)); - } - return -1; - } - - tsdbInitSubmitMsgIter(pMsg, &msgIter); - while (true) { - tsdbGetSubmitMsgNext(&msgIter, &pBlock); - if (pBlock == NULL) break; - if (tsdbInsertDataToTable(pRepo, pBlock, &affectedrows) < 0) { - return -1; - } - } - - if (pRsp != NULL) pRsp->affectedRows = htonl(affectedrows); - - if (tsdbCheckCommit(pRepo) < 0) return -1; - return 0; -} - -// ---------------- INTERNAL FUNCTIONS ---------------- -int tsdbRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { - if (pMemTable == NULL) return 0; - int ref = T_REF_INC(pMemTable); - tsdbDebug("vgId:%d ref memtable %p ref %d", REPO_ID(pRepo), pMemTable, ref); - return 0; -} - -// Need to lock the repository -int tsdbUnRefMemTable(STsdbRepo *pRepo, SMemTable *pMemTable) { - if (pMemTable == NULL) return 0; - - int ref = T_REF_DEC(pMemTable); - tsdbDebug("vgId:%d unref memtable %p ref %d", REPO_ID(pRepo), pMemTable, ref); - if (ref == 0) { - STsdbBufPool *pBufPool = pRepo->pPool; - - SListNode *pNode = NULL; - bool addNew = false; - if (tsdbLockRepo(pRepo) < 0) return -1; - while ((pNode = tdListPopHead(pMemTable->bufBlockList)) != NULL) { - if (pBufPool->nRecycleBlocks > 0) { - tsdbRecycleBufferBlock(pBufPool, pNode, false); - pBufPool->nRecycleBlocks -= 1; - } else { - if(pBufPool->nElasticBlocks > 0 && listNEles(pBufPool->bufBlockList) > 2) { - tsdbRecycleBufferBlock(pBufPool, pNode, true); - } else { - tdListAppendNode(pBufPool->bufBlockList, pNode); - addNew = true; - } - } - } - if (addNew) { - int code = pthread_cond_signal(&pBufPool->poolNotEmpty); - if (code != 0) { - if (tsdbUnlockRepo(pRepo) < 0) return -1; - tsdbError("vgId:%d failed to signal pool not empty since %s", REPO_ID(pRepo), strerror(code)); - terrno = TAOS_SYSTEM_ERROR(code); - return -1; - } - } - - if (tsdbUnlockRepo(pRepo) < 0) return -1; - - for (int i = 0; i < pMemTable->maxTables; i++) { - if (pMemTable->tData[i] != NULL) { - tsdbFreeTableData(pMemTable->tData[i]); - } - } - - tdListDiscard(pMemTable->actList); - tdListDiscard(pMemTable->bufBlockList); - tsdbFreeMemTable(pMemTable); - } - return 0; -} - -int tsdbTakeMemSnapshot(STsdbRepo *pRepo, SMemSnapshot *pSnapshot, SArray *pATable) { - memset(pSnapshot, 0, sizeof(*pSnapshot)); - - if (tsdbLockRepo(pRepo) < 0) return -1; - - pSnapshot->omem = pRepo->mem; - pSnapshot->imem = pRepo->imem; - tsdbRefMemTable(pRepo, pRepo->mem); - tsdbRefMemTable(pRepo, pRepo->imem); - - if (tsdbUnlockRepo(pRepo) < 0) return -1; - - if (pSnapshot->omem) { - taosRLockLatch(&(pSnapshot->omem->latch)); - - pSnapshot->mem = &(pSnapshot->mtable); - - pSnapshot->mem->tData = (STableData **)calloc(pSnapshot->omem->maxTables, sizeof(STableData *)); - if (pSnapshot->mem->tData == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - taosRUnLockLatch(&(pSnapshot->omem->latch)); - tsdbUnRefMemTable(pRepo, pSnapshot->omem); - tsdbUnRefMemTable(pRepo, pSnapshot->imem); - pSnapshot->mem = NULL; - pSnapshot->imem = NULL; - pSnapshot->omem = NULL; - return -1; - } - - pSnapshot->mem->keyFirst = pSnapshot->omem->keyFirst; - pSnapshot->mem->keyLast = pSnapshot->omem->keyLast; - pSnapshot->mem->numOfRows = pSnapshot->omem->numOfRows; - pSnapshot->mem->maxTables = pSnapshot->omem->maxTables; - - for (size_t i = 0; i < taosArrayGetSize(pATable); i++) { - STable * pTable = *(STable **)taosArrayGet(pATable, i); - int32_t tid = TABLE_TID(pTable); - STableData *pTableData = (tid < pSnapshot->omem->maxTables) ? pSnapshot->omem->tData[tid] : NULL; - - if ((pTableData == NULL) || (TABLE_UID(pTable) != pTableData->uid)) continue; - - pSnapshot->mem->tData[tid] = pTableData; - T_REF_INC(pTableData); - } - - taosRUnLockLatch(&(pSnapshot->omem->latch)); - } - - tsdbDebug("vgId:%d take memory snapshot, pMem %p pIMem %p", REPO_ID(pRepo), pSnapshot->omem, pSnapshot->imem); - return 0; -} - -void tsdbUnTakeMemSnapShot(STsdbRepo *pRepo, SMemSnapshot *pSnapshot) { - tsdbDebug("vgId:%d untake memory snapshot, pMem %p pIMem %p", REPO_ID(pRepo), pSnapshot->omem, pSnapshot->imem); - - if (pSnapshot->mem) { - ASSERT(pSnapshot->omem != NULL); - - for (size_t i = 0; i < pSnapshot->mem->maxTables; i++) { - STableData *pTableData = pSnapshot->mem->tData[i]; - if (pTableData) { - tsdbFreeTableData(pTableData); - } - } - tfree(pSnapshot->mem->tData); - - tsdbUnRefMemTable(pRepo, pSnapshot->omem); - } - - tsdbUnRefMemTable(pRepo, pSnapshot->imem); - - pSnapshot->mem = NULL; - pSnapshot->imem = NULL; - pSnapshot->omem = NULL; -} - -void *tsdbAllocBytes(STsdbRepo *pRepo, int bytes) { - STsdbCfg * pCfg = &pRepo->config; - STsdbBufBlock *pBufBlock = NULL; - void * ptr = NULL; - - // Either allocate from buffer blocks or from SYSTEM memory pool - if (pRepo->mem == NULL) { - SMemTable *pMemTable = tsdbNewMemTable(pRepo); - if (pMemTable == NULL) return NULL; - pRepo->mem = pMemTable; - } - - ASSERT(pRepo->mem != NULL); - - pBufBlock = tsdbGetCurrBufBlock(pRepo); - if ((pRepo->mem->extraBuffList != NULL) || - ((listNEles(pRepo->mem->bufBlockList) >= pCfg->totalBlocks / 3) && (pBufBlock->remain < bytes))) { - // allocate from SYSTEM buffer pool - if (pRepo->mem->extraBuffList == NULL) { - pRepo->mem->extraBuffList = tdListNew(0); - if (pRepo->mem->extraBuffList == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return NULL; - } - } - - ASSERT(pRepo->mem->extraBuffList != NULL); - SListNode *pNode = (SListNode *)malloc(sizeof(SListNode) + bytes); - if (pNode == NULL) { - if (listNEles(pRepo->mem->extraBuffList) == 0) { - tdListFree(pRepo->mem->extraBuffList); - pRepo->mem->extraBuffList = NULL; - } - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return NULL; - } - - pNode->next = pNode->prev = NULL; - tdListAppendNode(pRepo->mem->extraBuffList, pNode); - ptr = (void *)(pNode->data); - tsdbTrace("vgId:%d allocate %d bytes from SYSTEM buffer block", REPO_ID(pRepo), bytes); - } else { // allocate from TSDB buffer pool - if (pBufBlock == NULL || pBufBlock->remain < bytes) { - ASSERT(listNEles(pRepo->mem->bufBlockList) < pCfg->totalBlocks / 3); - if (tsdbLockRepo(pRepo) < 0) return NULL; - SListNode *pNode = tsdbAllocBufBlockFromPool(pRepo); - tdListAppendNode(pRepo->mem->bufBlockList, pNode); - if (tsdbUnlockRepo(pRepo) < 0) return NULL; - pBufBlock = tsdbGetCurrBufBlock(pRepo); - } - - ASSERT(pBufBlock->remain >= bytes); - ptr = POINTER_SHIFT(pBufBlock->data, pBufBlock->offset); - pBufBlock->offset += bytes; - pBufBlock->remain -= bytes; - tsdbTrace("vgId:%d allocate %d bytes from TSDB buffer block, nBlocks %d offset %d remain %d", REPO_ID(pRepo), bytes, - listNEles(pRepo->mem->bufBlockList), pBufBlock->offset, pBufBlock->remain); - } - - return ptr; -} - -int tsdbSyncCommitConfig(STsdbRepo* pRepo) { - ASSERT(pRepo->config_changed == true); - tsem_wait(&(pRepo->readyToCommit)); - - if (pRepo->code != TSDB_CODE_SUCCESS) { - tsdbWarn("vgId:%d try to commit config when TSDB not in good state: %s", REPO_ID(pRepo), tstrerror(terrno)); - } - - if (tsdbLockRepo(pRepo) < 0) return -1; - tsdbScheduleCommit(pRepo, COMMIT_CONFIG_REQ); - if (tsdbUnlockRepo(pRepo) < 0) return -1; - - tsem_wait(&(pRepo->readyToCommit)); - tsem_post(&(pRepo->readyToCommit)); - - if (pRepo->code != TSDB_CODE_SUCCESS) { - terrno = pRepo->code; - return -1; - } - - terrno = TSDB_CODE_SUCCESS; - return 0; -} - -int tsdbAsyncCommit(STsdbRepo *pRepo) { - tsem_wait(&(pRepo->readyToCommit)); - - ASSERT(pRepo->imem == NULL); - if (pRepo->mem == NULL) { - tsem_post(&(pRepo->readyToCommit)); - return 0; - } - - if (pRepo->code != TSDB_CODE_SUCCESS) { - tsdbWarn("vgId:%d try to commit when TSDB not in good state: %s", REPO_ID(pRepo), tstrerror(terrno)); - } - - if (pRepo->appH.notifyStatus) pRepo->appH.notifyStatus(pRepo->appH.appH, TSDB_STATUS_COMMIT_START, TSDB_CODE_SUCCESS); - if (tsdbLockRepo(pRepo) < 0) return -1; - pRepo->imem = pRepo->mem; - pRepo->mem = NULL; - tsdbScheduleCommit(pRepo, COMMIT_REQ); - if (tsdbUnlockRepo(pRepo) < 0) return -1; - - return 0; -} - -int tsdbSyncCommit(STsdbRepo *repo) { - STsdbRepo *pRepo = repo; - - tsdbAsyncCommit(pRepo); - tsem_wait(&(pRepo->readyToCommit)); - tsem_post(&(pRepo->readyToCommit)); - - if (pRepo->code != TSDB_CODE_SUCCESS) { - terrno = pRepo->code; - return -1; - } else { - terrno = TSDB_CODE_SUCCESS; - return 0; - } -} - -/** - * This is an important function to load data or try to load data from memory skiplist iterator. - * - * This function load memory data until: - * 1. iterator ends - * 2. data key exceeds maxKey - * 3. rowsIncreased = rowsInserted - rowsDeleteSucceed >= maxRowsToRead - * 4. operations in pCols not exceeds its max capacity if pCols is given - * - * The function tries to procceed AS MUCH AS POSSIBLE. - */ -int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKey, int maxRowsToRead, SDataCols *pCols, - TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo) { - ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0); - if (pIter == NULL) return 0; - STSchema * pSchema = NULL; - TSKEY rowKey = 0; - TSKEY fKey = 0; - bool isRowDel = false; - int filterIter = 0; - SMemRow row = NULL; - SMergeInfo mInfo; - - if (pMergeInfo == NULL) pMergeInfo = &mInfo; - - memset(pMergeInfo, 0, sizeof(*pMergeInfo)); - pMergeInfo->keyFirst = INT64_MAX; - pMergeInfo->keyLast = INT64_MIN; - if (pCols) tdResetDataCols(pCols); - - row = tsdbNextIterRow(pIter); - if (row == NULL || memRowKey(row) > maxKey) { - rowKey = INT64_MAX; - isRowDel = false; - } else { - rowKey = memRowKey(row); - isRowDel = memRowDeleted(row); - } - - if (filterIter >= nFilterKeys) { - fKey = INT64_MAX; - } else { - fKey = tdGetKey(filterKeys[filterIter]); - } - - while (true) { - if (fKey == INT64_MAX && rowKey == INT64_MAX) break; - - if (fKey < rowKey) { - pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); - pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); - - filterIter++; - if (filterIter >= nFilterKeys) { - fKey = INT64_MAX; - } else { - fKey = tdGetKey(filterKeys[filterIter]); - } - } else if (fKey > rowKey) { - if (isRowDel) { - pMergeInfo->rowsDeleteFailed++; - } else { - if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break; - if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; - pMergeInfo->rowsInserted++; - pMergeInfo->nOperations++; - pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); - pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); - tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); - } - - tSkipListIterNext(pIter); - row = tsdbNextIterRow(pIter); - if (row == NULL || memRowKey(row) > maxKey) { - rowKey = INT64_MAX; - isRowDel = false; - } else { - rowKey = memRowKey(row); - isRowDel = memRowDeleted(row); - } - } else { - if (isRowDel) { - ASSERT(!keepDup); - if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; - pMergeInfo->rowsDeleteSucceed++; - pMergeInfo->nOperations++; - tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); - } else { - if (keepDup) { - if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break; - pMergeInfo->rowsUpdated++; - pMergeInfo->nOperations++; - pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, rowKey); - pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, rowKey); - tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row); - } else { - pMergeInfo->keyFirst = MIN(pMergeInfo->keyFirst, fKey); - pMergeInfo->keyLast = MAX(pMergeInfo->keyLast, fKey); - } - } - - tSkipListIterNext(pIter); - row = tsdbNextIterRow(pIter); - if (row == NULL || memRowKey(row) > maxKey) { - rowKey = INT64_MAX; - isRowDel = false; - } else { - rowKey = memRowKey(row); - isRowDel = memRowDeleted(row); - } - - filterIter++; - if (filterIter >= nFilterKeys) { - fKey = INT64_MAX; - } else { - fKey = tdGetKey(filterKeys[filterIter]); - } - } - } - - return 0; -} - -// ---------------- LOCAL FUNCTIONS ---------------- -static SMemTable* tsdbNewMemTable(STsdbRepo *pRepo) { - STsdbMeta *pMeta = pRepo->tsdbMeta; - - SMemTable *pMemTable = (SMemTable *)calloc(1, sizeof(*pMemTable)); - if (pMemTable == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - pMemTable->keyFirst = INT64_MAX; - pMemTable->keyLast = 0; - pMemTable->numOfRows = 0; - - pMemTable->maxTables = pMeta->maxTables; - pMemTable->tData = (STableData **)calloc(pMemTable->maxTables, sizeof(STableData *)); - if (pMemTable->tData == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - pMemTable->actList = tdListNew(0); - if (pMemTable->actList == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - pMemTable->bufBlockList = tdListNew(sizeof(STsdbBufBlock*)); - if (pMemTable->bufBlockList == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - goto _err; - } - - T_REF_INC(pMemTable); - - return pMemTable; - -_err: - tsdbFreeMemTable(pMemTable); - return NULL; -} - -static void tsdbFreeMemTable(SMemTable* pMemTable) { - if (pMemTable) { - ASSERT((pMemTable->bufBlockList == NULL) ? true : (listNEles(pMemTable->bufBlockList) == 0)); - ASSERT((pMemTable->actList == NULL) ? true : (listNEles(pMemTable->actList) == 0)); - - tdListFree(pMemTable->extraBuffList); - tdListFree(pMemTable->bufBlockList); - tdListFree(pMemTable->actList); - tfree(pMemTable->tData); - free(pMemTable); - } -} - -static STableData *tsdbNewTableData(STsdbCfg *pCfg, STable *pTable) { - STableData *pTableData = (STableData *)calloc(1, sizeof(*pTableData)); - if (pTableData == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return NULL; - } - - pTableData->uid = TABLE_UID(pTable); - pTableData->keyFirst = INT64_MAX; - pTableData->keyLast = 0; - pTableData->numOfRows = 0; - - uint8_t skipListCreateFlags; - if(pCfg->update == TD_ROW_DISCARD_UPDATE) - skipListCreateFlags = SL_DISCARD_DUP_KEY; - else - skipListCreateFlags = SL_UPDATE_DUP_KEY; - - pTableData->pData = - tSkipListCreate(TSDB_DATA_SKIPLIST_LEVEL, TSDB_DATA_TYPE_TIMESTAMP, TYPE_BYTES[TSDB_DATA_TYPE_TIMESTAMP], - tkeyComparFn, skipListCreateFlags, tsdbGetTsTupleKey); - if (pTableData->pData == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - free(pTableData); - return NULL; - } - - T_REF_INC(pTableData); - - return pTableData; -} - -static void tsdbFreeTableData(STableData *pTableData) { - if (pTableData) { - int32_t ref = T_REF_DEC(pTableData); - if (ref == 0) { - tSkipListDestroy(pTableData->pData); - free(pTableData); - } - } -} - -static char *tsdbGetTsTupleKey(const void *data) { return memRowTuple((SMemRow)data); } - -static int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables) { - ASSERT(pMemTable->maxTables < maxTables); - - STableData **pTableData = (STableData **)calloc(maxTables, sizeof(STableData *)); - if (pTableData == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - memcpy((void *)pTableData, (void *)pMemTable->tData, sizeof(STableData *) * pMemTable->maxTables); - - STableData **tData = pMemTable->tData; - - taosWLockLatch(&(pMemTable->latch)); - pMemTable->maxTables = maxTables; - pMemTable->tData = pTableData; - taosWUnLockLatch(&(pMemTable->latch)); - - tfree(tData); - - return 0; -} - -static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, SMemRow row) { - if (pCols) { - if (*ppSchema == NULL || schemaVersion(*ppSchema) != memRowVersion(row)) { - *ppSchema = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row)); - if (*ppSchema == NULL) { - ASSERT(false); - return -1; - } - } - - tdAppendMemRowToDataCol(row, *ppSchema, pCols, true); - } - - return 0; -} - -static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter) { - if (pBlock->dataLen <= 0) return -1; - pIter->totalLen = pBlock->dataLen; - pIter->len = 0; - pIter->row = (SMemRow)(pBlock->data + pBlock->schemaLen); - return 0; -} - -static SMemRow tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter) { - SMemRow row = pIter->row; // firstly, get current row - if (row == NULL) return NULL; - - pIter->len += memRowTLen(row); - if (pIter->len >= pIter->totalLen) { // reach the end - pIter->row = NULL; - } else { - pIter->row = (char *)row + memRowTLen(row); // secondly, move to next row - } - - return row; -} - -static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, SMemRow row, TSKEY minKey, TSKEY maxKey, - TSKEY now) { - TSKEY rowKey = memRowKey(row); - if (rowKey < minKey || rowKey > maxKey) { - tsdbError("vgId:%d table %s tid %d uid %" PRIu64 " timestamp is out of range! now %" PRId64 " minKey %" PRId64 - " maxKey %" PRId64 " row key %" PRId64, - REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), now, minKey, maxKey, - rowKey); - terrno = TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE; - return -1; - } - - return 0; -} - -static int tsdbScanAndConvertSubmitMsg(STsdbRepo *pRepo, SSubmitMsg *pMsg) { - ASSERT(pMsg != NULL); - STsdbMeta * pMeta = pRepo->tsdbMeta; - SSubmitMsgIter msgIter = {0}; - SSubmitBlk * pBlock = NULL; - SSubmitBlkIter blkIter = {0}; - SMemRow row = NULL; - TSKEY now = taosGetTimestamp(pRepo->config.precision); - TSKEY minKey = now - tsTickPerDay[pRepo->config.precision] * pRepo->config.keep; - TSKEY maxKey = now + tsTickPerDay[pRepo->config.precision] * pRepo->config.daysPerFile; - - terrno = TSDB_CODE_SUCCESS; - pMsg->length = htonl(pMsg->length); - pMsg->numOfBlocks = htonl(pMsg->numOfBlocks); - - if (tsdbInitSubmitMsgIter(pMsg, &msgIter) < 0) return -1; - while (true) { - if (tsdbGetSubmitMsgNext(&msgIter, &pBlock) < 0) return -1; - if (pBlock == NULL) break; - - pBlock->uid = htobe64(pBlock->uid); - pBlock->tid = htonl(pBlock->tid); - pBlock->sversion = htonl(pBlock->sversion); - pBlock->dataLen = htonl(pBlock->dataLen); - pBlock->schemaLen = htonl(pBlock->schemaLen); - pBlock->numOfRows = htons(pBlock->numOfRows); - - if (pBlock->tid <= 0 || pBlock->tid >= pMeta->maxTables) { - tsdbError("vgId:%d failed to get table to insert data, uid %" PRIu64 " tid %d", REPO_ID(pRepo), pBlock->uid, - pBlock->tid); - terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; - return -1; - } - - STable *pTable = pMeta->tables[pBlock->tid]; - if (pTable == NULL || TABLE_UID(pTable) != pBlock->uid) { - tsdbError("vgId:%d failed to get table to insert data, uid %" PRIu64 " tid %d", REPO_ID(pRepo), pBlock->uid, - pBlock->tid); - terrno = TSDB_CODE_TDB_INVALID_TABLE_ID; - return -1; - } - - if (TABLE_TYPE(pTable) == TSDB_SUPER_TABLE) { - tsdbError("vgId:%d invalid action trying to insert a super table %s", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable)); - terrno = TSDB_CODE_TDB_INVALID_ACTION; - return -1; - } - - // Check schema version and update schema if needed - if (tsdbCheckTableSchema(pRepo, pBlock, pTable) < 0) { - if (terrno == TSDB_CODE_TDB_TABLE_RECONFIGURE) { - continue; - } else { - return -1; - } - } - - tsdbInitSubmitBlkIter(pBlock, &blkIter); - while ((row = tsdbGetSubmitBlkNext(&blkIter)) != NULL) { - if (tsdbCheckRowRange(pRepo, pTable, row, minKey, maxKey, now) < 0) { - return -1; - } - } - } - - if (terrno != TSDB_CODE_SUCCESS) return -1; - return 0; -} - -//row1 has higher priority -static SMemRow tsdbInsertDupKeyMerge(SMemRow row1, SMemRow row2, STsdbRepo* pRepo, - STSchema **ppSchema1, STSchema **ppSchema2, - STable* pTable, int32_t* pPoints, SMemRow* pLastRow) { - - //for compatiblity, duplicate key inserted when update=0 should be also calculated as affected rows! - if(row1 == NULL && row2 == NULL && pRepo->config.update == TD_ROW_DISCARD_UPDATE) { - (*pPoints)++; - return NULL; - } - - if(row2 == NULL || pRepo->config.update != TD_ROW_PARTIAL_UPDATE) { - void* pMem = tsdbAllocBytes(pRepo, memRowTLen(row1)); - if(pMem == NULL) return NULL; - memRowCpy(pMem, row1); - (*pPoints)++; - *pLastRow = pMem; - return pMem; - } - - STSchema *pSchema1 = *ppSchema1; - STSchema *pSchema2 = *ppSchema2; - SMergeBuf * pBuf = &pRepo->mergeBuf; - int dv1 = memRowVersion(row1); - int dv2 = memRowVersion(row2); - if(pSchema1 == NULL || schemaVersion(pSchema1) != dv1) { - if(pSchema2 != NULL && schemaVersion(pSchema2) == dv1) { - *ppSchema1 = pSchema2; - } else { - *ppSchema1 = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row1)); - } - pSchema1 = *ppSchema1; - } - - if(pSchema2 == NULL || schemaVersion(pSchema2) != dv2) { - if(schemaVersion(pSchema1) == dv2) { - pSchema2 = pSchema1; - } else { - *ppSchema2 = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row2)); - pSchema2 = *ppSchema2; - } - } - - SMemRow tmp = tsdbMergeTwoRows(pBuf, row1, row2, pSchema1, pSchema2); - - void* pMem = tsdbAllocBytes(pRepo, memRowTLen(tmp)); - if(pMem == NULL) return NULL; - memRowCpy(pMem, tmp); - - (*pPoints)++; - *pLastRow = pMem; - return pMem; -} - -static void* tsdbInsertDupKeyMergePacked(void** args) { - return tsdbInsertDupKeyMerge(args[0], args[1], args[2], (STSchema**)&args[3], (STSchema**)&args[4], args[5], args[6], args[7]); -} - -static void tsdbSetupSkipListHookFns(SSkipList* pSkipList, STsdbRepo *pRepo, STable *pTable, int32_t* pPoints, SMemRow* pLastRow) { - - if(pSkipList->insertHandleFn == NULL) { - tGenericSavedFunc *dupHandleSavedFunc = genericSavedFuncInit((GenericVaFunc)&tsdbInsertDupKeyMergePacked, 9); - dupHandleSavedFunc->args[2] = pRepo; - dupHandleSavedFunc->args[3] = NULL; - dupHandleSavedFunc->args[4] = NULL; - dupHandleSavedFunc->args[5] = pTable; - pSkipList->insertHandleFn = dupHandleSavedFunc; - } - pSkipList->insertHandleFn->args[6] = pPoints; - pSkipList->insertHandleFn->args[7] = pLastRow; -} - -static int tsdbInsertDataToTable(STsdbRepo* pRepo, SSubmitBlk* pBlock, int32_t *pAffectedRows) { - - STsdbMeta *pMeta = pRepo->tsdbMeta; - int32_t points = 0; - STable *pTable = NULL; - SSubmitBlkIter blkIter = {0}; - SMemTable *pMemTable = NULL; - STableData *pTableData = NULL; - STsdbCfg *pCfg = &(pRepo->config); - - tsdbInitSubmitBlkIter(pBlock, &blkIter); - if(blkIter.row == NULL) return 0; - TSKEY firstRowKey = memRowKey(blkIter.row); - - tsdbAllocBytes(pRepo, 0); - pMemTable = pRepo->mem; - - ASSERT(pMemTable != NULL); - ASSERT(pBlock->tid < pMeta->maxTables); - - pTable = pMeta->tables[pBlock->tid]; - - ASSERT(pTable != NULL && TABLE_UID(pTable) == pBlock->uid); - - - if (TABLE_TID(pTable) >= pMemTable->maxTables) { - if (tsdbAdjustMemMaxTables(pMemTable, pMeta->maxTables) < 0) { - return -1; - } - } - pTableData = pMemTable->tData[TABLE_TID(pTable)]; - - if (pTableData == NULL || pTableData->uid != TABLE_UID(pTable)) { - if (pTableData != NULL) { - taosWLockLatch(&(pMemTable->latch)); - pMemTable->tData[TABLE_TID(pTable)] = NULL; - tsdbFreeTableData(pTableData); - taosWUnLockLatch(&(pMemTable->latch)); - } - - pTableData = tsdbNewTableData(pCfg, pTable); - if (pTableData == NULL) { - tsdbError("vgId:%d failed to insert data to table %s uid %" PRId64 " tid %d since %s", REPO_ID(pRepo), - TABLE_CHAR_NAME(pTable), TABLE_UID(pTable), TABLE_TID(pTable), tstrerror(terrno)); - return -1; - } - - pRepo->mem->tData[TABLE_TID(pTable)] = pTableData; - } - - ASSERT((pTableData != NULL) && pTableData->uid == TABLE_UID(pTable)); - - SMemRow lastRow = NULL; - int64_t osize = SL_SIZE(pTableData->pData); - tsdbSetupSkipListHookFns(pTableData->pData, pRepo, pTable, &points, &lastRow); - tSkipListPutBatchByIter(pTableData->pData, &blkIter, (iter_next_fn_t)tsdbGetSubmitBlkNext); - int64_t dsize = SL_SIZE(pTableData->pData) - osize; - (*pAffectedRows) += points; - - - if(lastRow != NULL) { - TSKEY lastRowKey = memRowKey(lastRow); - if (pMemTable->keyFirst > firstRowKey) pMemTable->keyFirst = firstRowKey; - pMemTable->numOfRows += dsize; - - if (pTableData->keyFirst > firstRowKey) pTableData->keyFirst = firstRowKey; - pTableData->numOfRows += dsize; - if (pMemTable->keyLast < lastRowKey) pMemTable->keyLast = lastRowKey; - if (pTableData->keyLast < lastRowKey) pTableData->keyLast = lastRowKey; - if (tsdbUpdateTableLatestInfo(pRepo, pTable, lastRow) < 0) { - return -1; - } - } - - STSchema *pSchema = tsdbGetTableSchemaByVersion(pTable, pBlock->sversion); - pRepo->stat.pointsWritten += points * schemaNCols(pSchema); - pRepo->stat.totalStorage += points * schemaVLen(pSchema); - - return 0; -} - - -static int tsdbInitSubmitMsgIter(SSubmitMsg *pMsg, SSubmitMsgIter *pIter) { - if (pMsg == NULL) { - terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; - return -1; - } - - pIter->totalLen = pMsg->length; - pIter->len = 0; - pIter->pMsg = pMsg; - if (pMsg->length <= TSDB_SUBMIT_MSG_HEAD_SIZE) { - terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; - return -1; - } - - return 0; -} - -static int tsdbGetSubmitMsgNext(SSubmitMsgIter *pIter, SSubmitBlk **pPBlock) { - if (pIter->len == 0) { - pIter->len += TSDB_SUBMIT_MSG_HEAD_SIZE; - } else { - SSubmitBlk *pSubmitBlk = (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len); - pIter->len += (sizeof(SSubmitBlk) + pSubmitBlk->dataLen + pSubmitBlk->schemaLen); - } - - if (pIter->len > pIter->totalLen) { - terrno = TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP; - *pPBlock = NULL; - return -1; - } - - *pPBlock = (pIter->len == pIter->totalLen) ? NULL : (SSubmitBlk *)POINTER_SHIFT(pIter->pMsg, pIter->len); - - return 0; -} - -static int tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable) { - ASSERT(pTable != NULL); - - STSchema *pSchema = tsdbGetTableSchemaImpl(pTable, false, false, -1); - int sversion = schemaVersion(pSchema); - - if (pBlock->sversion == sversion) { - return 0; - } else { - if (TABLE_TYPE(pTable) == TSDB_STREAM_TABLE) { // stream table is not allowed to change schema - terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; - return -1; - } - } - - if (pBlock->sversion > sversion) { // may need to update table schema - if (pBlock->schemaLen > 0) { - tsdbDebug( - "vgId:%d table %s tid %d uid %" PRIu64 " schema version %d is out of data, client version %d, update...", - REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), sversion, pBlock->sversion); - ASSERT(pBlock->schemaLen % sizeof(STColumn) == 0); - int numOfCols = pBlock->schemaLen / sizeof(STColumn); - STColumn *pTCol = (STColumn *)pBlock->data; - - STSchemaBuilder schemaBuilder = {0}; - if (tdInitTSchemaBuilder(&schemaBuilder, pBlock->sversion) < 0) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tsdbError("vgId:%d failed to update schema of table %s since %s", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), - tstrerror(terrno)); - return -1; - } - - for (int i = 0; i < numOfCols; i++) { - if (tdAddColToSchema(&schemaBuilder, pTCol[i].type, htons(pTCol[i].colId), htons(pTCol[i].bytes)) < 0) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tsdbError("vgId:%d failed to update schema of table %s since %s", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), - tstrerror(terrno)); - tdDestroyTSchemaBuilder(&schemaBuilder); - return -1; - } - } - - STSchema *pNSchema = tdGetSchemaFromBuilder(&schemaBuilder); - if (pNSchema == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - tdDestroyTSchemaBuilder(&schemaBuilder); - return -1; - } - - tdDestroyTSchemaBuilder(&schemaBuilder); - tsdbUpdateTableSchema(pRepo, pTable, pNSchema, true); - } else { - tsdbDebug( - "vgId:%d table %s tid %d uid %" PRIu64 " schema version %d is out of data, client version %d, reconfigure...", - REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable), sversion, pBlock->sversion); - terrno = TSDB_CODE_TDB_TABLE_RECONFIGURE; - return -1; - } - } else { - ASSERT(pBlock->sversion >= 0); - if (tsdbGetTableSchemaImpl(pTable, false, false, pBlock->sversion) == NULL) { - tsdbError("vgId:%d invalid submit schema version %d to table %s tid %d from client", REPO_ID(pRepo), - pBlock->sversion, TABLE_CHAR_NAME(pTable), TABLE_TID(pTable)); - terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; - return -1; - } - } - - return 0; -} - - -static void updateTableLatestColumn(STsdbRepo *pRepo, STable *pTable, SMemRow row) { - tsdbDebug("vgId:%d updateTableLatestColumn, %s row version:%d", REPO_ID(pRepo), pTable->name->data, - memRowVersion(row)); - - STSchema* pSchema = tsdbGetTableLatestSchema(pTable); - if (tsdbUpdateLastColSchema(pTable, pSchema) < 0) { - return; - } - - pSchema = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row)); - if (pSchema == NULL) { - return; - } - - SDataCol *pLatestCols = pTable->lastCols; - int32_t kvIdx = 0; - - for (int16_t j = 0; j < schemaNCols(pSchema); j++) { - STColumn *pTCol = schemaColAt(pSchema, j); - // ignore not exist colId - int16_t idx = tsdbGetLastColumnsIndexByColId(pTable, pTCol->colId); - if (idx == -1) { - continue; - } - - void *value = NULL; - - value = tdGetMemRowDataOfColEx(row, pTCol->colId, (int8_t)pTCol->type, - TD_DATA_ROW_HEAD_SIZE + pSchema->columns[j].offset, &kvIdx); - - if ((value == NULL) || isNull(value, pTCol->type)) { - continue; - } - - SDataCol *pDataCol = &(pLatestCols[idx]); - if (pDataCol->pData == NULL) { - pDataCol->pData = malloc(pTCol->bytes); - pDataCol->bytes = pTCol->bytes; - } else if (pDataCol->bytes < pTCol->bytes) { - pDataCol->pData = realloc(pDataCol->pData, pTCol->bytes); - pDataCol->bytes = pTCol->bytes; - } - // the actual value size - uint16_t bytes = IS_VAR_DATA_TYPE(pTCol->type) ? varDataTLen(value) : pTCol->bytes; - // the actual data size CANNOT larger than column size - assert(pTCol->bytes >= bytes); - memcpy(pDataCol->pData, value, bytes); - //tsdbInfo("updateTableLatestColumn vgId:%d cache column %d for %d,%s", REPO_ID(pRepo), j, pDataCol->bytes, (char*)pDataCol->pData); - pDataCol->ts = memRowKey(row); - } -} - -static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, SMemRow row) { - STsdbCfg *pCfg = &pRepo->config; - - // if cacheLastRow config has been reset, free the lastRow - if (!pCfg->cacheLastRow && pTable->lastRow != NULL) { - SMemRow cachedLastRow = pTable->lastRow; - TSDB_WLOCK_TABLE(pTable); - pTable->lastRow = NULL; - TSDB_WUNLOCK_TABLE(pTable); - taosTZfree(cachedLastRow); - } - - if (tsdbGetTableLastKeyImpl(pTable) <= memRowKey(row)) { - if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) { - SMemRow nrow = pTable->lastRow; - if (taosTSizeof(nrow) < memRowTLen(row)) { - SMemRow orow = nrow; - nrow = taosTMalloc(memRowTLen(row)); - if (nrow == NULL) { - terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; - return -1; - } - - memRowCpy(nrow, row); - TSDB_WLOCK_TABLE(pTable); - pTable->lastKey = memRowKey(row); - pTable->lastRow = nrow; - TSDB_WUNLOCK_TABLE(pTable); - taosTZfree(orow); - } else { - TSDB_WLOCK_TABLE(pTable); - pTable->lastKey = memRowKey(row); - memRowCpy(nrow, row); - TSDB_WUNLOCK_TABLE(pTable); - } - } else { - pTable->lastKey = memRowKey(row); - } - - if (CACHE_LAST_NULL_COLUMN(pCfg)) { - updateTableLatestColumn(pRepo, pTable, row); - } - } - return 0; -} diff --git a/src/wal/CMakeLists.txt b/src/wal/CMakeLists.txt deleted file mode 100644 index 0d9be42bd5..0000000000 --- a/src/wal/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -PROJECT(TDengine) - -ADD_DEFINITIONS(-DWAL_CHECKSUM_WHOLE) - -INCLUDE_DIRECTORIES(inc) -AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SRC) - -ADD_LIBRARY(twal ${SRC}) -TARGET_LINK_LIBRARIES(twal tutil common) -ADD_SUBDIRECTORY(test) diff --git a/src/wal/test/CMakeLists.txt b/src/wal/test/CMakeLists.txt deleted file mode 100644 index c5bc4198f1..0000000000 --- a/src/wal/test/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -PROJECT(TDengine) - -IF (TD_LINUX) - INCLUDE_DIRECTORIES(../inc) - - LIST(APPEND WALTEST_SRC ./waltest.c) - ADD_EXECUTABLE(waltest ${WALTEST_SRC}) - TARGET_LINK_LIBRARIES(waltest twal os tutil) - -ENDIF () - -IF (TD_DARWIN) - INCLUDE_DIRECTORIES(../inc) - - LIST(APPEND WALTEST_SRC ./waltest.c) - ADD_EXECUTABLE(waltest ${WALTEST_SRC}) - TARGET_LINK_LIBRARIES(waltest twal os tutil) - -ENDIF () -