Merge remote-tracking branch 'origin/3.0' into feature/3.0_wxy
This commit is contained in:
commit
498b5b3b16
|
@ -7,4 +7,4 @@ FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
|
|||
# [Optional] Uncomment this section to install additional packages.
|
||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||
RUN apt-get update && apt-get -y install tree vim tmux
|
||||
RUN apt-get update && apt-get -y install tree vim tmux python3-pip
|
||||
|
|
|
@ -110,7 +110,7 @@ execute_process(COMMAND "${CMAKE_COMMAND}" --build .
|
|||
# ================================================================================================
|
||||
# googletest
|
||||
if(${BUILD_TEST})
|
||||
add_subdirectory(googletest)
|
||||
add_subdirectory(googletest EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
gtest
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cpp-stub/src>
|
||||
|
@ -143,7 +143,7 @@ set(CMAKE_PROJECT_INCLUDE_BEFORE "${TD_SUPPORT_DIR}/EnableCMP0048.txt.in")
|
|||
option(ENABLE_CJSON_TEST "Enable building cJSON test" OFF)
|
||||
option(CJSON_OVERRIDE_BUILD_SHARED_LIBS "Override BUILD_SHARED_LIBS with CJSON_BUILD_SHARED_LIBS" ON)
|
||||
option(CJSON_BUILD_SHARED_LIBS "Overrides BUILD_SHARED_LIBS if CJSON_OVERRIDE_BUILD_SHARED_LIBS is enabled" OFF)
|
||||
add_subdirectory(cJson)
|
||||
add_subdirectory(cJson EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
cjson
|
||||
# see https://stackoverflow.com/questions/25676277/cmake-target-include-directories-prints-an-error-when-i-try-to-add-the-source
|
||||
|
@ -152,7 +152,7 @@ target_include_directories(
|
|||
unset(CMAKE_PROJECT_INCLUDE_BEFORE)
|
||||
|
||||
# lz4
|
||||
add_subdirectory(lz4/build/cmake)
|
||||
add_subdirectory(lz4/build/cmake EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
lz4_static
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/lz4/lib
|
||||
|
@ -160,7 +160,7 @@ target_include_directories(
|
|||
|
||||
# zlib
|
||||
set(CMAKE_PROJECT_INCLUDE_BEFORE "${TD_SUPPORT_DIR}/EnableCMP0048.txt.in")
|
||||
add_subdirectory(zlib)
|
||||
add_subdirectory(zlib EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
zlibstatic
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/zlib
|
||||
|
@ -176,7 +176,7 @@ unset(CMAKE_PROJECT_INCLUDE_BEFORE)
|
|||
# leveldb
|
||||
if(${BUILD_WITH_LEVELDB})
|
||||
option(LEVELDB_BUILD_TESTS "" OFF)
|
||||
add_subdirectory(leveldb)
|
||||
add_subdirectory(leveldb EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
leveldb
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/leveldb/include>
|
||||
|
@ -192,7 +192,7 @@ if(${BUILD_WITH_ROCKSDB})
|
|||
option(WITH_TOOLS "" OFF)
|
||||
option(WITH_LIBURING "" OFF)
|
||||
option(ROCKSDB_BUILD_SHARED "Build shared versions of the RocksDB libraries" OFF)
|
||||
add_subdirectory(rocksdb)
|
||||
add_subdirectory(rocksdb EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
rocksdb
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include>
|
||||
|
@ -203,7 +203,7 @@ endif(${BUILD_WITH_ROCKSDB})
|
|||
# To support build on ubuntu: sudo apt-get install libboost-all-dev
|
||||
if(${BUILD_WITH_LUCENE})
|
||||
option(ENABLE_TEST "Enable the tests" OFF)
|
||||
add_subdirectory(lucene)
|
||||
add_subdirectory(lucene EXCLUDE_FROM_ALL)
|
||||
target_include_directories(
|
||||
lucene++
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/lucene/include>
|
||||
|
@ -213,14 +213,14 @@ endif(${BUILD_WITH_LUCENE})
|
|||
|
||||
# NuRaft
|
||||
if(${BUILD_WITH_NURAFT})
|
||||
add_subdirectory(nuraft)
|
||||
add_subdirectory(nuraft EXCLUDE_FROM_ALL)
|
||||
endif(${BUILD_WITH_NURAFT})
|
||||
|
||||
# pthread
|
||||
if(${BUILD_PTHREAD})
|
||||
set(CMAKE_BUILD_TYPE release)
|
||||
add_definitions(-DPTW32_STATIC_LIB)
|
||||
add_subdirectory(pthread)
|
||||
add_subdirectory(pthread EXCLUDE_FROM_ALL)
|
||||
set_target_properties(libpthreadVC3 PROPERTIES OUTPUT_NAME pthread)
|
||||
add_library(pthread STATIC IMPORTED GLOBAL)
|
||||
SET_PROPERTY(TARGET pthread PROPERTY IMPORTED_LOCATION ${LIBRARY_OUTPUT_PATH}/pthread.lib)
|
||||
|
@ -228,12 +228,12 @@ endif()
|
|||
|
||||
# iconv
|
||||
if(${BUILD_WITH_ICONV})
|
||||
add_subdirectory(iconv)
|
||||
add_subdirectory(iconv EXCLUDE_FROM_ALL)
|
||||
endif(${BUILD_WITH_ICONV})
|
||||
|
||||
# wingetopt
|
||||
if(${BUILD_WINGETOPT})
|
||||
add_subdirectory(wingetopt)
|
||||
add_subdirectory(wingetopt EXCLUDE_FROM_ALL)
|
||||
endif(${BUILD_WINGETOPT})
|
||||
|
||||
# msvcregex
|
||||
|
@ -293,7 +293,7 @@ if(${BUILD_WITH_UV})
|
|||
MESSAGE("Windows need set no-sign-compare")
|
||||
add_compile_options(-Wno-sign-compare)
|
||||
endif ()
|
||||
add_subdirectory(libuv)
|
||||
add_subdirectory(libuv EXCLUDE_FROM_ALL)
|
||||
endif(${BUILD_WITH_UV})
|
||||
|
||||
# BDB
|
||||
|
@ -334,5 +334,5 @@ endif(${BUILD_WITH_SQLITE})
|
|||
# Build test
|
||||
# ================================================================================================
|
||||
if(${BUILD_DEPENDENCY_TESTS})
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(test EXCLUDE_FROM_ALL)
|
||||
endif(${BUILD_DEPENDENCY_TESTS})
|
||||
|
|
|
@ -438,6 +438,7 @@ typedef struct {
|
|||
|
||||
int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp);
|
||||
int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp);
|
||||
void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
int16_t colId; // column id
|
||||
|
@ -1332,7 +1333,7 @@ int32_t tDeserializeSCMCreateTopicRsp(void* buf, int32_t bufLen, SCMCreateTopicR
|
|||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
} SMqConsumerLostMsg;
|
||||
} SMqConsumerLostMsg, SMqConsumerRecoverMsg;
|
||||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
|
@ -2383,9 +2384,9 @@ typedef struct {
|
|||
int32_t epoch;
|
||||
uint64_t reqId;
|
||||
int64_t consumerId;
|
||||
int64_t blockingTime;
|
||||
int64_t waitTime;
|
||||
int64_t currentOffset;
|
||||
} SMqPollReqV2;
|
||||
} SMqPollReq;
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
|
@ -2400,53 +2401,6 @@ typedef struct {
|
|||
SSchemaWrapper schema;
|
||||
} SMqSubTopicEp;
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
int64_t reqOffset;
|
||||
int64_t rspOffset;
|
||||
int32_t skipLogNum;
|
||||
int32_t dataLen;
|
||||
SArray* blockPos; // beginning pos for each SRetrieveTableRsp
|
||||
void* blockData; // serialized batched SRetrieveTableRsp
|
||||
} SMqPollRspV2;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqPollRspV2(void** buf, const SMqPollRspV2* pRsp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->reqOffset);
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->rspOffset);
|
||||
tlen += taosEncodeFixedI32(buf, pRsp->skipLogNum);
|
||||
tlen += taosEncodeFixedI32(buf, pRsp->dataLen);
|
||||
if (pRsp->dataLen != 0) {
|
||||
int32_t sz = taosArrayGetSize(pRsp->blockPos);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
int32_t blockPos = *(int32_t*)taosArrayGet(pRsp->blockPos, i);
|
||||
tlen += taosEncodeFixedI32(buf, blockPos);
|
||||
}
|
||||
tlen += taosEncodeBinary(buf, pRsp->blockData, pRsp->dataLen);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqPollRspV2(const void* buf, SMqPollRspV2* pRsp) {
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->reqOffset);
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->rspOffset);
|
||||
buf = taosDecodeFixedI32(buf, &pRsp->skipLogNum);
|
||||
buf = taosDecodeFixedI32(buf, &pRsp->dataLen);
|
||||
if (pRsp->dataLen != 0) {
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pRsp->blockPos = taosArrayInit(sz, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
int32_t blockPos;
|
||||
buf = taosDecodeFixedI32(buf, &blockPos);
|
||||
taosArrayPush(pRsp->blockPos, &blockPos);
|
||||
}
|
||||
buf = taosDecodeBinary(buf, &pRsp->blockData, pRsp->dataLen);
|
||||
}
|
||||
return (void*)buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
int64_t reqOffset;
|
||||
|
|
|
@ -145,10 +145,11 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_TOPIC, "mnode-alter-topic", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_DROP_TOPIC, "mnode-drop-topic", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_SUBSCRIBE, "mnode-subscribe", SCMSubscribeReq, SCMSubscribeRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_ASK_EP, "mnode-mq-ask-ep", SMqAskEpReq, SMqAskEpReq)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_TIMER, "mnode-mq-tmr", SMTimerReq, SMTimerReq)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_CONSUMER_LOST, "mnode-mq-consumer-lost", SMTimerReq, SMTimerReq)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_DO_REBALANCE, "mnode-mq-do-rebalance", SMqDoRebalanceMsg, SMqDoRebalanceMsg)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_ASK_EP, "mnode-mq-ask-ep", SMqAskEpReq, SMqAskEpRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_TIMER, "mnode-mq-tmr", SMTimerReq, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_CONSUMER_LOST, "mnode-mq-consumer-lost", SMqConsumerLostMsg, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_CONSUMER_RECOVER, "mnode-mq-consumer-recover", SMqConsumerRecoverMsg, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_DO_REBALANCE, "mnode-mq-do-rebalance", SMqDoRebalanceMsg, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_COMMIT_OFFSET, "mnode-mq-commit-offset", SMqCMCommitOffsetReq, SMqCMCommitOffsetRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_CREATE_STREAM, "mnode-create-stream", SCMCreateStreamReq, SCMCreateStreamRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_STREAM, "mnode-alter-stream", NULL, NULL)
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
#include "os.h"
|
||||
|
||||
#include "thash.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tlog.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -135,7 +140,7 @@ typedef enum {
|
|||
typedef struct SSdb SSdb;
|
||||
typedef int32_t (*SdbInsertFp)(SSdb *pSdb, void *pObj);
|
||||
typedef int32_t (*SdbUpdateFp)(SSdb *pSdb, void *pSrcObj, void *pDstObj);
|
||||
typedef int32_t (*SdbDeleteFp)(SSdb *pSdb, void *pObj);
|
||||
typedef int32_t (*SdbDeleteFp)(SSdb *pSdb, void *pObj, bool callFunc);
|
||||
typedef int32_t (*SdbDeployFp)(SMnode *pMnode);
|
||||
typedef SSdbRow *(*SdbDecodeFp)(SSdbRaw *pRaw);
|
||||
typedef SSdbRaw *(*SdbEncodeFp)(void *pObj);
|
||||
|
@ -326,9 +331,29 @@ int32_t sdbGetRawSoftVer(SSdbRaw *pRaw, int8_t *sver);
|
|||
int32_t sdbGetRawTotalSize(SSdbRaw *pRaw);
|
||||
|
||||
SSdbRow *sdbAllocRow(int32_t objSize);
|
||||
void sdbFreeRow(SSdb *pSdb, SSdbRow *pRow);
|
||||
void sdbFreeRow(SSdb *pSdb, SSdbRow *pRow, bool callFunc);
|
||||
void *sdbGetRowObj(SSdbRow *pRow);
|
||||
|
||||
typedef struct SSdb {
|
||||
SMnode *pMnode;
|
||||
char *currDir;
|
||||
char *syncDir;
|
||||
char *tmpDir;
|
||||
int64_t lastCommitVer;
|
||||
int64_t curVer;
|
||||
int64_t tableVer[SDB_MAX];
|
||||
int64_t maxId[SDB_MAX];
|
||||
EKeyType keyTypes[SDB_MAX];
|
||||
SHashObj *hashObjs[SDB_MAX];
|
||||
SRWLatch locks[SDB_MAX];
|
||||
SdbInsertFp insertFps[SDB_MAX];
|
||||
SdbUpdateFp updateFps[SDB_MAX];
|
||||
SdbDeleteFp deleteFps[SDB_MAX];
|
||||
SdbDeployFp deployFps[SDB_MAX];
|
||||
SdbEncodeFp encodeFps[SDB_MAX];
|
||||
SdbDecodeFp decodeFps[SDB_MAX];
|
||||
} SSdb;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ typedef struct SReadHandle {
|
|||
void* reader;
|
||||
void* meta;
|
||||
void* config;
|
||||
void* vnode;
|
||||
} SReadHandle;
|
||||
|
||||
#define STREAM_DATA_TYPE_SUBMIT_BLOCK 0x1
|
||||
|
|
|
@ -59,9 +59,13 @@ typedef struct {
|
|||
void * pNode;
|
||||
} SNodeMsg;
|
||||
|
||||
typedef void (*RpcCfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||
typedef void (*RpcCfp)(void *parent, SRpcMsg *, SEpSet *rf);
|
||||
typedef int (*RpcAfp)(void *parent, char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
typedef int (*RpcRfp)(void *parent, SRpcMsg *, SEpSet *);
|
||||
///
|
||||
// // SRpcMsg code
|
||||
// REDIERE,
|
||||
// NOT READY, EpSet
|
||||
typedef bool (*RpcRfp)(int32_t code);
|
||||
|
||||
typedef struct SRpcInit {
|
||||
uint16_t localPort; // local port
|
||||
|
|
|
@ -72,8 +72,6 @@ extern "C" {
|
|||
#define WAL_FILE_LEN (WAL_PATH_LEN + 32)
|
||||
#define WAL_MAGIC 0xFAFBFCFDULL
|
||||
|
||||
#define WAL_CUR_FAILED 1
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef enum {
|
||||
TAOS_WAL_NOLOG = 0,
|
||||
|
|
|
@ -137,7 +137,8 @@ typedef struct TdEpoll *TdEpollPtr;
|
|||
int32_t taosSendto(TdSocketPtr pSocket, void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
|
||||
int32_t taosWriteSocket(TdSocketPtr pSocket, void *msg, int len);
|
||||
int32_t taosReadSocket(TdSocketPtr pSocket, void *msg, int len);
|
||||
int32_t taosReadFromSocket(TdSocketPtr pSocket, void *buf, int32_t len, int32_t flags, struct sockaddr *destAddr, int *addrLen);
|
||||
int32_t taosReadFromSocket(TdSocketPtr pSocket, void *buf, int32_t len, int32_t flags, struct sockaddr *destAddr,
|
||||
int *addrLen);
|
||||
int32_t taosCloseSocketNoCheck1(SocketFd fd);
|
||||
int32_t taosCloseSocket(TdSocketPtr *ppSocket);
|
||||
int32_t taosCloseSocketServer(TdSocketServerPtr *ppSocketServer);
|
||||
|
@ -156,6 +157,8 @@ int32_t taosNonblockwrite(TdSocketPtr pSocket, char *ptr, int32_t nbytes);
|
|||
int64_t taosCopyFds(TdSocketPtr pSrcSocket, TdSocketPtr pDestSocket, int64_t len);
|
||||
void taosWinSocketInit();
|
||||
|
||||
int taosCreateSocketWithTimeOutOpt(uint32_t conn_timeout_sec);
|
||||
|
||||
TdSocketPtr taosOpenUdpSocket(uint32_t localIp, uint16_t localPort);
|
||||
TdSocketPtr taosOpenTcpClientSocket(uint32_t ip, uint16_t port, uint32_t localIp);
|
||||
TdSocketServerPtr taosOpenTcpServerSocket(uint32_t ip, uint16_t port);
|
||||
|
|
|
@ -268,14 +268,13 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_TOPIC_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E1)
|
||||
#define TSDB_CODE_MND_TOO_MANY_TOPICS TAOS_DEF_ERROR_CODE(0, 0x03E2)
|
||||
#define TSDB_CODE_MND_INVALID_TOPIC TAOS_DEF_ERROR_CODE(0, 0x03E3)
|
||||
#define TSDB_CODE_MND_INVALID_TOPIC_OPTION TAOS_DEF_ERROR_CODE(0, 0x03E4)
|
||||
#define TSDB_CODE_MND_TOPIC_OPTION_UNCHNAGED TAOS_DEF_ERROR_CODE(0, 0x03E5)
|
||||
#define TSDB_CODE_MND_NAME_CONFLICT_WITH_STB TAOS_DEF_ERROR_CODE(0, 0x03E6)
|
||||
#define TSDB_CODE_MND_CONSUMER_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E7)
|
||||
#define TSDB_CODE_MND_UNSUPPORTED_TOPIC TAOS_DEF_ERROR_CODE(0, 0x03E8)
|
||||
#define TSDB_CODE_MND_SUBSCRIBE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E9)
|
||||
#define TSDB_CODE_MND_OFFSET_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03EA)
|
||||
#define TSDB_CODE_MND_CONSUMER_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x03EB)
|
||||
#define TSDB_CODE_MND_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x03E4)
|
||||
#define TSDB_CODE_MND_INVALID_TOPIC_OPTION TAOS_DEF_ERROR_CODE(0, 0x03E5)
|
||||
#define TSDB_CODE_MND_CONSUMER_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E6)
|
||||
#define TSDB_CODE_MND_TOPIC_OPTION_UNCHNAGED TAOS_DEF_ERROR_CODE(0, 0x03E7)
|
||||
#define TSDB_CODE_MND_SUBSCRIBE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E8)
|
||||
#define TSDB_CODE_MND_OFFSET_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E9)
|
||||
#define TSDB_CODE_MND_CONSUMER_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x03EA)
|
||||
|
||||
// mnode-stream
|
||||
#define TSDB_CODE_MND_STREAM_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03F0)
|
||||
|
|
|
@ -205,7 +205,6 @@ SArray* taosArrayDup(const SArray* pSrc);
|
|||
*/
|
||||
SArray* taosArrayDeepCopy(const SArray* pSrc, FCopy deepCopy);
|
||||
|
||||
|
||||
/**
|
||||
* clear the array (remove all element)
|
||||
* @param pArray
|
||||
|
@ -272,6 +271,8 @@ void taosArraySortPWithExt(SArray* pArray, __ext_compar_fn_t fn, const void* par
|
|||
int32_t taosEncodeArray(void** buf, const SArray* pArray, FEncode encode);
|
||||
void* taosDecodeArray(const void* buf, SArray** pArray, FDecode decode, int32_t dataSz);
|
||||
|
||||
char* taosShowStrArray(const SArray* pArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -131,6 +131,7 @@ extern const int32_t TYPE_BYTES[15];
|
|||
#define TSDB_PERFS_TABLE_TOPICS "topics"
|
||||
#define TSDB_PERFS_TABLE_CONSUMERS "consumers"
|
||||
#define TSDB_PERFS_TABLE_SUBSCRIPTIONS "subscriptions"
|
||||
#define TSDB_PERFS_TABLE_OFFSETS "offsets"
|
||||
|
||||
#define TSDB_INDEX_TYPE_SMA "SMA"
|
||||
#define TSDB_INDEX_TYPE_FULLTEXT "FULLTEXT"
|
||||
|
|
|
@ -103,6 +103,7 @@ TAOS* taos_connect_internal(const char* ip, const char* user, const char* pass,
|
|||
|
||||
if (port) {
|
||||
epSet.epSet.eps[0].port = port;
|
||||
epSet.epSet.eps[1].port = port;
|
||||
}
|
||||
|
||||
char* key = getClusterKey(user, secretEncrypt, ip, port);
|
||||
|
@ -245,7 +246,12 @@ void setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t
|
|||
ASSERT(pSchema != NULL && numOfCols > 0);
|
||||
|
||||
pResInfo->numOfCols = numOfCols;
|
||||
// TODO handle memory leak
|
||||
if (pResInfo->fields != NULL) {
|
||||
taosMemoryFree(pResInfo->fields);
|
||||
}
|
||||
if (pResInfo->userFields != NULL) {
|
||||
taosMemoryFree(pResInfo->userFields);
|
||||
}
|
||||
pResInfo->fields = taosMemoryCalloc(numOfCols, sizeof(TAOS_FIELD));
|
||||
pResInfo->userFields = taosMemoryCalloc(numOfCols, sizeof(TAOS_FIELD));
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "parser.h"
|
||||
#include "planner.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tdef.h"
|
||||
#include "tglobal.h"
|
||||
|
@ -68,7 +67,7 @@ struct tmq_conf_t {
|
|||
char* user;
|
||||
char* pass;
|
||||
char* db;
|
||||
tmq_commit_cb* commit_cb;
|
||||
tmq_commit_cb* commitCb;
|
||||
};
|
||||
|
||||
struct tmq_t {
|
||||
|
@ -115,8 +114,8 @@ enum {
|
|||
|
||||
enum {
|
||||
TMQ_CONSUMER_STATUS__INIT = 0,
|
||||
TMQ_CONSUMER_STATUS__SUBSCRIBED,
|
||||
TMQ_CONSUMER_STATUS__READY,
|
||||
TMQ_CONSUMER_STATUS__NO_TOPIC,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -175,7 +174,6 @@ typedef struct {
|
|||
int32_t epoch;
|
||||
int32_t vgId;
|
||||
tsem_t rspSem;
|
||||
int32_t sync;
|
||||
} SMqPollCbParam;
|
||||
|
||||
typedef struct {
|
||||
|
@ -300,6 +298,7 @@ void tmqAssignDelayedHbTask(void* param, void* tmrId) {
|
|||
int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t));
|
||||
*pTaskType = TMQ_DELAYED_TASK__HB;
|
||||
taosWriteQitem(tmq->delayedTask, pTaskType);
|
||||
tsem_post(&tmq->rspSem);
|
||||
}
|
||||
|
||||
void tmqAssignDelayedCommitTask(void* param, void* tmrId) {
|
||||
|
@ -307,6 +306,7 @@ void tmqAssignDelayedCommitTask(void* param, void* tmrId) {
|
|||
int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t));
|
||||
*pTaskType = TMQ_DELAYED_TASK__COMMIT;
|
||||
taosWriteQitem(tmq->delayedTask, pTaskType);
|
||||
tsem_post(&tmq->rspSem);
|
||||
}
|
||||
|
||||
void tmqAssignDelayedReportTask(void* param, void* tmrId) {
|
||||
|
@ -314,6 +314,7 @@ void tmqAssignDelayedReportTask(void* param, void* tmrId) {
|
|||
int8_t* pTaskType = taosAllocateQitem(sizeof(int8_t));
|
||||
*pTaskType = TMQ_DELAYED_TASK__REPORT;
|
||||
taosWriteQitem(tmq->delayedTask, pTaskType);
|
||||
tsem_post(&tmq->rspSem);
|
||||
}
|
||||
|
||||
int32_t tmqHandleAllDelayedTask(tmq_t* tmq) {
|
||||
|
@ -364,7 +365,6 @@ int32_t tmqSubscribeCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
SMqSubscribeCbParam* pParam = (SMqSubscribeCbParam*)param;
|
||||
pParam->rspErr = code;
|
||||
tmq_t* tmq = pParam->tmq;
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__SUBSCRIBED);
|
||||
tsem_post(&pParam->rspSem);
|
||||
return 0;
|
||||
}
|
||||
|
@ -385,14 +385,16 @@ tmq_resp_err_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics) {
|
|||
}
|
||||
for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) {
|
||||
SMqClientTopic* topic = taosArrayGetP(tmq->clientTopics, i);
|
||||
tmq_list_append(*topics, strdup(topic->topicName));
|
||||
tmq_list_append(*topics, topic->topicName);
|
||||
}
|
||||
return TMQ_RESP_ERR__SUCCESS;
|
||||
}
|
||||
|
||||
tmq_resp_err_t tmq_unsubscribe(tmq_t* tmq) {
|
||||
tmq_list_t* lst = tmq_list_new();
|
||||
return tmq_subscribe(tmq, lst);
|
||||
tmq_resp_err_t rsp = tmq_subscribe(tmq, lst);
|
||||
tmq_list_destroy(lst);
|
||||
return rsp;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -475,7 +477,7 @@ tmq_t* tmq_consumer_new(tmq_conf_t* conf, char* errstr, int32_t errstrLen) {
|
|||
strcpy(pTmq->groupId, conf->groupId);
|
||||
pTmq->autoCommit = conf->autoCommit;
|
||||
pTmq->autoCommitInterval = conf->autoCommitInterval;
|
||||
pTmq->commit_cb = conf->commit_cb;
|
||||
pTmq->commit_cb = conf->commitCb;
|
||||
pTmq->resetOffsetCfg = conf->resetOffset;
|
||||
|
||||
// assign consumerId
|
||||
|
@ -655,13 +657,15 @@ tmq_resp_err_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
int64_t transporterId = 0;
|
||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
||||
|
||||
// avoid double free if msg is sent
|
||||
buf = NULL;
|
||||
|
||||
tsem_wait(¶m.rspSem);
|
||||
tsem_destroy(¶m.rspSem);
|
||||
|
||||
code = param.rspErr;
|
||||
if (code != 0) goto FAIL;
|
||||
|
||||
// TODO: add max retry cnt
|
||||
while (TSDB_CODE_MND_CONSUMER_NOT_READY == tmqAskEp(tmq, false)) {
|
||||
tscDebug("not ready, retry");
|
||||
taosMsleep(500);
|
||||
|
@ -678,7 +682,7 @@ tmq_resp_err_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
code = 0;
|
||||
FAIL:
|
||||
if (req.topicNames != NULL) taosArrayDestroyP(req.topicNames, taosMemoryFree);
|
||||
if (code != 0) {
|
||||
if (code != 0 && buf) {
|
||||
taosMemoryFree(buf);
|
||||
}
|
||||
return code;
|
||||
|
@ -686,7 +690,7 @@ FAIL:
|
|||
|
||||
void tmq_conf_set_offset_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb) {
|
||||
//
|
||||
conf->commit_cb = cb;
|
||||
conf->commitCb = cb;
|
||||
}
|
||||
|
||||
TAOS_RES* tmq_create_stream(TAOS* taos, const char* streamName, const char* tbName, const char* sql) {
|
||||
|
@ -798,7 +802,7 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
// do not write into queue since updating epoch reset
|
||||
tscWarn("msg discard from vg %d since from earlier epoch, rsp epoch %d, current epoch %d", pParam->vgId, msgEpoch,
|
||||
tmqEpoch);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -806,25 +810,6 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
tscWarn("mismatch rsp from vg %d, epoch %d, current epoch %d", pParam->vgId, msgEpoch, tmqEpoch);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (pParam->sync == 1) {
|
||||
/**pParam->msg = taosMemoryMalloc(sizeof(tmq_message_t));*/
|
||||
*pParam->msg = taosAllocateQitem(sizeof(tmq_message_t));
|
||||
if (*pParam->msg) {
|
||||
memcpy(*pParam->msg, pMsg->pData, sizeof(SMqRspHead));
|
||||
tDecodeSMqConsumeRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &((*pParam->msg)->consumeRsp));
|
||||
if ((*pParam->msg)->consumeRsp.numOfTopics != 0) {
|
||||
pVg->currentOffset = (*pParam->msg)->consumeRsp.rspOffset;
|
||||
}
|
||||
taosWriteQitem(tmq->mqueue, *pParam->msg);
|
||||
tsem_post(&pParam->rspSem);
|
||||
return 0;
|
||||
}
|
||||
tsem_post(&pParam->rspSem);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
SMqPollRspWrapper* pRspWrapper = taosAllocateQitem(sizeof(SMqPollRspWrapper));
|
||||
if (pRspWrapper == NULL) {
|
||||
tscWarn("msg discard from vg %d, epoch %d since out of memory", pParam->vgId, pParam->epoch);
|
||||
|
@ -843,14 +828,14 @@ int32_t tmqPollCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
pRspWrapper->msg.reqOffset, pRspWrapper->msg.rspOffset);
|
||||
|
||||
taosWriteQitem(tmq->mqueue, pRspWrapper);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
|
||||
return 0;
|
||||
CREATE_MSG_FAIL:
|
||||
if (pParam->epoch == tmq->epoch) {
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
}
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -927,6 +912,12 @@ bool tmqUpdateEp(tmq_t* tmq, int32_t epoch, SMqAskEpRsp* pRsp) {
|
|||
if (tmq->clientTopics) taosArrayDestroy(tmq->clientTopics);
|
||||
taosHashCleanup(pHash);
|
||||
tmq->clientTopics = newTopics;
|
||||
|
||||
if (taosArrayGetSize(tmq->clientTopics) == 0)
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__NO_TOPIC);
|
||||
else
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__READY);
|
||||
|
||||
atomic_store_32(&tmq->epoch, epoch);
|
||||
return set;
|
||||
}
|
||||
|
@ -955,9 +946,7 @@ int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
tDecodeSMqAskEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &rsp);
|
||||
/*printf("rsp epoch %ld sz %ld\n", rsp.epoch, rsp.topics->size);*/
|
||||
/*printf("tmq epoch %ld sz %ld\n", tmq->epoch, tmq->clientTopics->size);*/
|
||||
if (tmqUpdateEp(tmq, head->epoch, &rsp)) {
|
||||
atomic_store_8(&tmq->status, TMQ_CONSUMER_STATUS__READY);
|
||||
}
|
||||
tmqUpdateEp(tmq, head->epoch, &rsp);
|
||||
tDeleteSMqAskEpRsp(&rsp);
|
||||
} else {
|
||||
SMqAskEpRspWrapper* pWrapper = taosAllocateQitem(sizeof(SMqAskEpRspWrapper));
|
||||
|
@ -972,7 +961,7 @@ int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
tDecodeSMqAskEpRsp(POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), &pWrapper->msg);
|
||||
|
||||
taosWriteQitem(tmq->mqueue, pWrapper);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
taosMemoryFree(pParam);
|
||||
}
|
||||
|
||||
|
@ -1076,7 +1065,7 @@ tmq_resp_err_t tmq_seek(tmq_t* tmq, const tmq_topic_vgroup_t* offset) {
|
|||
return TMQ_RESP_ERR__FAIL;
|
||||
}
|
||||
|
||||
SMqPollReqV2* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t blockingTime, SMqClientTopic* pTopic, SMqClientVg* pVg) {
|
||||
SMqPollReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t waitTime, SMqClientTopic* pTopic, SMqClientVg* pVg) {
|
||||
int64_t reqOffset;
|
||||
if (pVg->currentOffset >= 0) {
|
||||
reqOffset = pVg->currentOffset;
|
||||
|
@ -1088,7 +1077,7 @@ SMqPollReqV2* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t blockingTime, SMqClient
|
|||
reqOffset = tmq->resetOffsetCfg;
|
||||
}
|
||||
|
||||
SMqPollReqV2* pReq = taosMemoryMalloc(sizeof(SMqPollReqV2));
|
||||
SMqPollReq* pReq = taosMemoryMalloc(sizeof(SMqPollReq));
|
||||
if (pReq == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1101,14 +1090,14 @@ SMqPollReqV2* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t blockingTime, SMqClient
|
|||
pReq->subKey[tlen] = TMQ_SEPARATOR;
|
||||
strcpy(pReq->subKey + tlen + 1, pTopic->topicName);
|
||||
|
||||
pReq->blockingTime = blockingTime;
|
||||
pReq->waitTime = waitTime;
|
||||
pReq->consumerId = tmq->consumerId;
|
||||
pReq->epoch = tmq->epoch;
|
||||
pReq->currentOffset = reqOffset;
|
||||
pReq->reqId = generateRequestId();
|
||||
|
||||
pReq->head.vgId = htonl(pVg->vgId);
|
||||
pReq->head.contLen = htonl(sizeof(SMqPollReqV2));
|
||||
pReq->head.contLen = htonl(sizeof(SMqPollReq));
|
||||
return pReq;
|
||||
}
|
||||
|
||||
|
@ -1130,7 +1119,7 @@ SMqRspObj* tmqBuildRspFromWrapper(SMqPollRspWrapper* pWrapper) {
|
|||
return pRspObj;
|
||||
}
|
||||
|
||||
int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
||||
int32_t tmqPollImpl(tmq_t* tmq, int64_t waitTime) {
|
||||
/*printf("call poll\n");*/
|
||||
for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) {
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
|
@ -1151,17 +1140,17 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
|||
#endif
|
||||
}
|
||||
atomic_store_32(&pVg->vgSkipCnt, 0);
|
||||
SMqPollReqV2* pReq = tmqBuildConsumeReqImpl(tmq, blockingTime, pTopic, pVg);
|
||||
SMqPollReq* pReq = tmqBuildConsumeReqImpl(tmq, waitTime, pTopic, pVg);
|
||||
if (pReq == NULL) {
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
return -1;
|
||||
}
|
||||
SMqPollCbParam* pParam = taosMemoryMalloc(sizeof(SMqPollCbParam));
|
||||
if (pParam == NULL) {
|
||||
taosMemoryFree(pReq);
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
return -1;
|
||||
}
|
||||
pParam->tmq = tmq;
|
||||
|
@ -1169,20 +1158,19 @@ int32_t tmqPollImpl(tmq_t* tmq, int64_t blockingTime) {
|
|||
pParam->pTopic = pTopic;
|
||||
pParam->vgId = pVg->vgId;
|
||||
pParam->epoch = tmq->epoch;
|
||||
pParam->sync = 0;
|
||||
|
||||
SMsgSendInfo* sendInfo = taosMemoryMalloc(sizeof(SMsgSendInfo));
|
||||
if (sendInfo == NULL) {
|
||||
taosMemoryFree(pReq);
|
||||
taosMemoryFree(pParam);
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
/*tsem_post(&tmq->rspSem);*/
|
||||
tsem_post(&tmq->rspSem);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sendInfo->msgInfo = (SDataBuf){
|
||||
.pData = pReq,
|
||||
.len = sizeof(SMqPollReqV2),
|
||||
.len = sizeof(SMqPollReq),
|
||||
.handle = NULL,
|
||||
};
|
||||
sendInfo->requestId = pReq->reqId;
|
||||
|
@ -1222,7 +1210,7 @@ int32_t tmqHandleNoPollRsp(tmq_t* tmq, SMqRspWrapper* rspWrapper, bool* pReset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t blockingTime, bool pollIfReset) {
|
||||
SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t waitTime, bool pollIfReset) {
|
||||
while (1) {
|
||||
SMqRspWrapper* rspWrapper = NULL;
|
||||
taosGetQitem(tmq->qall, (void**)&rspWrapper);
|
||||
|
@ -1261,37 +1249,45 @@ SMqRspObj* tmqHandleAllRsp(tmq_t* tmq, int64_t blockingTime, bool pollIfReset) {
|
|||
taosFreeQitem(rspWrapper);
|
||||
if (pollIfReset && reset) {
|
||||
tscDebug("consumer %ld reset and repoll", tmq->consumerId);
|
||||
tmqPollImpl(tmq, blockingTime);
|
||||
tmqPollImpl(tmq, waitTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) {
|
||||
TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t wait_time) {
|
||||
SMqRspObj* rspObj;
|
||||
int64_t startTime = taosGetTimestampMs();
|
||||
|
||||
rspObj = tmqHandleAllRsp(tmq, blocking_time, false);
|
||||
rspObj = tmqHandleAllRsp(tmq, wait_time, false);
|
||||
if (rspObj) {
|
||||
return (TAOS_RES*)rspObj;
|
||||
}
|
||||
|
||||
// in no topic status also need process delayed task
|
||||
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
tmqHandleAllDelayedTask(tmq);
|
||||
tmqPollImpl(tmq, blocking_time);
|
||||
tmqPollImpl(tmq, wait_time);
|
||||
|
||||
/*tsem_wait(&tmq->rspSem);*/
|
||||
|
||||
rspObj = tmqHandleAllRsp(tmq, blocking_time, false);
|
||||
rspObj = tmqHandleAllRsp(tmq, wait_time, false);
|
||||
if (rspObj) {
|
||||
return (TAOS_RES*)rspObj;
|
||||
}
|
||||
if (blocking_time != 0) {
|
||||
if (wait_time != 0) {
|
||||
int64_t endTime = taosGetTimestampMs();
|
||||
if (endTime - startTime > blocking_time) {
|
||||
int64_t leftTime = endTime - startTime;
|
||||
if (leftTime > wait_time) {
|
||||
tscDebug("consumer %ld (epoch %d) timeout, no rsp", tmq->consumerId, tmq->epoch);
|
||||
return NULL;
|
||||
}
|
||||
tsem_timewait(&tmq->rspSem, leftTime * 1000);
|
||||
} else {
|
||||
// use tsem_timewait instead of tsem_wait to avoid unexpected stuck
|
||||
tsem_timewait(&tmq->rspSem, 500 * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,10 +129,11 @@ int32_t colDataAppend(SColumnInfoData* pColumnInfoData, uint32_t currentRow, con
|
|||
}
|
||||
dataLen += CHAR_BYTES;
|
||||
}
|
||||
|
||||
SVarColAttr* pAttr = &pColumnInfoData->varmeta;
|
||||
if (pAttr->allocLen < pAttr->length + dataLen) {
|
||||
uint32_t newSize = pAttr->allocLen;
|
||||
if (newSize == 0) {
|
||||
if (newSize <= 1) {
|
||||
newSize = 8;
|
||||
}
|
||||
|
||||
|
|
|
@ -1302,6 +1302,11 @@ int32_t tDeserializeSGetUserAuthRsp(void *buf, int32_t bufLen, SGetUserAuthRsp *
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tFreeSGetUserAuthRsp(SGetUserAuthRsp *pRsp) {
|
||||
taosHashCleanup(pRsp->readDbs);
|
||||
taosHashCleanup(pRsp->writeDbs);
|
||||
}
|
||||
|
||||
int32_t tSerializeSCreateDropMQSBNodeReq(void *buf, int32_t bufLen, SMCreateQnodeReq *pReq) {
|
||||
SCoder encoder = {0};
|
||||
tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, bufLen, TD_ENCODER);
|
||||
|
|
|
@ -69,8 +69,8 @@ static void dmSetSignalHandle() {
|
|||
static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
|
||||
int32_t cmdEnvIndex = 0;
|
||||
if (argc < 2) return 0;
|
||||
global.envCmd = taosMemoryMalloc(argc-1);
|
||||
memset(global.envCmd, 0, argc-1);
|
||||
global.envCmd = taosMemoryMalloc((argc-1)*sizeof(char*));
|
||||
memset(global.envCmd, 0, (argc-1)*sizeof(char*));
|
||||
for (int32_t i = 1; i < argc; ++i) {
|
||||
if (strcmp(argv[i], "-c") == 0) {
|
||||
if (i < argc - 1) {
|
||||
|
|
|
@ -120,7 +120,7 @@ int32_t dmReadEps(SDnode *pDnode) {
|
|||
goto PRASE_DNODE_OVER;
|
||||
}
|
||||
|
||||
dnodeEp.id = dnodeId->valueint;
|
||||
dnodeEp.id = did->valueint;
|
||||
|
||||
cJSON *dnodeFqdn = cJSON_GetObjectItem(node, "fqdn");
|
||||
if (!dnodeFqdn || dnodeFqdn->type != cJSON_String || dnodeFqdn->valuestring == NULL) {
|
||||
|
@ -156,11 +156,6 @@ PRASE_DNODE_OVER:
|
|||
if (root != NULL) cJSON_Delete(root);
|
||||
if (pFile != NULL) taosCloseFile(&pFile);
|
||||
|
||||
if (dmIsEpChanged(pDnode, pDnode->data.dnodeId, pDnode->data.localEp)) {
|
||||
dError("localEp %s different with %s and need reconfigured", pDnode->data.localEp, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(pDnode->data.dnodeEps) == 0) {
|
||||
SDnodeEp dnodeEp = {0};
|
||||
dnodeEp.isMnode = 1;
|
||||
|
@ -170,6 +165,11 @@ PRASE_DNODE_OVER:
|
|||
|
||||
dmResetEps(pDnode, pDnode->data.dnodeEps);
|
||||
|
||||
if (dmIsEpChanged(pDnode, pDnode->data.dnodeId, pDnode->data.localEp)) {
|
||||
dError("localEp %s different with %s and need reconfigured", pDnode->data.localEp, file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
terrno = code;
|
||||
return code;
|
||||
}
|
||||
|
@ -291,13 +291,17 @@ static void dmPrintEps(SDnode *pDnode) {
|
|||
|
||||
static bool dmIsEpChanged(SDnode *pDnode, int32_t dnodeId, const char *ep) {
|
||||
bool changed = false;
|
||||
if (dnodeId == 0) return changed;
|
||||
taosRLockLatch(&pDnode->data.latch);
|
||||
|
||||
SDnodeEp *pDnodeEp = taosHashGet(pDnode->data.dnodeHash, &dnodeId, sizeof(int32_t));
|
||||
if (pDnodeEp != NULL) {
|
||||
char epstr[TSDB_EP_LEN + 1];
|
||||
char epstr[TSDB_EP_LEN + 1] = {0};
|
||||
snprintf(epstr, TSDB_EP_LEN, "%s:%u", pDnodeEp->ep.fqdn, pDnodeEp->ep.port);
|
||||
changed = strcmp(ep, epstr) != 0;
|
||||
changed = (strcmp(ep, epstr) != 0);
|
||||
if (changed) {
|
||||
dError("dnode:%d, localEp %s different from %s", dnodeId, ep, epstr);
|
||||
}
|
||||
}
|
||||
|
||||
taosRUnLockLatch(&pDnode->data.latch);
|
||||
|
|
|
@ -114,7 +114,6 @@ static void vmGenerateVnodeCfg(SCreateVnodeReq *pCreate, SVnodeCfg *pCfg) {
|
|||
pCfg->tsdbCfg.keep2 = 3650; // pCreate->daysToKeep0;
|
||||
pCfg->tsdbCfg.keep0 = 3650; // pCreate->daysToKeep2;
|
||||
pCfg->tsdbCfg.keep1 = 3650; // pCreate->daysToKeep0;
|
||||
pCfg->tsdbCfg.lruCacheSize = pCreate->cacheBlockSize;
|
||||
pCfg->tsdbCfg.retentions = pCreate->pRetensions;
|
||||
pCfg->walCfg.vgId = pCreate->vgId;
|
||||
pCfg->hashBegin = pCreate->hashBegin;
|
||||
|
|
|
@ -23,10 +23,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
enum {
|
||||
// MQ_CONSUMER_STATUS__INIT = 1,
|
||||
MQ_CONSUMER_STATUS__MODIFY = 1,
|
||||
MQ_CONSUMER_STATUS__MODIFY_IN_REB,
|
||||
// MQ_CONSUMER_STATUS__IDLE,
|
||||
MQ_CONSUMER_STATUS__READY,
|
||||
MQ_CONSUMER_STATUS__LOST,
|
||||
MQ_CONSUMER_STATUS__LOST_IN_REB,
|
||||
|
|
|
@ -89,6 +89,7 @@ typedef enum {
|
|||
TRN_TYPE_DROP_STREAM = 1020,
|
||||
TRN_TYPE_ALTER_STREAM = 1021,
|
||||
TRN_TYPE_CONSUMER_LOST = 1022,
|
||||
TRN_TYPE_CONSUMER_RECOVER = 1023,
|
||||
TRN_TYPE_BASIC_SCOPE_END,
|
||||
TRN_TYPE_GLOBAL_SCOPE = 2000,
|
||||
TRN_TYPE_CREATE_DNODE = 2001,
|
||||
|
@ -126,8 +127,6 @@ typedef enum {
|
|||
DND_REASON_OTHERS
|
||||
} EDndReason;
|
||||
|
||||
typedef void (*TransCbFp)(SMnode* pMnode, void* param);
|
||||
|
||||
typedef struct {
|
||||
int32_t id;
|
||||
ETrnStage stage;
|
||||
|
@ -150,8 +149,10 @@ typedef struct {
|
|||
int64_t dbUid;
|
||||
char dbname[TSDB_DB_FNAME_LEN];
|
||||
char lastError[TSDB_TRANS_ERROR_LEN];
|
||||
TransCbFp transCbFp;
|
||||
void* transCbParam;
|
||||
int32_t startFunc;
|
||||
int32_t stopFunc;
|
||||
int32_t paramLen;
|
||||
void* param;
|
||||
} STrans;
|
||||
|
||||
typedef struct {
|
||||
|
@ -463,12 +464,14 @@ enum {
|
|||
CONSUMER_UPDATE__ADD,
|
||||
CONSUMER_UPDATE__REMOVE,
|
||||
CONSUMER_UPDATE__LOST,
|
||||
CONSUMER_UPDATE__RECOVER,
|
||||
CONSUMER_UPDATE__MODIFY,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
char cgroup[TSDB_CGROUP_LEN];
|
||||
char appId[TSDB_CGROUP_LEN];
|
||||
int8_t updateType; // used only for update
|
||||
int32_t epoch;
|
||||
int32_t status;
|
||||
|
@ -479,6 +482,17 @@ typedef struct {
|
|||
SArray* currentTopics; // SArray<char*>
|
||||
SArray* rebNewTopics; // SArray<char*>
|
||||
SArray* rebRemovedTopics; // SArray<char*>
|
||||
|
||||
// subscribed by user
|
||||
SArray* assignedTopics; // SArray<char*>
|
||||
|
||||
// data for display
|
||||
int32_t pid;
|
||||
SEpSet ep;
|
||||
int64_t upTime;
|
||||
int64_t subscribeTime;
|
||||
int64_t rebalanceTime;
|
||||
|
||||
} SMqConsumerObj;
|
||||
|
||||
SMqConsumerObj* tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_LEN]);
|
||||
|
|
|
@ -33,6 +33,15 @@ typedef struct {
|
|||
void *pCont;
|
||||
} STransAction;
|
||||
|
||||
typedef enum {
|
||||
TEST_TRANS_START_FUNC = 1,
|
||||
TEST_TRANS_STOP_FUNC = 2,
|
||||
CONSUME_TRANS_START_FUNC = 3,
|
||||
CONSUME_TRANS_STOP_FUNC = 4,
|
||||
} ETrnFuncType;
|
||||
|
||||
typedef void (*TransCbFp)(SMnode *pMnode, void *param, int32_t paramLen);
|
||||
|
||||
int32_t mndInitTrans(SMnode *pMnode);
|
||||
void mndCleanupTrans(SMnode *pMnode);
|
||||
|
||||
|
@ -44,7 +53,7 @@ int32_t mndTransAppendCommitlog(STrans *pTrans, SSdbRaw *pRaw);
|
|||
int32_t mndTransAppendRedoAction(STrans *pTrans, STransAction *pAction);
|
||||
int32_t mndTransAppendUndoAction(STrans *pTrans, STransAction *pAction);
|
||||
void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen);
|
||||
void mndTransSetCb(STrans *pTrans, TransCbFp fp, void *param);
|
||||
void mndTransSetCb(STrans *pTrans, ETrnFuncType startFunc, ETrnFuncType stopFunc, void *param, int32_t paramLen);
|
||||
void mndTransSetDbInfo(STrans *pTrans, SDbObj *pDb);
|
||||
|
||||
int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans);
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
static int8_t mqInRebFlag = 0;
|
||||
|
||||
static const char *mndConsumerStatusName(int status);
|
||||
|
||||
static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
static int32_t mndConsumerActionDelete(SSdb *pSdb, SMqConsumerObj *pConsumer);
|
||||
static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pConsumer, SMqConsumerObj *pNewConsumer);
|
||||
|
@ -48,6 +50,7 @@ static int32_t mndProcessSubscribeReq(SNodeMsg *pMsg);
|
|||
static int32_t mndProcessAskEpReq(SNodeMsg *pMsg);
|
||||
static int32_t mndProcessMqTimerMsg(SNodeMsg *pMsg);
|
||||
static int32_t mndProcessConsumerLostMsg(SNodeMsg *pMsg);
|
||||
static int32_t mndProcessConsumerRecoverMsg(SNodeMsg *pMsg);
|
||||
|
||||
int32_t mndInitConsumer(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_CONSUMER,
|
||||
|
@ -62,6 +65,11 @@ int32_t mndInitConsumer(SMnode *pMnode) {
|
|||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_ASK_EP, mndProcessAskEpReq);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_TIMER, mndProcessMqTimerMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_CONSUMER_LOST, mndProcessConsumerLostMsg);
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_CONSUMER_RECOVER, mndProcessConsumerRecoverMsg);
|
||||
|
||||
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_CONSUMERS, mndRetrieveConsumer);
|
||||
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_CONSUMERS, mndCancelGetNextConsumer);
|
||||
|
||||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
|
@ -91,6 +99,30 @@ FAIL:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndProcessConsumerRecoverMsg(SNodeMsg *pMsg) {
|
||||
SMnode *pMnode = pMsg->pNode;
|
||||
SMqConsumerRecoverMsg *pRecoverMsg = pMsg->rpcMsg.pCont;
|
||||
SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pRecoverMsg->consumerId);
|
||||
ASSERT(pConsumer);
|
||||
|
||||
SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup);
|
||||
pConsumerNew->updateType = CONSUMER_UPDATE__RECOVER;
|
||||
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_CONSUMER_RECOVER, &pMsg->rpcMsg);
|
||||
if (pTrans == NULL) goto FAIL;
|
||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto FAIL;
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) goto FAIL;
|
||||
|
||||
mndTransDrop(pTrans);
|
||||
return 0;
|
||||
FAIL:
|
||||
tDeleteSMqConsumerObj(pConsumerNew);
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SMqRebSubscribe *mndGetOrCreateRebSub(SHashObj *pHash, const char *key) {
|
||||
SMqRebSubscribe *pRebSub = taosHashGet(pHash, key, strlen(key) + 1);
|
||||
if (pRebSub == NULL) {
|
||||
|
@ -216,8 +248,15 @@ static int32_t mndProcessAskEpReq(SNodeMsg *pMsg) {
|
|||
// 1. check consumer status
|
||||
int32_t status = atomic_load_32(&pConsumer->status);
|
||||
|
||||
if (status == MQ_CONSUMER_STATUS__LOST) {
|
||||
// TODO: recover consumer
|
||||
if (status == MQ_CONSUMER_STATUS__LOST_REBD) {
|
||||
SMqConsumerRecoverMsg *pRecoverMsg = rpcMallocCont(sizeof(SMqConsumerRecoverMsg));
|
||||
|
||||
pRecoverMsg->consumerId = consumerId;
|
||||
SRpcMsg *pRpcMsg = taosMemoryCalloc(1, sizeof(SRpcMsg));
|
||||
pRpcMsg->msgType = TDMT_MND_MQ_CONSUMER_RECOVER;
|
||||
pRpcMsg->pCont = pRecoverMsg;
|
||||
pRpcMsg->contLen = sizeof(SMqConsumerRecoverMsg);
|
||||
tmsgPutToQueue(&pMnode->msgCb, WRITE_QUEUE, pRpcMsg);
|
||||
}
|
||||
|
||||
if (status != MQ_CONSUMER_STATUS__READY) {
|
||||
|
@ -366,10 +405,14 @@ static int32_t mndProcessSubscribeReq(SNodeMsg *pMsg) {
|
|||
if (pConsumerOld == NULL) {
|
||||
pConsumerNew = tNewSMqConsumerObj(consumerId, cgroup);
|
||||
pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
|
||||
/*pConsumerNew->waitingRebTopics = newSub;*/
|
||||
pConsumerNew->rebNewTopics = newSub;
|
||||
subscribe.topicNames = NULL;
|
||||
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char *newTopicCopy = strdup(taosArrayGetP(newSub, i));
|
||||
taosArrayPush(pConsumerNew->assignedTopics, &newTopicCopy);
|
||||
}
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_TYPE_SUBSCRIBE, &pMsg->rpcMsg);
|
||||
if (pTrans == NULL) goto SUBSCRIBE_OVER;
|
||||
if (mndSetConsumerCommitLogs(pMnode, pTrans, pConsumerNew) != 0) goto SUBSCRIBE_OVER;
|
||||
|
@ -389,7 +432,11 @@ static int32_t mndProcessSubscribeReq(SNodeMsg *pMsg) {
|
|||
goto SUBSCRIBE_OVER;
|
||||
}
|
||||
pConsumerNew->updateType = CONSUMER_UPDATE__MODIFY;
|
||||
/*pConsumerOld->waitingRebTopics = newSub;*/
|
||||
|
||||
for (int32_t i = 0; i < newTopicNum; i++) {
|
||||
char *newTopicCopy = strdup(taosArrayGetP(newSub, i));
|
||||
taosArrayPush(pConsumerNew->assignedTopics, &newTopicCopy);
|
||||
}
|
||||
|
||||
int32_t oldTopicNum = 0;
|
||||
if (pConsumerOld->currentTopics) {
|
||||
|
@ -532,6 +579,7 @@ CM_DECODE_OVER:
|
|||
|
||||
static int32_t mndConsumerActionInsert(SSdb *pSdb, SMqConsumerObj *pConsumer) {
|
||||
mTrace("consumer:%" PRId64 ", perform insert action", pConsumer->consumerId);
|
||||
pConsumer->subscribeTime = pConsumer->upTime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -557,17 +605,45 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
|||
pOldConsumer->rebRemovedTopics = pNewConsumer->rebRemovedTopics;
|
||||
pNewConsumer->rebRemovedTopics = tmp;
|
||||
|
||||
tmp = pOldConsumer->assignedTopics;
|
||||
pOldConsumer->assignedTopics = pNewConsumer->assignedTopics;
|
||||
pNewConsumer->assignedTopics = tmp;
|
||||
|
||||
pOldConsumer->subscribeTime = pNewConsumer->upTime;
|
||||
|
||||
pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__LOST) {
|
||||
ASSERT(taosArrayGetSize(pOldConsumer->rebNewTopics) == 0);
|
||||
ASSERT(taosArrayGetSize(pOldConsumer->rebRemovedTopics) == 0);
|
||||
|
||||
int32_t sz = taosArrayGetSize(pOldConsumer->currentTopics);
|
||||
pOldConsumer->rebRemovedTopics = taosArrayInit(sz, sizeof(void *));
|
||||
/*pOldConsumer->rebRemovedTopics = taosArrayInit(sz, sizeof(void *));*/
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *topic = strdup(taosArrayGetP(pOldConsumer->currentTopics, i));
|
||||
taosArrayPush(pNewConsumer->rebRemovedTopics, &topic);
|
||||
taosArrayPush(pOldConsumer->rebRemovedTopics, &topic);
|
||||
}
|
||||
|
||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||
|
||||
pOldConsumer->status = MQ_CONSUMER_STATUS__LOST;
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__RECOVER) {
|
||||
ASSERT(taosArrayGetSize(pOldConsumer->currentTopics) == 0);
|
||||
ASSERT(taosArrayGetSize(pOldConsumer->rebNewTopics) == 0);
|
||||
|
||||
int32_t sz = taosArrayGetSize(pOldConsumer->assignedTopics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *topic = strdup(taosArrayGetP(pOldConsumer->assignedTopics, i));
|
||||
taosArrayPush(pOldConsumer->rebNewTopics, &topic);
|
||||
}
|
||||
|
||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||
|
||||
pOldConsumer->status = MQ_CONSUMER_STATUS__MODIFY;
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__TOUCH) {
|
||||
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
||||
|
||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__ADD) {
|
||||
ASSERT(taosArrayGetSize(pNewConsumer->rebNewTopics) == 1);
|
||||
ASSERT(taosArrayGetSize(pNewConsumer->rebRemovedTopics) == 0);
|
||||
|
@ -612,6 +688,9 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
|||
pOldConsumer->status = MQ_CONSUMER_STATUS__LOST_IN_REB;
|
||||
}
|
||||
}
|
||||
|
||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||
|
||||
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
||||
} else if (pNewConsumer->updateType == CONSUMER_UPDATE__REMOVE) {
|
||||
ASSERT(taosArrayGetSize(pNewConsumer->rebNewTopics) == 0);
|
||||
|
@ -668,6 +747,9 @@ static int32_t mndConsumerActionUpdate(SSdb *pSdb, SMqConsumerObj *pOldConsumer,
|
|||
pOldConsumer->status = MQ_CONSUMER_STATUS__LOST_IN_REB;
|
||||
}
|
||||
}
|
||||
|
||||
pOldConsumer->rebalanceTime = pNewConsumer->upTime;
|
||||
|
||||
atomic_add_fetch_32(&pOldConsumer->epoch, 1);
|
||||
}
|
||||
|
||||
|
@ -688,3 +770,104 @@ void mndReleaseConsumer(SMnode *pMnode, SMqConsumerObj *pConsumer) {
|
|||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbRelease(pSdb, pConsumer);
|
||||
}
|
||||
|
||||
static int32_t mndRetrieveConsumer(SNodeMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rowsCapacity) {
|
||||
SMnode *pMnode = pReq->pNode;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
int32_t numOfRows = 0;
|
||||
SMqConsumerObj *pConsumer = NULL;
|
||||
|
||||
while (numOfRows < rowsCapacity) {
|
||||
pShow->pIter = sdbFetch(pSdb, SDB_CONSUMER, pShow->pIter, (void **)&pConsumer);
|
||||
if (pShow->pIter == NULL) break;
|
||||
|
||||
SColumnInfoData *pColInfo;
|
||||
int32_t cols = 0;
|
||||
|
||||
taosRLockLatch(&pConsumer->lock);
|
||||
|
||||
// consumer id
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->consumerId, false);
|
||||
|
||||
// group id
|
||||
char groupId[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tstrncpy(varDataVal(groupId), pConsumer->cgroup, TSDB_CGROUP_LEN);
|
||||
varDataSetLen(groupId, strlen(varDataVal(groupId)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)groupId, false);
|
||||
|
||||
// app id
|
||||
char appId[TSDB_CGROUP_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tstrncpy(varDataVal(appId), pConsumer->appId, TSDB_CGROUP_LEN);
|
||||
varDataSetLen(appId, strlen(varDataVal(appId)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)appId, false);
|
||||
|
||||
// status
|
||||
char status[20 + VARSTR_HEADER_SIZE] = {0};
|
||||
tstrncpy(varDataVal(status), mndConsumerStatusName(pConsumer->status), 20);
|
||||
varDataSetLen(status, strlen(varDataVal(status)));
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)status, false);
|
||||
|
||||
// subscribed topics
|
||||
char topics[TSDB_SHOW_LIST_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
char *showStr = taosShowStrArray(pConsumer->assignedTopics);
|
||||
tstrncpy(varDataVal(topics), showStr, TSDB_SHOW_LIST_LEN);
|
||||
taosMemoryFree(showStr);
|
||||
varDataSetLen(topics, strlen(varDataVal(topics)));
|
||||
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)topics, false);
|
||||
|
||||
// pid
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->pid, true);
|
||||
|
||||
// end point
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->ep, true);
|
||||
|
||||
// up time
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->upTime, false);
|
||||
|
||||
// subscribe time
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->subscribeTime, false);
|
||||
|
||||
// rebalance time
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pConsumer->rebalanceTime, pConsumer->rebalanceTime == 0);
|
||||
|
||||
taosRUnLockLatch(&pConsumer->lock);
|
||||
sdbRelease(pSdb, pConsumer);
|
||||
|
||||
numOfRows++;
|
||||
}
|
||||
|
||||
pShow->numOfRows += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void mndCancelGetNextConsumer(SMnode *pMnode, void *pIter) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
||||
|
||||
static const char *mndConsumerStatusName(int status) {
|
||||
switch (status) {
|
||||
case MQ_CONSUMER_STATUS__READY:
|
||||
return "ready";
|
||||
case MQ_CONSUMER_STATUS__LOST:
|
||||
case MQ_CONSUMER_STATUS__LOST_REBD:
|
||||
case MQ_CONSUMER_STATUS__LOST_IN_REB:
|
||||
return "lost";
|
||||
case MQ_CONSUMER_STATUS__MODIFY:
|
||||
case MQ_CONSUMER_STATUS__MODIFY_IN_REB:
|
||||
return "rebalancing";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,15 +34,20 @@ SMqConsumerObj *tNewSMqConsumerObj(int64_t consumerId, char cgroup[TSDB_CGROUP_L
|
|||
pConsumer->currentTopics = taosArrayInit(0, sizeof(void *));
|
||||
pConsumer->rebNewTopics = taosArrayInit(0, sizeof(void *));
|
||||
pConsumer->rebRemovedTopics = taosArrayInit(0, sizeof(void *));
|
||||
pConsumer->assignedTopics = taosArrayInit(0, sizeof(void *));
|
||||
|
||||
if (pConsumer->currentTopics == NULL || pConsumer->rebNewTopics == NULL || pConsumer->rebRemovedTopics == NULL) {
|
||||
if (pConsumer->currentTopics == NULL || pConsumer->rebNewTopics == NULL || pConsumer->rebRemovedTopics == NULL ||
|
||||
pConsumer->assignedTopics == NULL) {
|
||||
taosArrayDestroy(pConsumer->currentTopics);
|
||||
taosArrayDestroy(pConsumer->rebNewTopics);
|
||||
taosArrayDestroy(pConsumer->rebRemovedTopics);
|
||||
taosArrayDestroy(pConsumer->assignedTopics);
|
||||
taosMemoryFree(pConsumer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pConsumer->upTime = taosGetTimestampMs();
|
||||
|
||||
return pConsumer;
|
||||
}
|
||||
|
||||
|
@ -56,6 +61,9 @@ void tDeleteSMqConsumerObj(SMqConsumerObj *pConsumer) {
|
|||
if (pConsumer->rebRemovedTopics) {
|
||||
taosArrayDestroyP(pConsumer->rebRemovedTopics, (FDelete)taosMemoryFree);
|
||||
}
|
||||
if (pConsumer->assignedTopics) {
|
||||
taosArrayDestroyP(pConsumer->assignedTopics, (FDelete)taosMemoryFree);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) {
|
||||
|
@ -67,6 +75,12 @@ int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) {
|
|||
tlen += taosEncodeFixedI32(buf, pConsumer->epoch);
|
||||
tlen += taosEncodeFixedI32(buf, pConsumer->status);
|
||||
|
||||
tlen += taosEncodeFixedI32(buf, pConsumer->pid);
|
||||
tlen += taosEncodeSEpSet(buf, &pConsumer->ep);
|
||||
tlen += taosEncodeFixedI64(buf, pConsumer->upTime);
|
||||
tlen += taosEncodeFixedI64(buf, pConsumer->subscribeTime);
|
||||
tlen += taosEncodeFixedI64(buf, pConsumer->rebalanceTime);
|
||||
|
||||
// current topics
|
||||
if (pConsumer->currentTopics) {
|
||||
sz = taosArrayGetSize(pConsumer->currentTopics);
|
||||
|
@ -103,6 +117,18 @@ int32_t tEncodeSMqConsumerObj(void **buf, const SMqConsumerObj *pConsumer) {
|
|||
tlen += taosEncodeFixedI32(buf, 0);
|
||||
}
|
||||
|
||||
// lost topics
|
||||
if (pConsumer->assignedTopics) {
|
||||
sz = taosArrayGetSize(pConsumer->assignedTopics);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *topic = taosArrayGetP(pConsumer->assignedTopics, i);
|
||||
tlen += taosEncodeString(buf, topic);
|
||||
}
|
||||
} else {
|
||||
tlen += taosEncodeFixedI32(buf, 0);
|
||||
}
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
|
@ -114,6 +140,12 @@ void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer) {
|
|||
buf = taosDecodeFixedI32(buf, &pConsumer->epoch);
|
||||
buf = taosDecodeFixedI32(buf, &pConsumer->status);
|
||||
|
||||
buf = taosDecodeFixedI32(buf, &pConsumer->pid);
|
||||
buf = taosDecodeSEpSet(buf, &pConsumer->ep);
|
||||
buf = taosDecodeFixedI64(buf, &pConsumer->upTime);
|
||||
buf = taosDecodeFixedI64(buf, &pConsumer->subscribeTime);
|
||||
buf = taosDecodeFixedI64(buf, &pConsumer->rebalanceTime);
|
||||
|
||||
// current topics
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pConsumer->currentTopics = taosArrayInit(sz, sizeof(void *));
|
||||
|
@ -141,6 +173,15 @@ void *tDecodeSMqConsumerObj(const void *buf, SMqConsumerObj *pConsumer) {
|
|||
taosArrayPush(pConsumer->rebRemovedTopics, &topic);
|
||||
}
|
||||
|
||||
// reb removed topics
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pConsumer->assignedTopics = taosArrayInit(sz, sizeof(void *));
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
char *topic;
|
||||
buf = taosDecodeString(buf, &topic);
|
||||
taosArrayPush(pConsumer->assignedTopics, &topic);
|
||||
}
|
||||
|
||||
return (void *)buf;
|
||||
}
|
||||
|
||||
|
@ -329,6 +370,7 @@ int32_t tEncodeSMqSubActionLogEntry(void **buf, const SMqSubActionLogEntry *pEnt
|
|||
tlen += taosEncodeArray(buf, pEntry->consumers, (FEncode)tEncodeSMqSubActionLogEntry);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tDecodeSMqSubActionLogEntry(const void *buf, SMqSubActionLogEntry *pEntry) {
|
||||
buf = taosDecodeFixedI32(buf, &pEntry->epoch);
|
||||
buf = taosDecodeArray(buf, &pEntry->consumers, (FDecode)tDecodeSMqSubActionLogEntry, sizeof(SMqSubActionLogEntry));
|
||||
|
|
|
@ -142,6 +142,7 @@ static const SInfosTableSchema userTblsSchema[] = {
|
|||
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "ttl", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "table_comment", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "type", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
};
|
||||
|
||||
static const SInfosTableSchema userTblDistSchema[] = {
|
||||
|
@ -164,7 +165,6 @@ static const SInfosTableSchema userUsersSchema[] = {
|
|||
{.name = "name", .bytes = TSDB_USER_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "privilege", .bytes = 10 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
{.name = "account", .bytes = TSDB_USER_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
};
|
||||
|
||||
static const SInfosTableSchema grantsSchema[] = {
|
||||
|
@ -199,23 +199,6 @@ static const SInfosTableSchema vgroupsSchema[] = {
|
|||
{.name = "file_size", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
};
|
||||
|
||||
static const SInfosTableSchema consumerSchema[] = {
|
||||
{.name = "client_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "group_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "pid", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "status", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
// ep
|
||||
// up time
|
||||
// topics
|
||||
};
|
||||
|
||||
static const SInfosTableSchema subscribeSchema[] = {
|
||||
{.name = "topic_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "group_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "client_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
};
|
||||
|
||||
static const SInfosTableSchema smaSchema[] = {
|
||||
{.name = "sma_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR},
|
||||
{.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
|
@ -282,8 +265,6 @@ static const SInfosTableMeta infosMeta[] = {
|
|||
{TSDB_INS_TABLE_USER_USERS, userUsersSchema, tListLen(userUsersSchema)},
|
||||
{TSDB_INS_TABLE_LICENCES, grantsSchema, tListLen(grantsSchema)},
|
||||
{TSDB_INS_TABLE_VGROUPS, vgroupsSchema, tListLen(vgroupsSchema)},
|
||||
{TSDB_INS_TABLE_CONSUMERS, consumerSchema, tListLen(consumerSchema)},
|
||||
{TSDB_INS_TABLE_SUBSCRIBES, subscribeSchema, tListLen(subscribeSchema)},
|
||||
{TSDB_INS_TABLE_TRANS, transSchema, tListLen(transSchema)},
|
||||
{TSDB_INS_TABLE_SMAS, smaSchema, tListLen(smaSchema)},
|
||||
{TSDB_INS_TABLE_CONFIGS, configSchema, tListLen(configSchema)},
|
||||
|
|
|
@ -49,13 +49,15 @@ static const SPerfsTableSchema topicSchema[] = {
|
|||
|
||||
static const SPerfsTableSchema consumerSchema[] = {
|
||||
{.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT},
|
||||
{.name = "app_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "group_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "status", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "app_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "status", .bytes = 20 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "topics", .bytes = TSDB_SHOW_LIST_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "pid", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "end_point", .bytes = TSDB_EP_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "up_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
{.name = "subscribe_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
{.name = "rebalance_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP},
|
||||
};
|
||||
|
||||
static const SPerfsTableSchema subscriptionSchema[] = {
|
||||
|
@ -63,6 +65,12 @@ static const SPerfsTableSchema subscriptionSchema[] = {
|
|||
{.name = "group_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "consumer_id", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT},
|
||||
};
|
||||
|
||||
static const SPerfsTableSchema offsetSchema[] = {
|
||||
{.name = "topic_name", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "group_id", .bytes = SYSTABLE_SCH_TABLE_NAME_LEN, .type = TSDB_DATA_TYPE_BINARY},
|
||||
{.name = "vgroup_id", .bytes = 4, .type = TSDB_DATA_TYPE_INT},
|
||||
{.name = "committed_offset", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT},
|
||||
{.name = "current_offset", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT},
|
||||
{.name = "skip_log_cnt", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT},
|
||||
|
@ -74,6 +82,7 @@ static const SPerfsTableMeta perfsMeta[] = {
|
|||
{TSDB_PERFS_TABLE_TOPICS, topicSchema, tListLen(topicSchema)},
|
||||
{TSDB_PERFS_TABLE_CONSUMERS, consumerSchema, tListLen(consumerSchema)},
|
||||
{TSDB_PERFS_TABLE_SUBSCRIPTIONS, subscriptionSchema, tListLen(subscriptionSchema)},
|
||||
{TSDB_PERFS_TABLE_OFFSETS, offsetSchema, tListLen(offsetSchema)},
|
||||
};
|
||||
|
||||
// connection/application/
|
||||
|
|
|
@ -196,7 +196,7 @@ static int32_t mndProcessConnectReq(SNodeMsg *pReq) {
|
|||
goto CONN_OVER;
|
||||
}
|
||||
if (0 != strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1)) {
|
||||
mError("user:%s, failed to auth while acquire user\n %s \r\n %s", pReq->user, connReq.passwd, pUser->pass);
|
||||
mError("user:%s, failed to auth while acquire user, input:%s saved:%s", pReq->user, connReq.passwd, pUser->pass);
|
||||
code = TSDB_CODE_RPC_AUTH_FAILURE;
|
||||
goto CONN_OVER;
|
||||
}
|
||||
|
|
|
@ -489,7 +489,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
|||
int32_t levelNum = LIST_LENGTH(pPlan->pSubplans);
|
||||
if (levelNum != 1) {
|
||||
qDestroyQueryPlan(pPlan);
|
||||
terrno = TSDB_CODE_MND_UNSUPPORTED_TOPIC;
|
||||
terrno = TSDB_CODE_MND_INVALID_TOPIC_QUERY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -498,7 +498,7 @@ int32_t mndSchedInitSubEp(SMnode* pMnode, const SMqTopicObj* pTopic, SMqSubscrib
|
|||
int32_t opNum = LIST_LENGTH(inner->pNodeList);
|
||||
if (opNum != 1) {
|
||||
qDestroyQueryPlan(pPlan);
|
||||
terrno = TSDB_CODE_MND_UNSUPPORTED_TOPIC;
|
||||
terrno = TSDB_CODE_MND_INVALID_TOPIC_QUERY;
|
||||
return -1;
|
||||
}
|
||||
plan = nodesListGetNode(inner->pNodeList, 0);
|
||||
|
|
|
@ -261,7 +261,7 @@ static SDDropTopicReq *mndBuildDropTopicMsg(SMnode *pMnode, SVgObj *pVgroup, SMq
|
|||
|
||||
static int32_t mndCheckCreateTopicReq(SCMCreateTopicReq *pCreate) {
|
||||
if (pCreate->name[0] == 0 || pCreate->sql == NULL || pCreate->sql[0] == 0 || pCreate->subscribeDbName[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_TOPIC_OPTION;
|
||||
terrno = TSDB_CODE_MND_INVALID_TOPIC;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans);
|
|||
static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw);
|
||||
static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans);
|
||||
static int32_t mndTransActionUpdate(SSdb *pSdb, STrans *OldTrans, STrans *pOld);
|
||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans);
|
||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc);
|
||||
|
||||
static int32_t mndTransAppendLog(SArray *pArray, SSdbRaw *pRaw);
|
||||
static int32_t mndTransAppendAction(SArray *pArray, STransAction *pAction);
|
||||
|
@ -174,6 +174,13 @@ static SSdbRaw *mndTransActionEncode(STrans *pTrans) {
|
|||
SDB_SET_BINARY(pRaw, dataPos, (void *)pAction->pCont, pAction->contLen, TRANS_ENCODE_OVER)
|
||||
}
|
||||
|
||||
SDB_SET_INT32(pRaw, dataPos, pTrans->startFunc, TRANS_ENCODE_OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pTrans->stopFunc, TRANS_ENCODE_OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pTrans->paramLen, TRANS_ENCODE_OVER)
|
||||
if (pTrans->param != NULL) {
|
||||
SDB_SET_BINARY(pRaw, dataPos, pTrans->param, pTrans->paramLen, TRANS_ENCODE_OVER)
|
||||
}
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, MND_TRANS_RESERVE_SIZE, TRANS_ENCODE_OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, TRANS_ENCODE_OVER)
|
||||
|
||||
|
@ -305,6 +312,14 @@ static SSdbRow *mndTransActionDecode(SSdbRaw *pRaw) {
|
|||
action.pCont = NULL;
|
||||
}
|
||||
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->startFunc, TRANS_DECODE_OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->stopFunc, TRANS_DECODE_OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pTrans->paramLen, TRANS_DECODE_OVER)
|
||||
if (pTrans->paramLen != 0) {
|
||||
pTrans->param = taosMemoryMalloc(pTrans->paramLen);
|
||||
SDB_GET_BINARY(pRaw, dataPos, pTrans->param, pTrans->paramLen, TRANS_DECODE_OVER);
|
||||
}
|
||||
|
||||
SDB_GET_RESERVE(pRaw, dataPos, MND_TRANS_RESERVE_SIZE, TRANS_DECODE_OVER)
|
||||
|
||||
terrno = 0;
|
||||
|
@ -413,9 +428,36 @@ static const char *mndTransType(ETrnType type) {
|
|||
}
|
||||
}
|
||||
|
||||
static void mndTransTestStartFunc(SMnode *pMnode, void *param, int32_t paramLen) {
|
||||
mInfo("test trans start, param:%s, len:%d", (char *)param, paramLen);
|
||||
}
|
||||
|
||||
static void mndTransTestStopFunc(SMnode *pMnode, void *param, int32_t paramLen) {
|
||||
mInfo("test trans stop, param:%s, len:%d", (char *)param, paramLen);
|
||||
}
|
||||
|
||||
static TransCbFp mndTransGetCbFp(ETrnFuncType ftype) {
|
||||
switch (ftype) {
|
||||
case TEST_TRANS_START_FUNC:
|
||||
return mndTransTestStartFunc;
|
||||
case TEST_TRANS_STOP_FUNC:
|
||||
return mndTransTestStopFunc;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransActionInsert(SSdb *pSdb, STrans *pTrans) {
|
||||
// pTrans->stage = TRN_STAGE_PREPARE;
|
||||
mTrace("trans:%d, perform insert action, row:%p stage:%s", pTrans->id, pTrans, mndTransStr(pTrans->stage));
|
||||
|
||||
if (pTrans->startFunc > 0) {
|
||||
TransCbFp fp = mndTransGetCbFp(pTrans->startFunc);
|
||||
if (fp) {
|
||||
(*fp)(pSdb->pMnode, pTrans->param, pTrans->paramLen);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -430,10 +472,23 @@ static void mndTransDropData(STrans *pTrans) {
|
|||
pTrans->rpcRsp = NULL;
|
||||
pTrans->rpcRspLen = 0;
|
||||
}
|
||||
if (pTrans->param != NULL) {
|
||||
taosMemoryFree(pTrans->param);
|
||||
pTrans->param = NULL;
|
||||
pTrans->paramLen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans, bool callFunc) {
|
||||
mDebug("trans:%d, perform delete action, row:%p stage:%s callfunc:%d", pTrans->id, pTrans, mndTransStr(pTrans->stage),
|
||||
callFunc);
|
||||
if (pTrans->stopFunc > 0 && callFunc) {
|
||||
TransCbFp fp = mndTransGetCbFp(pTrans->stopFunc);
|
||||
if (fp) {
|
||||
(*fp)(pSdb->pMnode, pTrans->param, pTrans->paramLen);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mndTransActionDelete(SSdb *pSdb, STrans *pTrans) {
|
||||
mTrace("trans:%d, perform delete action, row:%p stage:%s", pTrans->id, pTrans, mndTransStr(pTrans->stage));
|
||||
mndTransDropData(pTrans);
|
||||
return 0;
|
||||
}
|
||||
|
@ -498,7 +553,7 @@ STrans *mndTransCreate(SMnode *pMnode, ETrnPolicy policy, ETrnType type, const S
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mDebug("trans:%d, is created, data:%p", pTrans->id, pTrans);
|
||||
mDebug("trans:%d, local var is created, data:%p", pTrans->id, pTrans);
|
||||
return pTrans;
|
||||
}
|
||||
|
||||
|
@ -525,7 +580,7 @@ static void mndTransDropActions(SArray *pArray) {
|
|||
void mndTransDrop(STrans *pTrans) {
|
||||
if (pTrans != NULL) {
|
||||
mndTransDropData(pTrans);
|
||||
mDebug("trans:%d, is dropped, data:%p", pTrans->id, pTrans);
|
||||
mDebug("trans:%d, local var is freed, data:%p", pTrans->id, pTrans);
|
||||
taosMemoryFreeClear(pTrans);
|
||||
}
|
||||
}
|
||||
|
@ -574,9 +629,11 @@ void mndTransSetRpcRsp(STrans *pTrans, void *pCont, int32_t contLen) {
|
|||
pTrans->rpcRspLen = contLen;
|
||||
}
|
||||
|
||||
void mndTransSetCb(STrans *pTrans, TransCbFp fp, void *param) {
|
||||
pTrans->transCbFp = fp;
|
||||
pTrans->transCbParam = param;
|
||||
void mndTransSetCb(STrans *pTrans, ETrnFuncType startFunc, ETrnFuncType stopFunc, void *param, int32_t paramLen) {
|
||||
pTrans->startFunc = startFunc;
|
||||
pTrans->stopFunc = stopFunc;
|
||||
pTrans->param = param;
|
||||
pTrans->paramLen = paramLen;
|
||||
}
|
||||
|
||||
void mndTransSetDbInfo(STrans *pTrans, SDbObj *pDb) {
|
||||
|
@ -712,8 +769,6 @@ int32_t mndTransPrepare(SMnode *pMnode, STrans *pTrans) {
|
|||
pNew->rpcRefId = pTrans->rpcRefId;
|
||||
pNew->rpcRsp = pTrans->rpcRsp;
|
||||
pNew->rpcRspLen = pTrans->rpcRspLen;
|
||||
pNew->transCbFp = pTrans->transCbFp;
|
||||
pNew->transCbParam = pTrans->transCbParam;
|
||||
pTrans->rpcRsp = NULL;
|
||||
pTrans->rpcRspLen = 0;
|
||||
|
||||
|
@ -1125,10 +1180,6 @@ static bool mndTransPerfromFinishedStage(SMnode *pMnode, STrans *pTrans) {
|
|||
|
||||
mDebug("trans:%d, finished, code:0x%04x, failedTimes:%d", pTrans->id, pTrans->code, pTrans->failedTimes);
|
||||
|
||||
if (pTrans->transCbFp != NULL) {
|
||||
(*pTrans->transCbFp)(pMnode, pTrans->transCbParam);
|
||||
}
|
||||
|
||||
return continueExec;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,36 +96,36 @@ static SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
|
|||
int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + (numOfReadDbs + numOfWriteDbs) * TSDB_DB_FNAME_LEN;
|
||||
|
||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size);
|
||||
if (pRaw == NULL) goto USER_ENCODE_OVER;
|
||||
if (pRaw == NULL) goto _OVER;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, USER_ENCODE_OVER)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, USER_ENCODE_OVER)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, USER_ENCODE_OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, USER_ENCODE_OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, USER_ENCODE_OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->superUser, USER_ENCODE_OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, USER_ENCODE_OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, USER_ENCODE_OVER)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
|
||||
SDB_SET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->createdTime, _OVER)
|
||||
SDB_SET_INT64(pRaw, dataPos, pUser->updateTime, _OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->superUser, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
|
||||
|
||||
char *db = taosHashIterate(pUser->readDbs, NULL);
|
||||
while (db != NULL) {
|
||||
SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_ENCODE_OVER);
|
||||
SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
|
||||
db = taosHashIterate(pUser->readDbs, db);
|
||||
}
|
||||
|
||||
db = taosHashIterate(pUser->writeDbs, NULL);
|
||||
while (db != NULL) {
|
||||
SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_ENCODE_OVER);
|
||||
SDB_SET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER);
|
||||
db = taosHashIterate(pUser->writeDbs, db);
|
||||
}
|
||||
|
||||
SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, USER_ENCODE_OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, USER_ENCODE_OVER)
|
||||
SDB_SET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
|
||||
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
|
||||
|
||||
terrno = 0;
|
||||
|
||||
USER_ENCODE_OVER:
|
||||
_OVER:
|
||||
if (terrno != 0) {
|
||||
mError("user:%s, failed to encode to raw:%p since %s", pUser->user, pRaw, terrstr());
|
||||
sdbFreeRaw(pRaw);
|
||||
|
@ -140,55 +140,55 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto USER_DECODE_OVER;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
|
||||
|
||||
if (sver != USER_VER_NUMBER) {
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
goto USER_DECODE_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
SSdbRow *pRow = sdbAllocRow(sizeof(SUserObj));
|
||||
if (pRow == NULL) goto USER_DECODE_OVER;
|
||||
if (pRow == NULL) goto _OVER;
|
||||
|
||||
SUserObj *pUser = sdbGetRowObj(pRow);
|
||||
if (pUser == NULL) goto USER_DECODE_OVER;
|
||||
|
||||
pUser->readDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
|
||||
pUser->writeDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
|
||||
if (pUser->readDbs == NULL || pUser->writeDbs == NULL) goto USER_DECODE_OVER;
|
||||
if (pUser == NULL) goto _OVER;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, USER_DECODE_OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, USER_DECODE_OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, USER_DECODE_OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, USER_DECODE_OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, USER_DECODE_OVER)
|
||||
SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, USER_DECODE_OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->user, TSDB_USER_LEN, _OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->pass, TSDB_PASSWORD_LEN, _OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, pUser->acct, TSDB_USER_LEN, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pUser->createdTime, _OVER)
|
||||
SDB_GET_INT64(pRaw, dataPos, &pUser->updateTime, _OVER)
|
||||
SDB_GET_INT8(pRaw, dataPos, &pUser->superUser, _OVER)
|
||||
|
||||
int32_t numOfReadDbs = 0;
|
||||
int32_t numOfWriteDbs = 0;
|
||||
SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, USER_DECODE_OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, USER_DECODE_OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &numOfReadDbs, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &numOfWriteDbs, _OVER)
|
||||
pUser->readDbs = taosHashInit(numOfReadDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
pUser->writeDbs =
|
||||
taosHashInit(numOfWriteDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
if (pUser->readDbs == NULL || pUser->writeDbs == NULL) goto _OVER;
|
||||
|
||||
for (int32_t i = 0; i < numOfReadDbs; ++i) {
|
||||
char db[TSDB_DB_FNAME_LEN] = {0};
|
||||
SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_DECODE_OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
|
||||
int32_t len = strlen(db) + 1;
|
||||
taosHashPut(pUser->readDbs, db, len, db, TSDB_DB_FNAME_LEN);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfWriteDbs; ++i) {
|
||||
char db[TSDB_DB_FNAME_LEN] = {0};
|
||||
SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, USER_DECODE_OVER)
|
||||
SDB_GET_BINARY(pRaw, dataPos, db, TSDB_DB_FNAME_LEN, _OVER)
|
||||
int32_t len = strlen(db) + 1;
|
||||
taosHashPut(pUser->writeDbs, db, len, db, TSDB_DB_FNAME_LEN);
|
||||
}
|
||||
|
||||
SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, USER_DECODE_OVER)
|
||||
SDB_GET_RESERVE(pRaw, dataPos, USER_RESERVE_SIZE, _OVER)
|
||||
|
||||
terrno = 0;
|
||||
|
||||
USER_DECODE_OVER:
|
||||
_OVER:
|
||||
if (terrno != 0) {
|
||||
mError("user:%s, failed to decode from raw:%p since %s", pUser->user, pRaw, terrstr());
|
||||
taosHashCleanup(pUser->readDbs);
|
||||
|
@ -220,6 +220,8 @@ static int32_t mndUserActionDelete(SSdb *pSdb, SUserObj *pUser) {
|
|||
mTrace("user:%s, perform delete action, row:%p", pUser->user, pUser);
|
||||
taosHashCleanup(pUser->readDbs);
|
||||
taosHashCleanup(pUser->writeDbs);
|
||||
pUser->readDbs = NULL;
|
||||
pUser->writeDbs = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -228,13 +230,8 @@ static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
|
|||
memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
|
||||
pOld->updateTime = pNew->updateTime;
|
||||
|
||||
void *tmp1 = pOld->readDbs;
|
||||
pOld->readDbs = pNew->readDbs;
|
||||
pNew->readDbs = tmp1;
|
||||
|
||||
void *tmp2 = pOld->writeDbs;
|
||||
pOld->writeDbs = pNew->writeDbs;
|
||||
pNew->writeDbs = tmp2;
|
||||
TSWAP(pOld->readDbs, pNew->readDbs, (void *));
|
||||
TSWAP(pOld->writeDbs, pNew->writeDbs, (void *));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -277,6 +274,9 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate
|
|||
}
|
||||
sdbSetRawStatus(pRedoRaw, SDB_STATUS_READY);
|
||||
|
||||
char *param = strdup("====> test code to be deleted later <=====");
|
||||
mndTransSetCb(pTrans, TEST_TRANS_START_FUNC, TEST_TRANS_STOP_FUNC, param, strlen(param) + 1);
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
|
@ -296,41 +296,41 @@ static int32_t mndProcessCreateUserReq(SNodeMsg *pReq) {
|
|||
|
||||
if (tDeserializeSCreateUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &createReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
mDebug("user:%s, start to create", createReq.user);
|
||||
|
||||
if (createReq.user[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (createReq.pass[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pUser = mndAcquireUser(pMnode, createReq.user);
|
||||
if (pUser != NULL) {
|
||||
terrno = TSDB_CODE_MND_USER_ALREADY_EXIST;
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pOperUser = mndAcquireUser(pMnode, pReq->user);
|
||||
if (pOperUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckCreateUserAuth(pOperUser) != 0) {
|
||||
goto CREATE_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
|
||||
if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
|
||||
CREATE_USER_OVER:
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to create since %s", createReq.user, terrstr());
|
||||
}
|
||||
|
@ -341,13 +341,13 @@ CREATE_USER_OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SNodeMsg *pReq) {
|
||||
static int32_t mndAlterUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SNodeMsg *pReq) {
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_ALTER_USER, &pReq->rpcMsg);
|
||||
if (pTrans == NULL) {
|
||||
mError("user:%s, failed to update since %s", pOld->user, terrstr());
|
||||
mError("user:%s, failed to alter since %s", pOld->user, terrstr());
|
||||
return -1;
|
||||
}
|
||||
mDebug("trans:%d, used to update user:%s", pTrans->id, pOld->user);
|
||||
mDebug("trans:%d, used to alter user:%s", pTrans->id, pOld->user);
|
||||
|
||||
SSdbRaw *pRedoRaw = mndUserActionEncode(pNew);
|
||||
if (pRedoRaw == NULL || mndTransAppendRedolog(pTrans, pRedoRaw) != 0) {
|
||||
|
@ -368,7 +368,8 @@ static int32_t mndUpdateUser(SMnode *pMnode, SUserObj *pOld, SUserObj *pNew, SNo
|
|||
}
|
||||
|
||||
static SHashObj *mndDupDbHash(SHashObj *pOld) {
|
||||
SHashObj *pNew = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, true);
|
||||
SHashObj *pNew =
|
||||
taosHashInit(taosHashGetSize(pOld), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
if (pNew == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
|
@ -379,8 +380,8 @@ static SHashObj *mndDupDbHash(SHashObj *pOld) {
|
|||
int32_t len = strlen(db) + 1;
|
||||
if (taosHashPut(pNew, db, len, db, TSDB_DB_FNAME_LEN) != 0) {
|
||||
taosHashCancelIterate(pOld, db);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
taosHashCleanup(pNew);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
db = taosHashIterate(pOld, db);
|
||||
|
@ -399,38 +400,38 @@ static int32_t mndProcessAlterUserReq(SNodeMsg *pReq) {
|
|||
|
||||
if (tDeserializeSAlterUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &alterReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
mDebug("user:%s, start to alter", alterReq.user);
|
||||
|
||||
if (alterReq.user[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (alterReq.pass[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_PASS_FORMAT;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pUser = mndAcquireUser(pMnode, alterReq.user);
|
||||
if (pUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_USER_NOT_EXIST;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pOperUser = mndAcquireUser(pMnode, pReq->user);
|
||||
if (pOperUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
memcpy(&newUser, pUser, sizeof(SUserObj));
|
||||
newUser.readDbs = mndDupDbHash(pUser->readDbs);
|
||||
newUser.writeDbs = mndDupDbHash(pUser->writeDbs);
|
||||
if (newUser.readDbs == NULL || newUser.writeDbs == NULL) {
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int32_t len = strlen(alterReq.dbname) + 1;
|
||||
|
@ -440,56 +441,56 @@ static int32_t mndProcessAlterUserReq(SNodeMsg *pReq) {
|
|||
if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
|
||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
|
||||
memcpy(pUser->pass, pass, TSDB_PASSWORD_LEN);
|
||||
memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN);
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
|
||||
newUser.superUser = alterReq.superUser;
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_ADD_READ_DB) {
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_EXIST;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
if (taosHashPut(newUser.readDbs, alterReq.dbname, len, alterReq.dbname, TSDB_DB_FNAME_LEN) != 0) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_READ_DB) {
|
||||
if (taosHashRemove(newUser.readDbs, alterReq.dbname, len) != 0) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_EXIST;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_READ_DB) {
|
||||
taosHashClear(newUser.readDbs);
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_ADD_WRITE_DB) {
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_EXIST;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
if (taosHashPut(newUser.writeDbs, alterReq.dbname, len, alterReq.dbname, TSDB_DB_FNAME_LEN) != 0) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_REMOVE_WRITE_DB) {
|
||||
if (taosHashRemove(newUser.writeDbs, alterReq.dbname, len) != 0) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_EXIST;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
} else if (alterReq.alterType == TSDB_ALTER_USER_CLEAR_WRITE_DB) {
|
||||
taosHashClear(newUser.writeDbs);
|
||||
} else {
|
||||
terrno = TSDB_CODE_MND_INVALID_ALTER_OPER;
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
newUser.updateTime = taosGetTimestampMs();
|
||||
|
||||
if (mndCheckAlterUserAuth(pOperUser, pUser, pDb, &alterReq) != 0) {
|
||||
goto ALTER_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndUpdateUser(pMnode, pUser, &newUser, pReq);
|
||||
code = mndAlterUser(pMnode, pUser, &newUser, pReq);
|
||||
if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
|
||||
ALTER_USER_OVER:
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to alter since %s", alterReq.user, terrstr());
|
||||
}
|
||||
|
@ -537,36 +538,36 @@ static int32_t mndProcessDropUserReq(SNodeMsg *pReq) {
|
|||
|
||||
if (tDeserializeSDropUserReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &dropReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto DROP_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
mDebug("user:%s, start to drop", dropReq.user);
|
||||
|
||||
if (dropReq.user[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
|
||||
goto DROP_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pUser = mndAcquireUser(pMnode, dropReq.user);
|
||||
if (pUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_USER_NOT_EXIST;
|
||||
goto DROP_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pOperUser = mndAcquireUser(pMnode, pReq->user);
|
||||
if (pOperUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_NO_USER_FROM_CONN;
|
||||
goto DROP_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDropUserAuth(pOperUser) != 0) {
|
||||
goto DROP_USER_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropUser(pMnode, pReq, pUser);
|
||||
if (code == 0) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
|
||||
DROP_USER_OVER:
|
||||
_OVER:
|
||||
if (code != 0 && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) {
|
||||
mError("user:%s, failed to drop since %s", dropReq.user, terrstr());
|
||||
}
|
||||
|
@ -586,7 +587,7 @@ static int32_t mndProcessGetUserAuthReq(SNodeMsg *pReq) {
|
|||
|
||||
if (tDeserializeSGetUserAuthReq(pReq->rpcMsg.pCont, pReq->rpcMsg.contLen, &authReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto GET_AUTH_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
mTrace("user:%s, start to get auth", authReq.user);
|
||||
|
@ -594,7 +595,7 @@ static int32_t mndProcessGetUserAuthReq(SNodeMsg *pReq) {
|
|||
pUser = mndAcquireUser(pMnode, authReq.user);
|
||||
if (pUser == NULL) {
|
||||
terrno = TSDB_CODE_MND_USER_NOT_EXIST;
|
||||
goto GET_AUTH_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
memcpy(authRsp.user, pUser->user, TSDB_USER_LEN);
|
||||
|
@ -622,7 +623,7 @@ static int32_t mndProcessGetUserAuthReq(SNodeMsg *pReq) {
|
|||
void *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto GET_AUTH_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
tSerializeSGetUserAuthRsp(pRsp, contLen, &authRsp);
|
||||
|
@ -631,10 +632,9 @@ static int32_t mndProcessGetUserAuthReq(SNodeMsg *pReq) {
|
|||
pReq->rspLen = contLen;
|
||||
code = 0;
|
||||
|
||||
GET_AUTH_OVER:
|
||||
_OVER:
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
taosHashCleanup(authRsp.readDbs);
|
||||
taosHashCleanup(authRsp.writeDbs);
|
||||
tFreeSGetUserAuthRsp(&authRsp);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -671,11 +671,6 @@ static int32_t mndRetrieveUsers(SNodeMsg *pReq, SShowObj *pShow, SSDataBlock *pB
|
|||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)&pUser->createdTime, false);
|
||||
|
||||
cols++;
|
||||
pColInfo = taosArrayGet(pBlock->pDataBlock, cols);
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(name, pUser->acct, pShow->bytes[cols]);
|
||||
colDataAppend(pColInfo, numOfRows, (const char *)name, false);
|
||||
|
||||
numOfRows++;
|
||||
sdbRelease(pSdb, pUser);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ int32_t mndInitVgroup(SMnode *pMnode) {
|
|||
.encodeFp = (SdbEncodeFp)mndVgroupActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndVgroupActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndVgroupActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndVgroupActionDelete,
|
||||
.deleteFp = (SdbDeleteFp)mndVgroupActionUpdate};
|
||||
.updateFp = (SdbUpdateFp)mndVgroupActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndVgroupActionDelete};
|
||||
|
||||
mndSetMsgHandle(pMnode, TDMT_DND_CREATE_VNODE_RSP, mndProcessCreateVnodeRsp);
|
||||
mndSetMsgHandle(pMnode, TDMT_VND_ALTER_VNODE_RSP, mndProcessAlterVnodeRsp);
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
|
||||
#define MQ_TIMER_MS 3000
|
||||
#define MQ_TIMER_MS 2000
|
||||
#define TRNAS_TIMER_MS 6000
|
||||
|
||||
static void *mndBuildTimerMsg(int32_t *pContLen) {
|
||||
|
@ -418,7 +418,6 @@ int64_t mndGenerateUid(char *name, int32_t len) {
|
|||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgroupInfo *pVgroupInfo,
|
||||
SMonGrantInfo *pGrantInfo) {
|
||||
if (!mndIsMaster(pMnode)) return -1;
|
||||
|
|
|
@ -8,6 +8,7 @@ add_subdirectory(func)
|
|||
add_subdirectory(mnode)
|
||||
add_subdirectory(profile)
|
||||
add_subdirectory(qnode)
|
||||
add_subdirectory(sdb)
|
||||
add_subdirectory(show)
|
||||
add_subdirectory(sma)
|
||||
add_subdirectory(snode)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
aux_source_directory(. MNODE_SDB_TEST_SRC)
|
||||
add_executable(sdbTest ${MNODE_SDB_TEST_SRC})
|
||||
target_link_libraries(
|
||||
sdbTest
|
||||
PUBLIC sut
|
||||
PUBLIC sdb
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME sdbTest
|
||||
COMMAND sdbTest
|
||||
)
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* @file sdbTest.cpp
|
||||
* @author slguan (slguan@taosdata.com)
|
||||
* @brief MNODE module sdb tests
|
||||
* @version 1.0
|
||||
* @date 2022-04-27
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#include "sut.h"
|
||||
|
||||
class MndTestShow : public ::testing::Test {
|
||||
protected:
|
||||
static void SetUpTestSuite() { test.Init("/tmp/mnode_test_show", 9021); }
|
||||
static void TearDownTestSuite() { test.Cleanup(); }
|
||||
|
||||
static Testbase test;
|
||||
|
||||
public:
|
||||
void SetUp() override {}
|
||||
void TearDown() override {}
|
||||
};
|
||||
|
||||
Testbase MndTestShow::test;
|
||||
|
||||
TEST_F(MndTestShow, 01_ShowMsg_InvalidMsgMax) {
|
||||
SShowReq showReq = {0};
|
||||
showReq.type = TSDB_MGMT_TABLE_MAX;
|
||||
|
||||
int32_t contLen = tSerializeSShowReq(NULL, 0, &showReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
tSerializeSShowReq(pReq, contLen, &showReq);
|
||||
tFreeSShowReq(&showReq);
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_MND_SYSTABLE_RETRIEVE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_NE(pRsp->code, 0);
|
||||
}
|
||||
|
||||
TEST_F(MndTestShow, 02_ShowMsg_InvalidMsgStart) {
|
||||
SShowReq showReq = {0};
|
||||
showReq.type = TSDB_MGMT_TABLE_START;
|
||||
|
||||
int32_t contLen = tSerializeSShowReq(NULL, 0, &showReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
tSerializeSShowReq(pReq, contLen, &showReq);
|
||||
tFreeSShowReq(&showReq);
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_MND_SYSTABLE_RETRIEVE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_NE(pRsp->code, 0);
|
||||
}
|
||||
|
||||
TEST_F(MndTestShow, 03_ShowMsg_Conn) {
|
||||
char passwd[] = "taosdata";
|
||||
char secretEncrypt[TSDB_PASSWORD_LEN] = {0};
|
||||
taosEncryptPass_c((uint8_t*)passwd, strlen(passwd), secretEncrypt);
|
||||
|
||||
SConnectReq connectReq = {0};
|
||||
connectReq.pid = 1234;
|
||||
strcpy(connectReq.app, "mnode_test_show");
|
||||
strcpy(connectReq.db, "");
|
||||
strcpy(connectReq.user, "root");
|
||||
strcpy(connectReq.passwd, secretEncrypt);
|
||||
|
||||
int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
tSerializeSConnectReq(pReq, contLen, &connectReq);
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_MND_CONNECT, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_EQ(pRsp->code, 0);
|
||||
|
||||
test.SendShowReq(TSDB_MGMT_TABLE_CONNS, "connections", "");
|
||||
// EXPECT_EQ(test.GetShowRows(), 1);
|
||||
}
|
||||
|
||||
TEST_F(MndTestShow, 04_ShowMsg_Cluster) {
|
||||
test.SendShowReq(TSDB_MGMT_TABLE_CLUSTER, "cluster", "");
|
||||
EXPECT_EQ(test.GetShowRows(), 1);
|
||||
}
|
|
@ -19,10 +19,6 @@
|
|||
#include "os.h"
|
||||
|
||||
#include "sdb.h"
|
||||
#include "thash.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tlog.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -53,26 +49,6 @@ typedef struct SSdbRow {
|
|||
char pObj[];
|
||||
} SSdbRow;
|
||||
|
||||
typedef struct SSdb {
|
||||
SMnode *pMnode;
|
||||
char *currDir;
|
||||
char *syncDir;
|
||||
char *tmpDir;
|
||||
int64_t lastCommitVer;
|
||||
int64_t curVer;
|
||||
int64_t tableVer[SDB_MAX];
|
||||
int64_t maxId[SDB_MAX];
|
||||
EKeyType keyTypes[SDB_MAX];
|
||||
SHashObj *hashObjs[SDB_MAX];
|
||||
SRWLatch locks[SDB_MAX];
|
||||
SdbInsertFp insertFps[SDB_MAX];
|
||||
SdbUpdateFp updateFps[SDB_MAX];
|
||||
SdbDeleteFp deleteFps[SDB_MAX];
|
||||
SdbDeployFp deployFps[SDB_MAX];
|
||||
SdbEncodeFp encodeFps[SDB_MAX];
|
||||
SdbDecodeFp decodeFps[SDB_MAX];
|
||||
} SSdb;
|
||||
|
||||
const char *sdbTableName(ESdbType type);
|
||||
void sdbPrintOper(SSdb *pSdb, SSdbRow *pRow, const char *oper);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void sdbCleanup(SSdb *pSdb) {
|
|||
SSdbRow *pRow = *ppRow;
|
||||
if (pRow == NULL) continue;
|
||||
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, true);
|
||||
ppRow = taosHashIterate(hash, ppRow);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
SSdbRow *pOldRow = taosHashGet(hash, pRow->pObj, keySize);
|
||||
if (pOldRow != NULL) {
|
||||
taosWUnLockLatch(pLock);
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, false);
|
||||
terrno = TSDB_CODE_SDB_OBJ_ALREADY_THERE;
|
||||
return terrno;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
|
||||
if (taosHashPut(hash, pRow->pObj, keySize, &pRow, sizeof(void *)) != 0) {
|
||||
taosWUnLockLatch(pLock);
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, false);
|
||||
terrno = TSDB_CODE_SDB_OBJ_ALREADY_THERE;
|
||||
return terrno;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ static int32_t sdbInsertRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
taosWLockLatch(pLock);
|
||||
taosHashRemove(hash, pRow->pObj, keySize);
|
||||
taosWUnLockLatch(pLock);
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, false);
|
||||
terrno = code;
|
||||
return terrno;
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ static int32_t sdbUpdateRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
code = (*updateFp)(pSdb, pOldRow->pObj, pNewRow->pObj);
|
||||
}
|
||||
|
||||
sdbFreeRow(pSdb, pNewRow);
|
||||
sdbFreeRow(pSdb, pNewRow, false);
|
||||
|
||||
pSdb->tableVer[pOldRow->type]++;
|
||||
return code;
|
||||
|
@ -215,7 +215,7 @@ static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
SSdbRow **ppOldRow = taosHashGet(hash, pRow->pObj, keySize);
|
||||
if (ppOldRow == NULL || *ppOldRow == NULL) {
|
||||
taosWUnLockLatch(pLock);
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, false);
|
||||
terrno = TSDB_CODE_SDB_OBJ_NOT_THERE;
|
||||
return terrno;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
|
|||
taosWUnLockLatch(pLock);
|
||||
|
||||
pSdb->tableVer[pOldRow->type]++;
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, false);
|
||||
|
||||
sdbCheck(pSdb, pOldRow);
|
||||
// sdbRelease(pSdb, pOldRow->pObj);
|
||||
|
@ -322,7 +322,7 @@ static void sdbCheck(SSdb *pSdb, SSdbRow *pRow) {
|
|||
int32_t ref = atomic_load_32(&pRow->refCount);
|
||||
sdbPrintOper(pSdb, pRow, "check");
|
||||
if (ref <= 0 && pRow->status == SDB_STATUS_DROPPED) {
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, true);
|
||||
}
|
||||
|
||||
taosRUnLockLatch(pLock);
|
||||
|
@ -340,7 +340,7 @@ void sdbRelease(SSdb *pSdb, void *pObj) {
|
|||
int32_t ref = atomic_sub_fetch_32(&pRow->refCount, 1);
|
||||
sdbPrintOper(pSdb, pRow, "release");
|
||||
if (ref <= 0 && pRow->status == SDB_STATUS_DROPPED) {
|
||||
sdbFreeRow(pSdb, pRow);
|
||||
sdbFreeRow(pSdb, pRow, true);
|
||||
}
|
||||
|
||||
taosRUnLockLatch(pLock);
|
||||
|
|
|
@ -107,7 +107,9 @@ int32_t sdbSetRawBinary(SSdbRaw *pRaw, int32_t dataPos, const char *pVal, int32_
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pVal != NULL) {
|
||||
memcpy(pRaw->pData + dataPos, pVal, valLen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@ void *sdbGetRowObj(SSdbRow *pRow) {
|
|||
return pRow->pObj;
|
||||
}
|
||||
|
||||
void sdbFreeRow(SSdb *pSdb, SSdbRow *pRow) {
|
||||
void sdbFreeRow(SSdb *pSdb, SSdbRow *pRow, bool callFunc) {
|
||||
// remove attached object such as trans
|
||||
SdbDeleteFp deleteFp = pSdb->deleteFps[pRow->type];
|
||||
if (deleteFp != NULL) {
|
||||
(*deleteFp)(pSdb, pRow->pObj);
|
||||
(*deleteFp)(pSdb, pRow->pObj, callFunc);
|
||||
}
|
||||
|
||||
sdbPrintOper(pSdb, pRow, "free");
|
||||
|
|
|
@ -19,7 +19,6 @@ target_sources(
|
|||
"src/meta/metaOpen.c"
|
||||
"src/meta/metaIdx.c"
|
||||
"src/meta/metaTable.c"
|
||||
"src/meta/metaTDBImpl.c"
|
||||
"src/meta/metaQuery.c"
|
||||
"src/meta/metaCommit.c"
|
||||
"src/meta/metaEntry.c"
|
||||
|
@ -28,12 +27,10 @@ target_sources(
|
|||
"src/tsdb/tsdbTDBImpl.c"
|
||||
"src/tsdb/tsdbCommit.c"
|
||||
"src/tsdb/tsdbCommit2.c"
|
||||
"src/tsdb/tsdbCompact.c"
|
||||
"src/tsdb/tsdbFile.c"
|
||||
"src/tsdb/tsdbFS.c"
|
||||
"src/tsdb/tsdbMain.c"
|
||||
"src/tsdb/tsdbOpen.c"
|
||||
"src/tsdb/tsdbMemTable.c"
|
||||
"src/tsdb/tsdbOptions.c"
|
||||
"src/tsdb/tsdbRead.c"
|
||||
"src/tsdb/tsdbReadImpl.c"
|
||||
"src/tsdb/tsdbScan.c"
|
||||
|
|
|
@ -68,14 +68,16 @@ void vnodeStop(SVnode *pVnode);
|
|||
|
||||
int64_t vnodeGetSyncHandle(SVnode *pVnode);
|
||||
void vnodeGetSnapshot(SVnode *pVnode, SSnapshot *pSnapshot);
|
||||
void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId);
|
||||
|
||||
// meta
|
||||
typedef struct SMeta SMeta; // todo: remove
|
||||
typedef struct SMetaReader SMetaReader;
|
||||
typedef struct SMetaEntry SMetaEntry;
|
||||
|
||||
void metaReaderInit(SMetaReader *pReader, SVnode *pVnode, int32_t flags);
|
||||
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags);
|
||||
void metaReaderClear(SMetaReader *pReader);
|
||||
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid);
|
||||
int metaReadNext(SMetaReader *pReader);
|
||||
|
||||
#if 1 // refact APIs below (TODO)
|
||||
|
@ -133,10 +135,6 @@ int32_t tqRetrieveDataBlock(SArray **ppCols, STqReadHandle *pHandle, uint64_t *p
|
|||
// need to reposition
|
||||
|
||||
// structs
|
||||
struct SMetaCfg {
|
||||
uint64_t lruSize;
|
||||
};
|
||||
|
||||
struct STsdbCfg {
|
||||
int8_t precision;
|
||||
int8_t update;
|
||||
|
@ -145,10 +143,9 @@ struct STsdbCfg {
|
|||
int32_t days;
|
||||
int32_t minRows;
|
||||
int32_t maxRows;
|
||||
int32_t keep2;
|
||||
int32_t keep0;
|
||||
int32_t keep1;
|
||||
uint64_t lruCacheSize;
|
||||
int32_t keep2;
|
||||
SArray *retentions;
|
||||
};
|
||||
|
||||
|
@ -160,8 +157,6 @@ struct SVnodeCfg {
|
|||
int32_t szCache;
|
||||
uint64_t szBuf;
|
||||
bool isHeap;
|
||||
uint32_t ttl;
|
||||
uint32_t keep;
|
||||
int8_t streamMode;
|
||||
bool isWeak;
|
||||
STsdbCfg tsdbCfg;
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
#ifndef _TD_VNODE_META_H_
|
||||
#define _TD_VNODE_META_H_
|
||||
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SMetaIdx SMetaIdx;
|
||||
typedef struct SMetaDB SMetaDB;
|
||||
typedef struct SMCtbCursor SMCtbCursor;
|
||||
typedef struct SMSmaCursor SMSmaCursor;
|
||||
|
||||
// metaDebug ==================
|
||||
|
@ -36,22 +37,16 @@ typedef struct SMSmaCursor SMSmaCursor;
|
|||
// clang-format on
|
||||
|
||||
// metaOpen ==================
|
||||
int metaOpen(SVnode* pVnode, SMeta** ppMeta);
|
||||
int metaClose(SMeta* pMeta);
|
||||
|
||||
// metaEntry ==================
|
||||
int metaEncodeEntry(SCoder* pCoder, const SMetaEntry* pME);
|
||||
int metaDecodeEntry(SCoder* pCoder, SMetaEntry* pME);
|
||||
|
||||
// metaTable ==================
|
||||
int metaCreateSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
||||
int metaDropSTable(SMeta* pMeta, int64_t verison, SVDropStbReq* pReq);
|
||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq);
|
||||
|
||||
// metaQuery ==================
|
||||
int metaGetTableEntryByVersion(SMetaReader* pReader, int64_t version, tb_uid_t uid);
|
||||
int metaGetTableEntryByUid(SMetaReader* pReader, tb_uid_t uid);
|
||||
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
|
||||
|
||||
// metaIdx ==================
|
||||
int metaOpenIdx(SMeta* pMeta);
|
||||
|
@ -60,8 +55,6 @@ int metaSaveTableToIdx(SMeta* pMeta, const STbCfg* pTbOptions);
|
|||
int metaRemoveTableFromIdx(SMeta* pMeta, tb_uid_t uid);
|
||||
|
||||
// metaCommit ==================
|
||||
int metaBegin(SMeta* pMeta);
|
||||
|
||||
static FORCE_INLINE tb_uid_t metaGenerateUid(SMeta* pMeta) { return tGenIdPI64(); }
|
||||
|
||||
struct SMeta {
|
||||
|
@ -106,27 +99,12 @@ typedef struct {
|
|||
} STtlIdxKey;
|
||||
|
||||
#if 1
|
||||
#define META_SUPER_TABLE TD_SUPER_TABLE
|
||||
#define META_CHILD_TABLE TD_CHILD_TABLE
|
||||
#define META_NORMAL_TABLE TD_NORMAL_TABLE
|
||||
|
||||
// int metaCreateTable(SMeta* pMeta, STbCfg* pTbCfg, STbDdlH* pHandle);
|
||||
int metaDropTable(SMeta* pMeta, tb_uid_t uid);
|
||||
int metaCommit(SMeta* pMeta);
|
||||
int32_t metaCreateTSma(SMeta* pMeta, SSmaCfg* pCfg);
|
||||
int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid);
|
||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
|
||||
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
|
||||
void* metaGetSmaInfoByIndex(SMeta* pMeta, int64_t indexUid, bool isDecode);
|
||||
STSmaWrapper* metaGetSmaInfoByTable(SMeta* pMeta, tb_uid_t uid);
|
||||
SArray* metaGetSmaTbUids(SMeta* pMeta, bool isDup);
|
||||
int metaGetTbNum(SMeta* pMeta);
|
||||
SMSmaCursor* metaOpenSmaCursor(SMeta* pMeta, tb_uid_t uid);
|
||||
void metaCloseSmaCursor(SMSmaCursor* pSmaCur);
|
||||
int64_t metaSmaCursorNext(SMSmaCursor* pSmaCur);
|
||||
SMCtbCursor* metaOpenCtbCursor(SMeta* pMeta, tb_uid_t uid);
|
||||
void metaCloseCtbCurosr(SMCtbCursor* pCtbCur);
|
||||
tb_uid_t metaCtbCursorNext(SMCtbCursor* pCtbCur);
|
||||
|
||||
#ifndef META_REFACT
|
||||
// SMetaDB
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef _TD_VNODE_TQ_H_
|
||||
#define _TD_VNODE_TQ_H_
|
||||
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#include "executor.h"
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
|
@ -237,17 +239,7 @@ int tqInit();
|
|||
void tqCleanUp();
|
||||
|
||||
// open in each vnode
|
||||
STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal);
|
||||
void tqClose(STQ*);
|
||||
// required by vnode
|
||||
int tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
|
||||
int tqCommit(STQ*);
|
||||
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId);
|
||||
int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessTaskExec(STQ* pTq, char* msg, int32_t msgLen, int32_t workerId);
|
||||
int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, void* data, int32_t dataLen, int32_t workerId);
|
||||
|
||||
int32_t tqSerializeConsumer(const STqConsumer*, STqSerializedHead**);
|
||||
int32_t tqDeserializeConsumer(STQ*, const STqSerializedHead*, STqConsumer**);
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef _TD_VNODE_TSDB_H_
|
||||
#define _TD_VNODE_TSDB_H_
|
||||
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -43,14 +45,46 @@ int tsdbLoadDataFromCache(STable *pTable, SSkipListIterator *pIter, TSKEY maxKe
|
|||
TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo);
|
||||
|
||||
// tsdbCommit ================
|
||||
int tsdbBegin(STsdb *pTsdb);
|
||||
|
||||
#if 1
|
||||
// tsdbFS ================
|
||||
typedef struct STsdbFS STsdbFS;
|
||||
|
||||
typedef struct SSmaStat SSmaStat;
|
||||
// tsdbSma ================
|
||||
typedef struct SSmaEnv SSmaEnv;
|
||||
typedef struct SSmaEnvs SSmaEnvs;
|
||||
|
||||
// structs
|
||||
typedef struct {
|
||||
int minFid;
|
||||
int midFid;
|
||||
int maxFid;
|
||||
TSKEY minKey;
|
||||
} SRtn;
|
||||
|
||||
struct SSmaEnvs {
|
||||
int16_t nTSma;
|
||||
int16_t nRSma;
|
||||
SSmaEnv *pTSmaEnv;
|
||||
SSmaEnv *pRSmaEnv;
|
||||
};
|
||||
|
||||
struct STsdb {
|
||||
char *path;
|
||||
SVnode *pVnode;
|
||||
bool repoLocked;
|
||||
TdThreadMutex mutex;
|
||||
STsdbCfg config;
|
||||
STsdbMemTable *mem;
|
||||
STsdbMemTable *imem;
|
||||
SRtn rtn;
|
||||
STsdbFS *fs;
|
||||
SSmaEnvs smaEnvs;
|
||||
};
|
||||
|
||||
#if 1 // ======================================
|
||||
|
||||
typedef struct SSmaStat SSmaStat;
|
||||
|
||||
struct STable {
|
||||
uint64_t tid;
|
||||
uint64_t uid;
|
||||
|
@ -60,16 +94,9 @@ struct STable {
|
|||
#define TABLE_TID(t) (t)->tid
|
||||
#define TABLE_UID(t) (t)->uid
|
||||
|
||||
int tsdbOpen(SVnode *pVnode, STsdb **ppTsdb);
|
||||
int tsdbClose(STsdb *pTsdb);
|
||||
int tsdbInsertData(STsdb *pTsdb, int64_t version, SSubmitReq *pMsg, SSubmitRsp *pRsp);
|
||||
int tsdbPrepareCommit(STsdb *pTsdb);
|
||||
int tsdbCommit(STsdb *pTsdb);
|
||||
int32_t tsdbInitSma(STsdb *pTsdb);
|
||||
int32_t tsdbCreateTSma(STsdb *pTsdb, char *pMsg);
|
||||
int32_t tsdbDropTSma(STsdb *pTsdb, char *pMsg);
|
||||
int32_t tsdbUpdateSmaWindow(STsdb *pTsdb, SSubmitReq *pMsg, int64_t version);
|
||||
int32_t tsdbInsertTSmaData(STsdb *pTsdb, int64_t indexUid, const char *msg);
|
||||
int32_t tsdbDropTSmaData(STsdb *pTsdb, int64_t indexUid);
|
||||
int32_t tsdbInsertRSmaData(STsdb *pTsdb, char *msg);
|
||||
void tsdbCleanupReadHandle(tsdbReaderT queryHandle);
|
||||
|
@ -103,13 +130,6 @@ typedef struct {
|
|||
uint8_t state;
|
||||
} SDFile;
|
||||
|
||||
struct SSmaEnvs {
|
||||
int16_t nTSma;
|
||||
int16_t nRSma;
|
||||
SSmaEnv *pTSmaEnv;
|
||||
SSmaEnv *pRSmaEnv;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int fid;
|
||||
int8_t state; // -128~127
|
||||
|
@ -118,13 +138,6 @@ typedef struct {
|
|||
SDFile files[TSDB_FILE_MAX];
|
||||
} SDFileSet;
|
||||
|
||||
typedef struct {
|
||||
int minFid;
|
||||
int midFid;
|
||||
int maxFid;
|
||||
TSKEY minKey;
|
||||
} SRtn;
|
||||
|
||||
struct STbData {
|
||||
tb_uid_t uid;
|
||||
TSKEY keyMin;
|
||||
|
@ -161,7 +174,7 @@ typedef struct {
|
|||
SArray *sf; // sma data file array v2f1900.index_name_1
|
||||
} SFSStatus;
|
||||
|
||||
typedef struct {
|
||||
struct STsdbFS {
|
||||
TdThreadRwlock lock;
|
||||
|
||||
SFSStatus *cstatus; // current status
|
||||
|
@ -169,23 +182,9 @@ typedef struct {
|
|||
SHashObj *metaCacheComp; // meta cache for compact
|
||||
bool intxn;
|
||||
SFSStatus *nstatus; // new status
|
||||
} STsdbFS;
|
||||
|
||||
struct STsdb {
|
||||
char *path;
|
||||
SVnode *pVnode;
|
||||
int32_t vgId;
|
||||
bool repoLocked;
|
||||
TdThreadMutex mutex;
|
||||
STsdbCfg config;
|
||||
STsdbMemTable *mem;
|
||||
STsdbMemTable *imem;
|
||||
SRtn rtn;
|
||||
STsdbFS *fs;
|
||||
SSmaEnvs smaEnvs;
|
||||
};
|
||||
|
||||
#define REPO_ID(r) ((r)->vgId)
|
||||
#define REPO_ID(r) TD_VID((r)->pVnode)
|
||||
#define REPO_CFG(r) (&(r)->config)
|
||||
#define REPO_FS(r) ((r)->fs)
|
||||
#define REPO_META(r) ((r)->pVnode->pMeta)
|
||||
|
@ -237,12 +236,6 @@ static FORCE_INLINE TSKEY tsdbNextIterKey(SSkipListIterator *pIter) {
|
|||
return TD_ROW_KEY(row);
|
||||
}
|
||||
|
||||
// tsdbOptions
|
||||
extern const STsdbCfg defautlTsdbOptions;
|
||||
|
||||
int tsdbValidateOptions(const STsdbCfg *);
|
||||
void tsdbOptionsCopy(STsdbCfg *pDest, const STsdbCfg *pSrc);
|
||||
|
||||
// tsdbReadImpl
|
||||
typedef struct SReadH SReadH;
|
||||
|
||||
|
@ -519,12 +512,6 @@ static FORCE_INLINE void *taosTZfree(void *ptr) {
|
|||
|
||||
// tsdbCommit
|
||||
|
||||
typedef struct {
|
||||
uint64_t uid;
|
||||
int64_t offset;
|
||||
int64_t size;
|
||||
} SKVRecord;
|
||||
|
||||
void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn);
|
||||
|
||||
static FORCE_INLINE int TSDB_KEY_FID(TSKEY key, int32_t days, int8_t precision) {
|
||||
|
@ -903,66 +890,6 @@ static FORCE_INLINE int tsdbUnLockFS(STsdbFS *pFs) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// tsdbSma
|
||||
// #define TSDB_SMA_TEST // remove after test finished
|
||||
|
||||
// struct SSmaEnv {
|
||||
// TdThreadRwlock lock;
|
||||
// SDiskID did;
|
||||
// TDBEnv dbEnv; // TODO: If it's better to put it in smaIndex level?
|
||||
// char *path; // relative path
|
||||
// SSmaStat *pStat;
|
||||
// };
|
||||
|
||||
// #define SMA_ENV_LOCK(env) ((env)->lock)
|
||||
// #define SMA_ENV_DID(env) ((env)->did)
|
||||
// #define SMA_ENV_ENV(env) ((env)->dbEnv)
|
||||
// #define SMA_ENV_PATH(env) ((env)->path)
|
||||
// #define SMA_ENV_STAT(env) ((env)->pStat)
|
||||
// #define SMA_ENV_STAT_ITEMS(env) ((env)->pStat->smaStatItems)
|
||||
|
||||
// void tsdbDestroySmaEnv(SSmaEnv *pSmaEnv);
|
||||
// void *tsdbFreeSmaEnv(SSmaEnv *pSmaEnv);
|
||||
// #if 0
|
||||
// int32_t tsdbGetTSmaStatus(STsdb *pTsdb, STSma *param, void *result);
|
||||
// int32_t tsdbRemoveTSmaData(STsdb *pTsdb, STSma *param, STimeWindow *pWin);
|
||||
// #endif
|
||||
|
||||
// // internal func
|
||||
// static FORCE_INLINE int32_t tsdbEncodeTSmaKey(int64_t groupId, TSKEY tsKey, void **pData) {
|
||||
// int32_t len = 0;
|
||||
// len += taosEncodeFixedI64(pData, tsKey);
|
||||
// len += taosEncodeFixedI64(pData, groupId);
|
||||
// return len;
|
||||
// }
|
||||
|
||||
// static FORCE_INLINE int32_t tsdbRLockSma(SSmaEnv *pEnv) {
|
||||
// int code = taosThreadRwlockRdlock(&(pEnv->lock));
|
||||
// if (code != 0) {
|
||||
// terrno = TAOS_SYSTEM_ERROR(code);
|
||||
// return -1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static FORCE_INLINE int32_t tsdbWLockSma(SSmaEnv *pEnv) {
|
||||
// int code = taosThreadRwlockWrlock(&(pEnv->lock));
|
||||
// if (code != 0) {
|
||||
// terrno = TAOS_SYSTEM_ERROR(code);
|
||||
// return -1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static FORCE_INLINE int32_t tsdbUnLockSma(SSmaEnv *pEnv) {
|
||||
// int code = taosThreadRwlockUnlock(&(pEnv->lock));
|
||||
// if (code != 0) {
|
||||
// terrno = TAOS_SYSTEM_ERROR(code);
|
||||
// return -1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
typedef struct SSmaKey SSmaKey;
|
||||
|
||||
struct SSmaKey {
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
#ifndef _TD_VNODE_TSDB_SMA_H_
|
||||
#define _TD_VNODE_TSDB_SMA_H_
|
||||
|
||||
#include "os.h"
|
||||
#include "thash.h"
|
||||
#include "tmsg.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -32,12 +30,6 @@ struct STbDdlH {
|
|||
__tb_ddl_fn_t fp;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
tb_uid_t suid;
|
||||
SArray *tbUids;
|
||||
SHashObj *uidHash;
|
||||
} STbUidStore;
|
||||
|
||||
static FORCE_INLINE int32_t tsdbUidStoreInit(STbUidStore **pStore) {
|
||||
ASSERT(*pStore == NULL);
|
||||
*pStore = taosMemoryCalloc(1, sizeof(STbUidStore));
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
#ifndef _TD_VND_H_
|
||||
#define _TD_VND_H_
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncTools.h"
|
||||
#include "vnodeInt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -61,8 +65,6 @@ struct SVBufPool {
|
|||
int vnodeOpenBufPool(SVnode* pVnode, int64_t size);
|
||||
int vnodeCloseBufPool(SVnode* pVnode);
|
||||
void vnodeBufPoolReset(SVBufPool* pPool);
|
||||
void* vnodeBufPoolMalloc(SVBufPool* pPool, int size);
|
||||
void vnodeBufPoolFree(SVBufPool* pPool, void* p);
|
||||
|
||||
// vnodeQuery ====================
|
||||
int vnodeQueryOpen(SVnode* pVnode);
|
||||
|
@ -79,6 +81,20 @@ int vnodeLoadInfo(const char* dir, SVnodeInfo* pInfo);
|
|||
int vnodeSyncCommit(SVnode* pVnode);
|
||||
int vnodeAsyncCommit(SVnode* pVnode);
|
||||
|
||||
// vnodeCommit ====================
|
||||
int32_t vnodeSyncOpen(SVnode* pVnode, char* path);
|
||||
int32_t vnodeSyncStart(SVnode* pVnode);
|
||||
void vnodeSyncClose(SVnode* pVnode);
|
||||
void vnodeSyncSetQ(SVnode* pVnode, void* qHandle);
|
||||
void vnodeSyncSetRpc(SVnode* pVnode, void* rpcHandle);
|
||||
int32_t vnodeSyncEqMsg(void* qHandle, SRpcMsg* pMsg);
|
||||
int32_t vnodeSendMsg(void* rpcHandle, const SEpSet* pEpSet, SRpcMsg* pMsg);
|
||||
void vnodeSyncCommitCb(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
void vnodeSyncPreCommitCb(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
void vnodeSyncRollBackCb(struct SSyncFSM* pFsm, const SRpcMsg* pMsg, SFsmCbMeta cbMeta);
|
||||
int32_t vnodeSyncGetSnapshotCb(struct SSyncFSM* pFsm, SSnapshot* pSnapshot);
|
||||
SSyncFSM* syncVnodeMakeFsm();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -59,6 +59,54 @@ typedef struct SQWorkerMgmt SQHandle;
|
|||
#define VNODE_TQ_DIR "tq"
|
||||
#define VNODE_WAL_DIR "wal"
|
||||
|
||||
// vnd.h
|
||||
void* vnodeBufPoolMalloc(SVBufPool* pPool, int size);
|
||||
void vnodeBufPoolFree(SVBufPool* pPool, void* p);
|
||||
|
||||
// meta
|
||||
typedef struct SMCtbCursor SMCtbCursor;
|
||||
typedef struct STbUidStore STbUidStore;
|
||||
|
||||
int metaOpen(SVnode* pVnode, SMeta** ppMeta);
|
||||
int metaClose(SMeta* pMeta);
|
||||
int metaBegin(SMeta* pMeta);
|
||||
int metaCommit(SMeta* pMeta);
|
||||
int metaCreateSTable(SMeta* pMeta, int64_t version, SVCreateStbReq* pReq);
|
||||
int metaCreateTable(SMeta* pMeta, int64_t version, SVCreateTbReq* pReq);
|
||||
SSchemaWrapper* metaGetTableSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver, bool isinline);
|
||||
STSchema* metaGetTbTSchema(SMeta* pMeta, tb_uid_t uid, int32_t sver);
|
||||
int metaGetTableEntryByName(SMetaReader* pReader, const char* name);
|
||||
int metaGetTbNum(SMeta* pMeta);
|
||||
SMCtbCursor* metaOpenCtbCursor(SMeta* pMeta, tb_uid_t uid);
|
||||
void metaCloseCtbCurosr(SMCtbCursor* pCtbCur);
|
||||
tb_uid_t metaCtbCursorNext(SMCtbCursor* pCtbCur);
|
||||
SArray* metaGetSmaTbUids(SMeta* pMeta, bool isDup);
|
||||
void* metaGetSmaInfoByIndex(SMeta* pMeta, int64_t indexUid, bool isDecode);
|
||||
STSmaWrapper* metaGetSmaInfoByTable(SMeta* pMeta, tb_uid_t uid);
|
||||
int32_t metaCreateTSma(SMeta* pMeta, SSmaCfg* pCfg);
|
||||
int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid);
|
||||
|
||||
// tsdb
|
||||
int tsdbOpen(SVnode* pVnode, STsdb** ppTsdb);
|
||||
int tsdbClose(STsdb* pTsdb);
|
||||
int tsdbBegin(STsdb* pTsdb);
|
||||
int tsdbCommit(STsdb* pTsdb);
|
||||
int32_t tsdbUpdateSmaWindow(STsdb* pTsdb, SSubmitReq* pMsg, int64_t version);
|
||||
int32_t tsdbCreateTSma(STsdb* pTsdb, char* pMsg);
|
||||
int32_t tsdbInsertTSmaData(STsdb* pTsdb, int64_t indexUid, const char* msg);
|
||||
int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSubmitRsp* pRsp);
|
||||
|
||||
// tq
|
||||
STQ* tqOpen(const char* path, SVnode* pVnode, SWal* pWal);
|
||||
void tqClose(STQ*);
|
||||
int tqPushMsg(STQ*, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver);
|
||||
int tqCommit(STQ*);
|
||||
int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessTaskExec(STQ* pTq, char* msg, int32_t msgLen, int32_t workerId);
|
||||
int32_t tqProcessTaskDeploy(STQ* pTq, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessStreamTrigger(STQ* pTq, void* data, int32_t dataLen, int32_t workerId);
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId);
|
||||
|
||||
typedef struct {
|
||||
int8_t streamType; // sma or other
|
||||
int8_t dstType;
|
||||
|
@ -106,6 +154,12 @@ struct SVnode {
|
|||
SQHandle* pQuery;
|
||||
};
|
||||
|
||||
struct STbUidStore {
|
||||
tb_uid_t suid;
|
||||
SArray* tbUids;
|
||||
SHashObj* uidHash;
|
||||
};
|
||||
|
||||
#define TD_VID(PVNODE) (PVNODE)->config.vgId
|
||||
|
||||
typedef struct STbDdlH STbDdlH;
|
||||
|
@ -113,18 +167,6 @@ typedef struct STbDdlH STbDdlH;
|
|||
// sma
|
||||
void smaHandleRes(void* pVnode, int64_t smaId, const SArray* data);
|
||||
|
||||
#include "vnd.h"
|
||||
|
||||
#include "meta.h"
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
#include "tq.h"
|
||||
|
||||
#include "vnodeSync.h"
|
||||
|
||||
#include "tsdbSma.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_VNODE_SYNC_H_
|
||||
#define _TD_VNODE_SYNC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t vnodeSyncOpen(SVnode *pVnode, char *path);
|
||||
int32_t vnodeSyncStart(SVnode *pVnode);
|
||||
void vnodeSyncClose(SVnode *pVnode);
|
||||
|
||||
void vnodeSyncSetQ(SVnode *pVnode, void *qHandle);
|
||||
void vnodeSyncSetRpc(SVnode *pVnode, void *rpcHandle);
|
||||
|
||||
int32_t vnodeSyncEqMsg(void *qHandle, SRpcMsg *pMsg);
|
||||
int32_t vnodeSendMsg(void *rpcHandle, const SEpSet *pEpSet, SRpcMsg *pMsg);
|
||||
|
||||
void vnodeSyncCommitCb(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
void vnodeSyncPreCommitCb(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
void vnodeSyncRollBackCb(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
int32_t vnodeSyncGetSnapshotCb(struct SSyncFSM *pFsm, SSnapshot *pSnapshot);
|
||||
|
||||
SSyncFSM *syncVnodeMakeFsm();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_VNODE_SYNC_H_*/
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
static FORCE_INLINE void *metaMalloc(void *pPool, size_t size) { return vnodeBufPoolMalloc((SVBufPool *)pPool, size); }
|
||||
static FORCE_INLINE void metaFree(void *pPool, void *p) { vnodeBufPoolFree((SVBufPool *)pPool, p); }
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
int metaEncodeEntry(SCoder *pCoder, const SMetaEntry *pME) {
|
||||
if (tStartEncode(pCoder) < 0) return -1;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#ifdef USE_INVERTED_INDEX
|
||||
#include "index.h"
|
||||
#endif
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
struct SMetaIdx {
|
||||
#ifdef USE_INVERTED_INDEX
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
static int tbDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||
static int skmDbKeyCmpr(const void *pKey1, int kLen1, const void *pKey2, int kLen2);
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
void metaReaderInit(SMetaReader *pReader, SVnode *pVnode, int32_t flags) {
|
||||
void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
|
||||
memset(pReader, 0, sizeof(*pReader));
|
||||
pReader->flags = flags;
|
||||
pReader->pMeta = pVnode->pMeta;
|
||||
pReader->pMeta = pMeta;
|
||||
}
|
||||
|
||||
void metaReaderClear(SMetaReader *pReader) {
|
||||
|
@ -32,6 +32,7 @@ int metaGetTableEntryByVersion(SMetaReader *pReader, int64_t version, tb_uid_t u
|
|||
|
||||
// query table.db
|
||||
if (tdbDbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pReader->pBuf, &pReader->szBuf) < 0) {
|
||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
|
@ -54,6 +55,7 @@ int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
|
|||
|
||||
// query uid.idx
|
||||
if (tdbDbGet(pMeta->pUidIdx, &uid, sizeof(uid), &pReader->pBuf, &pReader->szBuf) < 0) {
|
||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -67,6 +69,7 @@ int metaGetTableEntryByName(SMetaReader *pReader, const char *name) {
|
|||
|
||||
// query name.idx
|
||||
if (tdbDbGet(pMeta->pNameIdx, name, strlen(name) + 1, &pReader->pBuf, &pReader->szBuf) < 0) {
|
||||
terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -91,7 +94,7 @@ SMTbCursor *metaOpenTbCursor(SMeta *pMeta) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
metaReaderInit(&pTbCur->mr, pMeta->pVnode, 0);
|
||||
metaReaderInit(&pTbCur->mr, pMeta, 0);
|
||||
|
||||
tdbDbcOpen(pMeta->pUidIdx, &pTbCur->pDbc);
|
||||
|
||||
|
@ -122,7 +125,7 @@ int metaTbCursorNext(SMTbCursor *pTbCur) {
|
|||
}
|
||||
|
||||
metaGetTableEntryByVersion(&pTbCur->mr, *(int64_t *)pTbCur->pVal, *(tb_uid_t *)pTbCur->pKey);
|
||||
if (pTbCur->mr.me.type == META_SUPER_TABLE) {
|
||||
if (pTbCur->mr.me.type == TSDB_SUPER_TABLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -234,7 +237,7 @@ STSchema *metaGetTbTSchema(SMeta *pMeta, tb_uid_t uid, int32_t sver) {
|
|||
STSchemaBuilder sb = {0};
|
||||
SSchema *pSchema;
|
||||
|
||||
metaReaderInit(&mr, pMeta->pVnode, 0);
|
||||
metaReaderInit(&mr, pMeta, 0);
|
||||
metaGetTableEntryByUid(&mr, uid);
|
||||
|
||||
if (mr.me.type == TSDB_CHILD_TABLE) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "meta.h"
|
||||
|
||||
static int metaHandleEntry(SMeta *pMeta, const SMetaEntry *pME);
|
||||
static int metaSaveToTbDb(SMeta *pMeta, const SMetaEntry *pME);
|
||||
|
@ -37,7 +37,7 @@ int metaCreateSTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
|
|||
SMetaReader mr = {0};
|
||||
|
||||
// validate req
|
||||
metaReaderInit(&mr, pMeta->pVnode, 0);
|
||||
metaReaderInit(&mr, pMeta, 0);
|
||||
if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
|
||||
// TODO: just for pass case
|
||||
#if 0
|
||||
|
@ -88,10 +88,10 @@ int metaCreateTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq) {
|
|||
|
||||
// preprocess req
|
||||
pReq->uid = tGenIdPI64();
|
||||
pReq->ctime = taosGetTimestampSec();
|
||||
pReq->ctime = taosGetTimestampMs();
|
||||
|
||||
// validate req
|
||||
metaReaderInit(&mr, pMeta->pVnode, 0);
|
||||
metaReaderInit(&mr, pMeta, 0);
|
||||
if (metaGetTableEntryByName(&mr, pReq->name) == 0) {
|
||||
terrno = TSDB_CODE_TDB_TABLE_ALREADY_EXIST;
|
||||
metaReaderClear(&mr);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tq.h"
|
||||
|
||||
int32_t tqInit() {
|
||||
//
|
||||
|
@ -78,7 +78,7 @@ int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_
|
|||
|
||||
SMqDataBlkRsp rsp = {0};
|
||||
rsp.reqOffset = pExec->pushHandle.reqOffset;
|
||||
rsp.blockData = taosArrayInit(0, sizeof(int32_t));
|
||||
rsp.blockData = taosArrayInit(0, sizeof(void*));
|
||||
rsp.blockDataLen = taosArrayInit(0, sizeof(int32_t));
|
||||
|
||||
if (pExec->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
|
@ -176,7 +176,7 @@ int32_t tqPushMsgNew(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_
|
|||
atomic_store_ptr(&pExec->pushHandle.handle, NULL);
|
||||
taosWUnLockLatch(&pExec->pushHandle.lock);
|
||||
|
||||
vDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
|
||||
tqDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
|
||||
TD_VID(pTq->pVnode), fetchOffset, pExec->pushHandle.consumerId, pExec->pushHandle.epoch, rsp.blockNum,
|
||||
rsp.reqOffset, rsp.rspOffset);
|
||||
|
||||
|
@ -210,35 +210,6 @@ int tqPushMsg(STQ* pTq, void* msg, int32_t msgLen, tmsg_t msgType, int64_t ver)
|
|||
|
||||
tmsgPutToQueue(&pTq->pVnode->msgCb, FETCH_QUEUE, &req);
|
||||
|
||||
#if 0
|
||||
void* pIter = taosHashIterate(pTq->tqPushMgr->pHash, NULL);
|
||||
while (pIter != NULL) {
|
||||
STqPusher* pusher = *(STqPusher**)pIter;
|
||||
if (pusher->type == TQ_PUSHER_TYPE__STREAM) {
|
||||
STqStreamPusher* streamPusher = (STqStreamPusher*)pusher;
|
||||
// repack
|
||||
STqStreamToken* token = taosMemoryMalloc(sizeof(STqStreamToken));
|
||||
if (token == NULL) {
|
||||
taosHashCancelIterate(pTq->tqPushMgr->pHash, pIter);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
token->type = TQ_STREAM_TOKEN__DATA;
|
||||
token->data = msg;
|
||||
// set input
|
||||
// exec
|
||||
}
|
||||
// send msg to ep
|
||||
}
|
||||
// iterate hash
|
||||
// process all msg
|
||||
// if waiting
|
||||
// memcpy and send msg to fetch thread
|
||||
// TODO: add reference
|
||||
// if handle waiting, launch query and response to consumer
|
||||
//
|
||||
// if no waiting handle, return
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -375,9 +346,9 @@ int32_t tqDeserializeConsumer(STQ* pTq, const STqSerializedHead* pHead, STqConsu
|
|||
}
|
||||
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
||||
SMqPollReqV2* pReq = pMsg->pCont;
|
||||
SMqPollReq* pReq = pMsg->pCont;
|
||||
int64_t consumerId = pReq->consumerId;
|
||||
int64_t waitTime = pReq->blockingTime;
|
||||
int64_t waitTime = pReq->waitTime;
|
||||
int32_t reqEpoch = pReq->epoch;
|
||||
int64_t fetchOffset;
|
||||
|
||||
|
@ -390,7 +361,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
fetchOffset = pReq->currentOffset + 1;
|
||||
}
|
||||
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), pReq->currentOffset, fetchOffset);
|
||||
|
||||
STqExec* pExec = taosHashGet(pTq->execs, pReq->subKey, strlen(pReq->subKey));
|
||||
|
@ -418,7 +389,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
while (1) {
|
||||
consumerEpoch = atomic_load_32(&pExec->epoch);
|
||||
if (consumerEpoch > reqEpoch) {
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
|
||||
consumerId, pReq->epoch, TD_VID(pTq->pVnode), fetchOffset, consumerEpoch, reqEpoch);
|
||||
break;
|
||||
}
|
||||
|
@ -426,7 +397,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
taosThreadMutexLock(&pExec->pWalReader->mutex);
|
||||
|
||||
if (walFetchHead(pExec->pWalReader, fetchOffset, pHeadWithCkSum) < 0) {
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset);
|
||||
taosThreadMutexUnlock(&pExec->pWalReader->mutex);
|
||||
break;
|
||||
|
@ -448,7 +419,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
// TODO: no more log, set timer to wait blocking time
|
||||
// if data inserted during waiting, launch query and
|
||||
// response to user
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset);
|
||||
|
||||
#if 0
|
||||
|
@ -476,7 +447,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
}
|
||||
#endif
|
||||
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
|
||||
|
||||
if (pHead->msgType == TDMT_VND_SUBMIT) {
|
||||
|
@ -591,7 +562,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
pMsg->code = 0;
|
||||
tmsgSendRsp(pMsg);
|
||||
|
||||
vDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
|
||||
tqDebug("vg %d offset %ld from consumer %ld (epoch %d) send rsp, block num: %d, reqOffset: %ld, rspOffset: %ld",
|
||||
TD_VID(pTq->pVnode), fetchOffset, consumerId, pReq->epoch, rsp.blockNum, rsp.reqOffset, rsp.rspOffset);
|
||||
|
||||
// TODO destroy
|
||||
|
@ -618,7 +589,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
fetchOffset = pReq->currentOffset + 1;
|
||||
}
|
||||
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) recv poll req in vg %d, req %ld %ld", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), pReq->currentOffset, fetchOffset);
|
||||
|
||||
SMqPollRspV2 rspV2 = {0};
|
||||
|
@ -660,7 +631,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
vDebug("poll topic %s from consumer %ld (epoch %d) vg %d", pTopic->topicName, consumerId, pReq->epoch,
|
||||
tqDebug("poll topic %s from consumer %ld (epoch %d) vg %d", pTopic->topicName, consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode));
|
||||
|
||||
rspV2.reqOffset = pReq->currentOffset;
|
||||
|
@ -671,7 +642,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
// TODO
|
||||
consumerEpoch = atomic_load_32(&pConsumer->epoch);
|
||||
if (consumerEpoch > reqEpoch) {
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, found new consumer epoch %d discard req epoch %d",
|
||||
consumerId, pReq->epoch, TD_VID(pTq->pVnode), fetchOffset, consumerEpoch, reqEpoch);
|
||||
break;
|
||||
}
|
||||
|
@ -680,11 +651,11 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
// TODO: no more log, set timer to wait blocking time
|
||||
// if data inserted during waiting, launch query and
|
||||
// response to user
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) vg %d offset %ld, no more log to return", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset);
|
||||
break;
|
||||
}
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d offset %ld msgType %d", consumerId, pReq->epoch,
|
||||
TD_VID(pTq->pVnode), fetchOffset, pHead->msgType);
|
||||
/*int8_t pos = fetchOffset % TQ_BUFFER_SIZE;*/
|
||||
/*pHead = pTopic->pReadhandle->pHead;*/
|
||||
|
@ -709,7 +680,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
}
|
||||
|
||||
if (taosArrayGetSize(pRes) == 0) {
|
||||
vDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d skip log %ld since not wanted", consumerId,
|
||||
tqDebug("tmq poll: consumer %ld (epoch %d) iter log, vg %d skip log %ld since not wanted", consumerId,
|
||||
pReq->epoch, TD_VID(pTq->pVnode), fetchOffset);
|
||||
fetchOffset++;
|
||||
rspV2.skipLogNum++;
|
||||
|
@ -770,7 +741,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
pMsg->pCont = buf;
|
||||
pMsg->contLen = msgLen;
|
||||
pMsg->code = 0;
|
||||
vDebug("vg %d offset %ld msgType %d from consumer %ld (epoch %d) actual rsp", TD_VID(pTq->pVnode), fetchOffset,
|
||||
tqDebug("vg %d offset %ld msgType %d from consumer %ld (epoch %d) actual rsp", TD_VID(pTq->pVnode), fetchOffset,
|
||||
pHead->msgType, consumerId, pReq->epoch);
|
||||
tmsgSendRsp(pMsg);
|
||||
taosMemoryFree(pHead);
|
||||
|
@ -804,7 +775,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) {
|
|||
pMsg->contLen = tlen;
|
||||
pMsg->code = 0;
|
||||
tmsgSendRsp(pMsg);
|
||||
vDebug("vg %d offset %ld from consumer %ld (epoch %d) not rsp", TD_VID(pTq->pVnode), fetchOffset, consumerId,
|
||||
tqDebug("vg %d offset %ld from consumer %ld (epoch %d) not rsp", TD_VID(pTq->pVnode), fetchOffset, consumerId,
|
||||
pReq->epoch);
|
||||
/*}*/
|
||||
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tq.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "vnodeInt.h"
|
||||
#include "tq.h"
|
||||
// #include <fcntl.h>
|
||||
// #include <string.h>
|
||||
// #include <unistd.h>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tq.h"
|
||||
|
||||
enum ETqOffsetPersist {
|
||||
TQ_OFFSET_PERSIST__LAZY = 1,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tq.h"
|
||||
|
||||
STqReadHandle* tqInitSubmitMsgScanner(SMeta* pMeta) {
|
||||
STqReadHandle* pReadHandle = taosMemoryMalloc(sizeof(STqReadHandle));
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
#define TSDB_MAX_SUBBLOCKS 8
|
||||
|
||||
|
@ -752,334 +752,7 @@ int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// // =================== Commit Meta Data
|
||||
// static int tsdbInitCommitMetaFile(STsdbRepo *pRepo, SMFile* pMf, bool open) {
|
||||
// STsdbFS * pfs = REPO_FS(pRepo);
|
||||
// SMFile * pOMFile = pfs->cstatus->pmf;
|
||||
// SDiskID did;
|
||||
|
||||
// // Create/Open a meta file or open the existing file
|
||||
// if (pOMFile == NULL) {
|
||||
// // Create a new meta file
|
||||
// did.level = TFS_PRIMARY_LEVEL;
|
||||
// did.id = TFS_PRIMARY_ID;
|
||||
// tsdbInitMFile(pMf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo)));
|
||||
|
||||
// if (open && tsdbCreateMFile(pMf, true) < 0) {
|
||||
// tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// tsdbInfo("vgId:%d meta file %s is created to commit", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMf));
|
||||
// } else {
|
||||
// tsdbInitMFileEx(pMf, pOMFile);
|
||||
// if (open && tsdbOpenMFile(pMf, O_WRONLY) < 0) {
|
||||
// tsdbError("vgId:%d failed to open META file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int tsdbCommitMeta(STsdbRepo *pRepo) {
|
||||
// STsdbFS * pfs = REPO_FS(pRepo);
|
||||
// SMemTable *pMem = pRepo->imem;
|
||||
// SMFile * pOMFile = pfs->cstatus->pmf;
|
||||
// SMFile mf;
|
||||
// SActObj * pAct = NULL;
|
||||
// SActCont * pCont = NULL;
|
||||
// SListNode *pNode = NULL;
|
||||
|
||||
// ASSERT(pOMFile != NULL || listNEles(pMem->actList) > 0);
|
||||
|
||||
// if (listNEles(pMem->actList) <= 0) {
|
||||
// // no meta data to commit, just keep the old meta file
|
||||
// tsdbUpdateMFile(pfs, pOMFile);
|
||||
// if (tsTsdbMetaCompactRatio > 0) {
|
||||
// if (tsdbInitCommitMetaFile(pRepo, &mf, false) < 0) {
|
||||
// return -1;
|
||||
// }
|
||||
// int ret = tsdbCompactMetaFile(pRepo, pfs, &mf);
|
||||
// if (ret < 0) tsdbError("compact meta file error");
|
||||
|
||||
// return ret;
|
||||
// }
|
||||
// return 0;
|
||||
// } else {
|
||||
// if (tsdbInitCommitMetaFile(pRepo, &mf, true) < 0) {
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Loop to write
|
||||
// while ((pNode = tdListPopHead(pMem->actList)) != NULL) {
|
||||
// pAct = (SActObj *)pNode->data;
|
||||
// if (pAct->act == TSDB_UPDATE_META) {
|
||||
// pCont = (SActCont *)POINTER_SHIFT(pAct, sizeof(SActObj));
|
||||
// if (tsdbUpdateMetaRecord(pfs, &mf, pAct->uid, (void *)(pCont->cont), pCont->len, false) < 0) {
|
||||
// tsdbError("vgId:%d failed to update META record, uid %" PRIu64 " since %s", REPO_ID(pRepo), pAct->uid,
|
||||
// tstrerror(terrno));
|
||||
// tsdbCloseMFile(&mf);
|
||||
// (void)tsdbApplyMFileChange(&mf, pOMFile);
|
||||
// // TODO: need to reload metaCache
|
||||
// return -1;
|
||||
// }
|
||||
// } else if (pAct->act == TSDB_DROP_META) {
|
||||
// if (tsdbDropMetaRecord(pfs, &mf, pAct->uid) < 0) {
|
||||
// tsdbError("vgId:%d failed to drop META record, uid %" PRIu64 " since %s", REPO_ID(pRepo), pAct->uid,
|
||||
// tstrerror(terrno));
|
||||
// tsdbCloseMFile(&mf);
|
||||
// tsdbApplyMFileChange(&mf, pOMFile);
|
||||
// // TODO: need to reload metaCache
|
||||
// return -1;
|
||||
// }
|
||||
// } else {
|
||||
// ASSERT(false);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (tsdbUpdateMFileHeader(&mf) < 0) {
|
||||
// tsdbError("vgId:%d failed to update META file header since %s, revert it", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// tsdbApplyMFileChange(&mf, pOMFile);
|
||||
// // TODO: need to reload metaCache
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// TSDB_FILE_FSYNC(&mf);
|
||||
// tsdbCloseMFile(&mf);
|
||||
// tsdbUpdateMFile(pfs, &mf);
|
||||
|
||||
// if (tsTsdbMetaCompactRatio > 0 && tsdbCompactMetaFile(pRepo, pfs, &mf) < 0) {
|
||||
// tsdbError("compact meta file error");
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord) {
|
||||
// int tlen = 0;
|
||||
// tlen += taosEncodeFixedU64(buf, pRecord->uid);
|
||||
// tlen += taosEncodeFixedI64(buf, pRecord->offset);
|
||||
// tlen += taosEncodeFixedI64(buf, pRecord->size);
|
||||
|
||||
// return tlen;
|
||||
// }
|
||||
|
||||
// void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord) {
|
||||
// buf = taosDecodeFixedU64(buf, &(pRecord->uid));
|
||||
// buf = taosDecodeFixedI64(buf, &(pRecord->offset));
|
||||
// buf = taosDecodeFixedI64(buf, &(pRecord->size));
|
||||
|
||||
// return buf;
|
||||
// }
|
||||
|
||||
// static int tsdbUpdateMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid, void *cont, int contLen, bool compact) {
|
||||
// char buf[64] = "\0";
|
||||
// void * pBuf = buf;
|
||||
// SKVRecord rInfo;
|
||||
// int64_t offset;
|
||||
|
||||
// // Seek to end of meta file
|
||||
// offset = tsdbSeekMFile(pMFile, 0, SEEK_END);
|
||||
// if (offset < 0) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// rInfo.offset = offset;
|
||||
// rInfo.uid = uid;
|
||||
// rInfo.size = contLen;
|
||||
|
||||
// int tlen = tsdbEncodeKVRecord((void **)(&pBuf), &rInfo);
|
||||
// if (tsdbAppendMFile(pMFile, buf, tlen, NULL) < tlen) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsdbAppendMFile(pMFile, cont, contLen, NULL) < contLen) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// tsdbUpdateMFileMagic(pMFile, POINTER_SHIFT(cont, contLen - sizeof(TSCKSUM)));
|
||||
|
||||
// SHashObj* cache = compact ? pfs->metaCacheComp : pfs->metaCache;
|
||||
|
||||
// pMFile->info.nRecords++;
|
||||
|
||||
// SKVRecord *pRecord = taosHashGet(cache, (void *)&uid, sizeof(uid));
|
||||
// if (pRecord != NULL) {
|
||||
// pMFile->info.tombSize += (pRecord->size + sizeof(SKVRecord));
|
||||
// } else {
|
||||
// pMFile->info.nRecords++;
|
||||
// }
|
||||
// taosHashPut(cache, (void *)(&uid), sizeof(uid), (void *)(&rInfo), sizeof(rInfo));
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int tsdbDropMetaRecord(STsdbFS *pfs, SMFile *pMFile, uint64_t uid) {
|
||||
// SKVRecord rInfo = {0};
|
||||
// char buf[128] = "\0";
|
||||
|
||||
// SKVRecord *pRecord = taosHashGet(pfs->metaCache, (void *)(&uid), sizeof(uid));
|
||||
// if (pRecord == NULL) {
|
||||
// tsdbError("failed to drop META record with key %" PRIu64 " since not find", uid);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// rInfo.offset = -pRecord->offset;
|
||||
// rInfo.uid = pRecord->uid;
|
||||
// rInfo.size = pRecord->size;
|
||||
|
||||
// void *pBuf = buf;
|
||||
// tsdbEncodeKVRecord(&pBuf, &rInfo);
|
||||
|
||||
// if (tsdbAppendMFile(pMFile, buf, sizeof(SKVRecord), NULL) < 0) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// pMFile->info.magic = taosCalcChecksum(pMFile->info.magic, (uint8_t *)buf, sizeof(SKVRecord));
|
||||
// pMFile->info.nDels++;
|
||||
// pMFile->info.nRecords--;
|
||||
// pMFile->info.tombSize += (rInfo.size + sizeof(SKVRecord) * 2);
|
||||
|
||||
// taosHashRemove(pfs->metaCache, (void *)(&uid), sizeof(uid));
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int tsdbCompactMetaFile(STsdbRepo *pRepo, STsdbFS *pfs, SMFile *pMFile) {
|
||||
// float delPercent = (float)(pMFile->info.nDels) / (float)(pMFile->info.nRecords);
|
||||
// float tombPercent = (float)(pMFile->info.tombSize) / (float)(pMFile->info.size);
|
||||
// float compactRatio = (float)(tsTsdbMetaCompactRatio)/100;
|
||||
|
||||
// if (delPercent < compactRatio && tombPercent < compactRatio) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// if (tsdbOpenMFile(pMFile, O_RDONLY) < 0) {
|
||||
// tsdbError("open meta file %s compact fail", pMFile->f.rname);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// tsdbInfo("begin compact tsdb meta file, ratio:%d, nDels:%" PRId64 ",nRecords:%" PRId64 ",tombSize:%" PRId64
|
||||
// ",size:%" PRId64,
|
||||
// tsTsdbMetaCompactRatio, pMFile->info.nDels,pMFile->info.nRecords,pMFile->info.tombSize,pMFile->info.size);
|
||||
|
||||
// SMFile mf;
|
||||
// SDiskID did;
|
||||
|
||||
// // first create tmp meta file
|
||||
// did.level = TFS_PRIMARY_LEVEL;
|
||||
// did.id = TFS_PRIMARY_ID;
|
||||
// tsdbInitMFile(&mf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo)) + 1);
|
||||
|
||||
// if (tsdbCreateMFile(&mf, true) < 0) {
|
||||
// tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// tsdbInfo("vgId:%d meta file %s is created to compact meta data", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf));
|
||||
|
||||
// // second iterator metaCache
|
||||
// int code = -1;
|
||||
// int64_t maxBufSize = 1024;
|
||||
// SKVRecord *pRecord;
|
||||
// void *pBuf = NULL;
|
||||
|
||||
// pBuf = taosMemoryMalloc((size_t)maxBufSize);
|
||||
// if (pBuf == NULL) {
|
||||
// goto _err;
|
||||
// }
|
||||
|
||||
// // init Comp
|
||||
// assert(pfs->metaCacheComp == NULL);
|
||||
// pfs->metaCacheComp = taosHashInit(4096, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
|
||||
// if (pfs->metaCacheComp == NULL) {
|
||||
// goto _err;
|
||||
// }
|
||||
|
||||
// pRecord = taosHashIterate(pfs->metaCache, NULL);
|
||||
// while (pRecord) {
|
||||
// if (tsdbSeekMFile(pMFile, pRecord->offset + sizeof(SKVRecord), SEEK_SET) < 0) {
|
||||
// tsdbError("vgId:%d failed to seek file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
// tstrerror(terrno));
|
||||
// goto _err;
|
||||
// }
|
||||
// if (pRecord->size > maxBufSize) {
|
||||
// maxBufSize = pRecord->size;
|
||||
// void* tmp = taosMemoryRealloc(pBuf, (size_t)maxBufSize);
|
||||
// if (tmp == NULL) {
|
||||
// goto _err;
|
||||
// }
|
||||
// pBuf = tmp;
|
||||
// }
|
||||
// int nread = (int)tsdbReadMFile(pMFile, pBuf, pRecord->size);
|
||||
// if (nread < 0) {
|
||||
// tsdbError("vgId:%d failed to read file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
// tstrerror(terrno));
|
||||
// goto _err;
|
||||
// }
|
||||
|
||||
// if (nread < pRecord->size) {
|
||||
// tsdbError("vgId:%d failed to read file %s since file corrupted, expected read:%" PRId64 " actual read:%d",
|
||||
// REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile), pRecord->size, nread);
|
||||
// goto _err;
|
||||
// }
|
||||
|
||||
// if (tsdbUpdateMetaRecord(pfs, &mf, pRecord->uid, pBuf, (int)pRecord->size, true) < 0) {
|
||||
// tsdbError("vgId:%d failed to update META record, uid %" PRIu64 " since %s", REPO_ID(pRepo), pRecord->uid,
|
||||
// tstrerror(terrno));
|
||||
// goto _err;
|
||||
// }
|
||||
|
||||
// pRecord = taosHashIterate(pfs->metaCache, pRecord);
|
||||
// }
|
||||
// code = 0;
|
||||
|
||||
// _err:
|
||||
// if (code == 0) TSDB_FILE_FSYNC(&mf);
|
||||
// tsdbCloseMFile(&mf);
|
||||
// tsdbCloseMFile(pMFile);
|
||||
|
||||
// if (code == 0) {
|
||||
// // rename meta.tmp -> meta
|
||||
// tsdbInfo("vgId:%d meta file rename %s -> %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf),
|
||||
// TSDB_FILE_FULL_NAME(pMFile)); taosRename(mf.f.aname,pMFile->f.aname); tstrncpy(mf.f.aname, pMFile->f.aname,
|
||||
// TSDB_FILENAME_LEN); tstrncpy(mf.f.rname, pMFile->f.rname, TSDB_FILENAME_LEN);
|
||||
// // update current meta file info
|
||||
// pfs->nstatus->pmf = NULL;
|
||||
// tsdbUpdateMFile(pfs, &mf);
|
||||
|
||||
// taosHashCleanup(pfs->metaCache);
|
||||
// pfs->metaCache = pfs->metaCacheComp;
|
||||
// pfs->metaCacheComp = NULL;
|
||||
// } else {
|
||||
// // remove meta.tmp file
|
||||
// taosRemoveFile(mf.f.aname);
|
||||
// taosHashCleanup(pfs->metaCacheComp);
|
||||
// pfs->metaCacheComp = NULL;
|
||||
// }
|
||||
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
|
||||
// ASSERT(mf.info.nDels == 0);
|
||||
// ASSERT(mf.info.tombSize == 0);
|
||||
|
||||
// tsdbInfo("end compact tsdb meta file,code:%d,nRecords:%" PRId64 ",size:%" PRId64,
|
||||
// code,mf.info.nRecords,mf.info.size);
|
||||
// return code;
|
||||
// }
|
||||
|
||||
// // =================== Commit Time-Series Data
|
||||
// #if 0
|
||||
// static bool tsdbHasDataToCommit(SCommitIter *iters, int nIters, TSKEY minKey, TSKEY maxKey) {
|
||||
// for (int i = 0; i < nIters; i++) {
|
||||
// TSKEY nextKey = tsdbNextIterKey((iters + i)->pIter);
|
||||
// if (nextKey != TSDB_DATA_TIMESTAMP_NULL && (nextKey >= minKey && nextKey <= maxKey)) return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// =================== Commit Time-Series Data
|
||||
static int tsdbCommitToTable(SCommitH *pCommith, int tid) {
|
||||
SCommitIter *pIter = pCommith->iters + tid;
|
||||
TSKEY nextKey = tsdbNextIterKey(pIter->pIter);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
int tsdbBegin(STsdb *pTsdb) {
|
||||
STsdbMemTable *pMem;
|
||||
|
|
|
@ -1,534 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#if 0
|
||||
#include "tsdbint.h"
|
||||
|
||||
typedef struct {
|
||||
STable * pTable;
|
||||
SBlockIdx * pBlkIdx;
|
||||
SBlockIdx bindex;
|
||||
SBlockInfo *pInfo;
|
||||
} STableCompactH;
|
||||
|
||||
typedef struct {
|
||||
SRtn rtn;
|
||||
SFSIter fsIter;
|
||||
SArray * tbArray; // table array to cache table obj and block indexes
|
||||
SReadH readh;
|
||||
SDFileSet wSet;
|
||||
SArray * aBlkIdx;
|
||||
SArray * aSupBlk;
|
||||
SDataCols *pDataCols;
|
||||
} SCompactH;
|
||||
|
||||
#define TSDB_COMPACT_WSET(pComph) (&((pComph)->wSet))
|
||||
#define TSDB_COMPACT_REPO(pComph) TSDB_READ_REPO(&((pComph)->readh))
|
||||
#define TSDB_COMPACT_HEAD_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_HEAD)
|
||||
#define TSDB_COMPACT_DATA_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_DATA)
|
||||
#define TSDB_COMPACT_LAST_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_LAST)
|
||||
#define TSDB_COMPACT_SMAD_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_SMAD)
|
||||
#define TSDB_COMPACT_SMAL_FILE(pComph) TSDB_DFILE_IN_SET(TSDB_COMPACT_WSET(pComph), TSDB_FILE_SMAL)
|
||||
#define TSDB_COMPACT_BUF(pComph) TSDB_READ_BUF(&((pComph)->readh))
|
||||
#define TSDB_COMPACT_COMP_BUF(pComph) TSDB_READ_COMP_BUF(&((pComph)->readh))
|
||||
|
||||
static int tsdbAsyncCompact(STsdbRepo *pRepo);
|
||||
static void tsdbStartCompact(STsdbRepo *pRepo);
|
||||
static void tsdbEndCompact(STsdbRepo *pRepo, int eno);
|
||||
static int tsdbCompactMeta(STsdbRepo *pRepo);
|
||||
static int tsdbCompactTSData(STsdbRepo *pRepo);
|
||||
static int tsdbCompactFSet(SCompactH *pComph, SDFileSet *pSet);
|
||||
static bool tsdbShouldCompact(SCompactH *pComph);
|
||||
static int tsdbInitCompactH(SCompactH *pComph, STsdbRepo *pRepo);
|
||||
static void tsdbDestroyCompactH(SCompactH *pComph);
|
||||
static int tsdbInitCompTbArray(SCompactH *pComph);
|
||||
static void tsdbDestroyCompTbArray(SCompactH *pComph);
|
||||
static int tsdbCacheFSetIndex(SCompactH *pComph);
|
||||
static int tsdbCompactFSetInit(SCompactH *pComph, SDFileSet *pSet);
|
||||
static void tsdbCompactFSetEnd(SCompactH *pComph);
|
||||
static int tsdbCompactFSetImpl(SCompactH *pComph);
|
||||
static int tsdbWriteBlockToRightFile(SCompactH *pComph, STable *pTable, SDataCols *pDataCols, void **ppBuf,
|
||||
void **ppCBuf);
|
||||
|
||||
enum { TSDB_NO_COMPACT, TSDB_IN_COMPACT, TSDB_WAITING_COMPACT};
|
||||
int tsdbCompact(STsdbRepo *pRepo) { return tsdbAsyncCompact(pRepo); }
|
||||
|
||||
void *tsdbCompactImpl(STsdbRepo *pRepo) {
|
||||
// Check if there are files in TSDB FS to compact
|
||||
if (REPO_FS(pRepo)->cstatus->pmf == NULL) {
|
||||
tsdbInfo("vgId:%d no file to compact in FS", REPO_ID(pRepo));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tsdbStartCompact(pRepo);
|
||||
|
||||
if (tsdbCompactMeta(pRepo) < 0) {
|
||||
tsdbError("vgId:%d failed to compact META data since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (tsdbCompactTSData(pRepo) < 0) {
|
||||
tsdbError("vgId:%d failed to compact TS data since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
tsdbEndCompact(pRepo, TSDB_CODE_SUCCESS);
|
||||
return NULL;
|
||||
|
||||
_err:
|
||||
pRepo->code = terrno;
|
||||
tsdbEndCompact(pRepo, terrno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int tsdbAsyncCompact(STsdbRepo *pRepo) {
|
||||
if (pRepo->compactState != TSDB_NO_COMPACT) {
|
||||
tsdbInfo("vgId:%d not compact tsdb again ", REPO_ID(pRepo));
|
||||
return 0;
|
||||
}
|
||||
pRepo->compactState = TSDB_WAITING_COMPACT;
|
||||
tsem_wait(&(pRepo->readyToCommit));
|
||||
return tsdbScheduleCommit(pRepo, COMPACT_REQ);
|
||||
}
|
||||
|
||||
static void tsdbStartCompact(STsdbRepo *pRepo) {
|
||||
assert(pRepo->compactState != TSDB_IN_COMPACT);
|
||||
tsdbInfo("vgId:%d start to compact!", REPO_ID(pRepo));
|
||||
tsdbStartFSTxn(pRepo, 0, 0);
|
||||
pRepo->code = TSDB_CODE_SUCCESS;
|
||||
pRepo->compactState = TSDB_IN_COMPACT;
|
||||
}
|
||||
|
||||
static void tsdbEndCompact(STsdbRepo *pRepo, int eno) {
|
||||
if (eno != TSDB_CODE_SUCCESS) {
|
||||
tsdbEndFSTxnWithError(REPO_FS(pRepo));
|
||||
} else {
|
||||
tsdbEndFSTxn(pRepo);
|
||||
}
|
||||
pRepo->compactState = TSDB_NO_COMPACT;
|
||||
tsdbInfo("vgId:%d compact over, %s", REPO_ID(pRepo), (eno == TSDB_CODE_SUCCESS) ? "succeed" : "failed");
|
||||
tsem_post(&(pRepo->readyToCommit));
|
||||
}
|
||||
|
||||
static int tsdbCompactMeta(STsdbRepo *pRepo) {
|
||||
STsdbFS *pfs = REPO_FS(pRepo);
|
||||
tsdbUpdateMFile(pfs, pfs->cstatus->pmf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsdbCompactTSData(STsdbRepo *pRepo) {
|
||||
SCompactH compactH;
|
||||
SDFileSet *pSet = NULL;
|
||||
|
||||
tsdbDebug("vgId:%d start to compact TS data", REPO_ID(pRepo));
|
||||
|
||||
// If no file, just return 0;
|
||||
if (taosArrayGetSize(REPO_FS(pRepo)->cstatus->df) <= 0) {
|
||||
tsdbDebug("vgId:%d no TS data file to compact, compact over", REPO_ID(pRepo));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tsdbInitCompactH(&compactH, pRepo) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((pSet = tsdbFSIterNext(&(compactH.fsIter)))) {
|
||||
// Remove those expired files
|
||||
if (pSet->fid < compactH.rtn.minFid) {
|
||||
tsdbInfo("vgId:%d FSET %d on level %d disk id %d expires, remove it", REPO_ID(pRepo), pSet->fid,
|
||||
TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (TSDB_FSET_LEVEL(pSet) == TFS_MAX_LEVEL) {
|
||||
tsdbDebug("vgId:%d FSET %d on level %d, should not compact", REPO_ID(pRepo), pSet->fid, TFS_MAX_LEVEL);
|
||||
tsdbUpdateDFileSet(REPO_FS(pRepo), pSet);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tsdbCompactFSet(&compactH, pSet) < 0) {
|
||||
tsdbDestroyCompactH(&compactH);
|
||||
tsdbError("vgId:%d failed to compact FSET %d since %s", REPO_ID(pRepo), pSet->fid, tstrerror(terrno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tsdbDestroyCompactH(&compactH);
|
||||
tsdbDebug("vgId:%d compact TS data over", REPO_ID(pRepo));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsdbCompactFSet(SCompactH *pComph, SDFileSet *pSet) {
|
||||
STsdbRepo *pRepo = TSDB_COMPACT_REPO(pComph);
|
||||
SDiskID did;
|
||||
|
||||
tsdbDebug("vgId:%d start to compact FSET %d on level %d id %d", REPO_ID(pRepo), pSet->fid, TSDB_FSET_LEVEL(pSet),
|
||||
TSDB_FSET_ID(pSet));
|
||||
|
||||
if (tsdbCompactFSetInit(pComph, pSet) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!tsdbShouldCompact(pComph)) {
|
||||
tsdbDebug("vgId:%d no need to compact FSET %d", REPO_ID(pRepo), pSet->fid);
|
||||
if (tsdbApplyRtnOnFSet(TSDB_COMPACT_REPO(pComph), pSet, &(pComph->rtn)) < 0) {
|
||||
tsdbCompactFSetEnd(pComph);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// Create new fset as compacted fset
|
||||
if (tfsAllocDisk(pRepo->pTfs, tsdbGetFidLevel(pSet->fid, &(pComph->rtn)), &did) < 0) {
|
||||
terrno = TSDB_CODE_TDB_NO_AVAIL_DISK;
|
||||
tsdbError("vgId:%d failed to compact FSET %d since %s", REPO_ID(pRepo), pSet->fid, tstrerror(terrno));
|
||||
tsdbCompactFSetEnd(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbInitDFileSet(TSDB_COMPACT_WSET(pComph), did, REPO_ID(pRepo), TSDB_FSET_FID(pSet),
|
||||
FS_TXN_VERSION(REPO_FS(pRepo)));
|
||||
if (tsdbCreateDFileSet(TSDB_COMPACT_WSET(pComph), true) < 0) {
|
||||
tsdbError("vgId:%d failed to compact FSET %d since %s", REPO_ID(pRepo), pSet->fid, tstrerror(terrno));
|
||||
tsdbCompactFSetEnd(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbCompactFSetImpl(pComph) < 0) {
|
||||
tsdbCloseDFileSet(TSDB_COMPACT_WSET(pComph));
|
||||
tsdbRemoveDFileSet(TSDB_COMPACT_WSET(pComph));
|
||||
tsdbCompactFSetEnd(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbCloseDFileSet(TSDB_COMPACT_WSET(pComph));
|
||||
tsdbUpdateDFileSet(REPO_FS(pRepo), TSDB_COMPACT_WSET(pComph));
|
||||
tsdbDebug("vgId:%d FSET %d compact over", REPO_ID(pRepo), pSet->fid);
|
||||
}
|
||||
|
||||
tsdbCompactFSetEnd(pComph);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool tsdbShouldCompact(SCompactH *pComph) {
|
||||
STsdbRepo * pRepo = TSDB_COMPACT_REPO(pComph);
|
||||
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
||||
SReadH * pReadh = &(pComph->readh);
|
||||
STableCompactH *pTh;
|
||||
SBlock * pBlock;
|
||||
int defaultRows = TSDB_DEFAULT_BLOCK_ROWS(pCfg->maxRowsPerFileBlock);
|
||||
SDFile * pDataF = TSDB_READ_DATA_FILE(pReadh);
|
||||
SDFile * pLastF = TSDB_READ_LAST_FILE(pReadh);
|
||||
|
||||
int tblocks = 0; // total blocks
|
||||
int nSubBlocks = 0; // # of blocks with sub-blocks
|
||||
int nSmallBlocks = 0; // # of blocks with rows < defaultRows
|
||||
int64_t tsize = 0;
|
||||
|
||||
for (size_t i = 0; i < taosArrayGetSize(pComph->tbArray); i++) {
|
||||
pTh = (STableCompactH *)taosArrayGet(pComph->tbArray, i);
|
||||
|
||||
if (pTh->pTable == NULL || pTh->pBlkIdx == NULL) continue;
|
||||
|
||||
for (size_t bidx = 0; bidx < pTh->pBlkIdx->numOfBlocks; bidx++) {
|
||||
tblocks++;
|
||||
pBlock = pTh->pInfo->blocks + bidx;
|
||||
|
||||
if (pBlock->numOfRows < defaultRows) {
|
||||
nSmallBlocks++;
|
||||
}
|
||||
|
||||
if (pBlock->numOfSubBlocks > 1) {
|
||||
nSubBlocks++;
|
||||
for (int k = 0; k < pBlock->numOfSubBlocks; k++) {
|
||||
SBlock *iBlock = ((SBlock *)POINTER_SHIFT(pTh->pInfo, pBlock->offset)) + k;
|
||||
tsize = tsize + iBlock->len;
|
||||
}
|
||||
} else if (pBlock->numOfSubBlocks == 1) {
|
||||
tsize += pBlock->len;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (((nSubBlocks * 1.0 / tblocks) > 0.33) || ((nSmallBlocks * 1.0 / tblocks) > 0.33) ||
|
||||
(tsize * 1.0 / (pDataF->info.size + pLastF->info.size - 2 * TSDB_FILE_HEAD_SIZE) < 0.85));
|
||||
}
|
||||
|
||||
static int tsdbInitCompactH(SCompactH *pComph, STsdbRepo *pRepo) {
|
||||
STsdbCfg *pCfg = REPO_CFG(pRepo);
|
||||
|
||||
memset(pComph, 0, sizeof(*pComph));
|
||||
|
||||
TSDB_FSET_SET_CLOSED(TSDB_COMPACT_WSET(pComph));
|
||||
|
||||
tsdbGetRtnSnap(pRepo, &(pComph->rtn));
|
||||
tsdbFSIterInit(&(pComph->fsIter), REPO_FS(pRepo), TSDB_FS_ITER_FORWARD);
|
||||
|
||||
if (tsdbInitReadH(&(pComph->readh), pRepo) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbInitCompTbArray(pComph) < 0) {
|
||||
tsdbDestroyCompactH(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pComph->aBlkIdx = taosArrayInit(1024, sizeof(SBlockIdx));
|
||||
if (pComph->aBlkIdx == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
tsdbDestroyCompactH(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pComph->aSupBlk = taosArrayInit(1024, sizeof(SBlock));
|
||||
if (pComph->aSupBlk == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
tsdbDestroyCompactH(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pComph->pDataCols = tdNewDataCols(0, pCfg->maxRowsPerFileBlock);
|
||||
if (pComph->pDataCols == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
tsdbDestroyCompactH(pComph);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsdbDestroyCompactH(SCompactH *pComph) {
|
||||
pComph->pDataCols = tdFreeDataCols(pComph->pDataCols);
|
||||
pComph->aSupBlk = taosArrayDestroy(pComph->aSupBlk);
|
||||
pComph->aBlkIdx = taosArrayDestroy(pComph->aBlkIdx);
|
||||
tsdbDestroyCompTbArray(pComph);
|
||||
tsdbDestroyReadH(&(pComph->readh));
|
||||
tsdbCloseDFileSet(TSDB_COMPACT_WSET(pComph));
|
||||
}
|
||||
|
||||
static int tsdbInitCompTbArray(SCompactH *pComph) { // Init pComp->tbArray
|
||||
STsdbRepo *pRepo = TSDB_COMPACT_REPO(pComph);
|
||||
STsdbMeta *pMeta = pRepo->tsdbMeta;
|
||||
|
||||
if (tsdbRLockRepoMeta(pRepo) < 0) return -1;
|
||||
|
||||
pComph->tbArray = taosArrayInit(pMeta->maxTables, sizeof(STableCompactH));
|
||||
if (pComph->tbArray == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
tsdbUnlockRepoMeta(pRepo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Note here must start from 0
|
||||
for (int i = 0; i < pMeta->maxTables; i++) {
|
||||
STableCompactH ch = {0};
|
||||
if (pMeta->tables[i] != NULL) {
|
||||
tsdbRefTable(pMeta->tables[i]);
|
||||
ch.pTable = pMeta->tables[i];
|
||||
}
|
||||
|
||||
if (taosArrayPush(pComph->tbArray, &ch) == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
tsdbUnlockRepoMeta(pRepo);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsdbUnlockRepoMeta(pRepo) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsdbDestroyCompTbArray(SCompactH *pComph) {
|
||||
STableCompactH *pTh;
|
||||
|
||||
if (pComph->tbArray == NULL) return;
|
||||
|
||||
for (size_t i = 0; i < taosArrayGetSize(pComph->tbArray); i++) {
|
||||
pTh = (STableCompactH *)taosArrayGet(pComph->tbArray, i);
|
||||
if (pTh->pTable) {
|
||||
tsdbUnRefTable(pTh->pTable);
|
||||
}
|
||||
|
||||
pTh->pInfo = taosTZfree(pTh->pInfo);
|
||||
}
|
||||
|
||||
pComph->tbArray = taosArrayDestroy(pComph->tbArray);
|
||||
}
|
||||
|
||||
static int tsdbCacheFSetIndex(SCompactH *pComph) {
|
||||
SReadH *pReadH = &(pComph->readh);
|
||||
|
||||
if (tsdbLoadBlockIdx(pReadH) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int tid = 1; tid < taosArrayGetSize(pComph->tbArray); tid++) {
|
||||
STableCompactH *pTh = (STableCompactH *)taosArrayGet(pComph->tbArray, tid);
|
||||
pTh->pBlkIdx = NULL;
|
||||
|
||||
if (pTh->pTable == NULL) continue;
|
||||
if (tsdbSetReadTable(pReadH, pTh->pTable) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pReadH->pBlkIdx == NULL) continue;
|
||||
pTh->bindex = *(pReadH->pBlkIdx);
|
||||
pTh->pBlkIdx = &(pTh->bindex);
|
||||
|
||||
if (tsdbMakeRoom((void **)(&(pTh->pInfo)), pTh->pBlkIdx->len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbLoadBlockInfo(pReadH, (void *)(pTh->pInfo)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsdbCompactFSetInit(SCompactH *pComph, SDFileSet *pSet) {
|
||||
taosArrayClear(pComph->aBlkIdx);
|
||||
taosArrayClear(pComph->aSupBlk);
|
||||
|
||||
if (tsdbSetAndOpenReadFSet(&(pComph->readh), pSet) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbCacheFSetIndex(pComph) < 0) {
|
||||
tsdbCloseAndUnsetFSet(&(pComph->readh));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tsdbCompactFSetEnd(SCompactH *pComph) { tsdbCloseAndUnsetFSet(&(pComph->readh)); }
|
||||
|
||||
static int tsdbCompactFSetImpl(SCompactH *pComph) {
|
||||
STsdbRepo *pRepo = TSDB_COMPACT_REPO(pComph);
|
||||
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
||||
SReadH * pReadh = &(pComph->readh);
|
||||
SBlockIdx blkIdx;
|
||||
void ** ppBuf = &(TSDB_COMPACT_BUF(pComph));
|
||||
void ** ppCBuf = &(TSDB_COMPACT_COMP_BUF(pComph));
|
||||
int defaultRows = TSDB_DEFAULT_BLOCK_ROWS(pCfg->maxRowsPerFileBlock);
|
||||
|
||||
taosArrayClear(pComph->aBlkIdx);
|
||||
|
||||
for (int tid = 1; tid < taosArrayGetSize(pComph->tbArray); tid++) {
|
||||
STableCompactH *pTh = (STableCompactH *)taosArrayGet(pComph->tbArray, tid);
|
||||
STSchema * pSchema;
|
||||
|
||||
if (pTh->pTable == NULL || pTh->pBlkIdx == NULL) continue;
|
||||
|
||||
pSchema = tsdbGetTableSchemaImpl(pTh->pTable, true, true, -1);
|
||||
taosArrayClear(pComph->aSupBlk);
|
||||
if ((tdInitDataCols(pComph->pDataCols, pSchema) < 0) || (tdInitDataCols(pReadh->pDCols[0], pSchema) < 0) ||
|
||||
(tdInitDataCols(pReadh->pDCols[1], pSchema) < 0)) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
tdFreeSchema(pSchema);
|
||||
|
||||
// Loop to compact each block data
|
||||
for (int i = 0; i < pTh->pBlkIdx->numOfBlocks; i++) {
|
||||
SBlock *pBlock = pTh->pInfo->blocks + i;
|
||||
|
||||
// Load the block data
|
||||
if (tsdbLoadBlockData(pReadh, pBlock, pTh->pInfo) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Merge pComph->pDataCols and pReadh->pDCols[0] and write data to file
|
||||
if (pComph->pDataCols->numOfRows == 0 && pBlock->numOfRows >= defaultRows) {
|
||||
if (tsdbWriteBlockToRightFile(pComph, pTh->pTable, pReadh->pDCols[0], ppBuf, ppCBuf) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
int ridx = 0;
|
||||
|
||||
while (true) {
|
||||
if (pReadh->pDCols[0]->numOfRows - ridx == 0) break;
|
||||
int rowsToMerge = TMIN(pReadh->pDCols[0]->numOfRows - ridx, defaultRows - pComph->pDataCols->numOfRows);
|
||||
|
||||
tdMergeDataCols(pComph->pDataCols, pReadh->pDCols[0], rowsToMerge, &ridx, pCfg->update != TD_ROW_PARTIAL_UPDATE);
|
||||
|
||||
if (pComph->pDataCols->numOfRows < defaultRows) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (tsdbWriteBlockToRightFile(pComph, pTh->pTable, pComph->pDataCols, ppBuf, ppCBuf) < 0) {
|
||||
return -1;
|
||||
}
|
||||
tdResetDataCols(pComph->pDataCols);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pComph->pDataCols->numOfRows > 0 &&
|
||||
tsdbWriteBlockToRightFile(pComph, pTh->pTable, pComph->pDataCols, ppBuf, ppCBuf) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbWriteBlockInfoImpl(TSDB_COMPACT_HEAD_FILE(pComph), pTh->pTable, pComph->aSupBlk, NULL, ppBuf, &blkIdx) <
|
||||
0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((blkIdx.numOfBlocks > 0) && (taosArrayPush(pComph->aBlkIdx, (void *)(&blkIdx)) == NULL)) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tsdbWriteBlockIdx(TSDB_COMPACT_HEAD_FILE(pComph), pComph->aBlkIdx, ppBuf) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsdbWriteBlockToRightFile(SCompactH *pComph, STable *pTable, SDataCols *pDataCols, void **ppBuf,
|
||||
void **ppCBuf) {
|
||||
STsdbRepo *pRepo = TSDB_COMPACT_REPO(pComph);
|
||||
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
||||
SDFile * pDFile;
|
||||
bool isLast;
|
||||
SBlock block;
|
||||
|
||||
ASSERT(pDataCols->numOfRows > 0);
|
||||
|
||||
if (pDataCols->numOfRows < pCfg->minRowsPerFileBlock) {
|
||||
pDFile = TSDB_COMPACT_LAST_FILE(pComph);
|
||||
isLast = true;
|
||||
} else {
|
||||
pDFile = TSDB_COMPACT_DATA_FILE(pComph);
|
||||
isLast = false;
|
||||
}
|
||||
|
||||
if (tsdbWriteBlockImpl(pRepo, pTable, pDFile, pDataCols, &block, isLast, true, ppBuf, ppCBuf) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosArrayPush(pComph->aSupBlk, (void *)(&block)) == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef enum { TSDB_TXN_TEMP_FILE = 0, TSDB_TXN_CURR_FILE } TSDB_TXN_FILE_T;
|
||||
static const char *tsdbTxnFname[] = {"current.t", "current"};
|
||||
|
@ -246,62 +246,6 @@ void *tsdbFreeFS(STsdbFS *pfs) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// static int tsdbProcessExpiredFS(STsdb *pRepo) {
|
||||
// tsdbStartFSTxn(pRepo, 0, 0);
|
||||
// // if (tsdbCreateMeta(pRepo) < 0) {
|
||||
// // tsdbError("vgId:%d failed to create meta since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// // return -1;
|
||||
// // }
|
||||
|
||||
// if (tsdbApplyRtn(pRepo) < 0) {
|
||||
// tsdbEndFSTxnWithError(REPO_FS(pRepo));
|
||||
// tsdbError("vgId:%d failed to apply rtn since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
// if (tsdbEndFSTxn(pRepo) < 0) {
|
||||
// tsdbError("vgId:%d failed to end fs txn since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// static int tsdbCreateMeta(STsdb *pRepo) {
|
||||
// STsdbFS *pfs = REPO_FS(pRepo);
|
||||
// SMFile * pOMFile = pfs->cstatus->pmf;
|
||||
// SMFile mf;
|
||||
// SDiskID did;
|
||||
|
||||
// if (pOMFile != NULL) {
|
||||
// // keep the old meta file
|
||||
// tsdbUpdateMFile(pfs, pOMFile);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// // Create a new meta file
|
||||
// did.level = TFS_PRIMARY_LEVEL;
|
||||
// did.id = TFS_PRIMARY_ID;
|
||||
// tsdbInitMFile(&mf, did, REPO_ID(pRepo), FS_TXN_VERSION(REPO_FS(pRepo)));
|
||||
|
||||
// if (tsdbCreateMFile(&mf, true) < 0) {
|
||||
// tsdbError("vgId:%d failed to create META file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// tsdbInfo("vgId:%d meta file %s is created", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(&mf));
|
||||
|
||||
// if (tsdbUpdateMFileHeader(&mf) < 0) {
|
||||
// tsdbError("vgId:%d failed to update META file header since %s, revert it", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// tsdbApplyMFileChange(&mf, pOMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// TSDB_FILE_FSYNC(&mf);
|
||||
// tsdbCloseMFile(&mf);
|
||||
// tsdbUpdateMFile(pfs, &mf);
|
||||
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
int tsdbOpenFS(STsdb *pRepo) {
|
||||
STsdbFS *pfs = REPO_FS(pRepo);
|
||||
char current[TSDB_FILENAME_LEN] = "\0";
|
||||
|
@ -644,7 +588,7 @@ static int tsdbComparFidFSet(const void *arg1, const void *arg2) {
|
|||
}
|
||||
|
||||
static void tsdbGetTxnFname(STsdb *pRepo, TSDB_TXN_FILE_T ftype, char fname[]) {
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "%s/vnode/vnode%d/tsdb/%s", tfsGetPrimaryPath(REPO_TFS(pRepo)), pRepo->vgId,
|
||||
snprintf(fname, TSDB_FILENAME_LEN, "%s/vnode/vnode%d/tsdb/%s", tfsGetPrimaryPath(REPO_TFS(pRepo)), REPO_ID(pRepo),
|
||||
tsdbTxnFname[ftype]);
|
||||
}
|
||||
|
||||
|
@ -769,142 +713,6 @@ static int tsdbScanAndTryFixFS(STsdb *pRepo) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// int tsdbLoadMetaCache(STsdb *pRepo, bool recoverMeta) {
|
||||
// char tbuf[128];
|
||||
// STsdbFS * pfs = REPO_FS(pRepo);
|
||||
// SMFile mf;
|
||||
// SMFile * pMFile = &mf;
|
||||
// void * pBuf = NULL;
|
||||
// SKVRecord rInfo;
|
||||
// int64_t maxBufSize = 0;
|
||||
// SMFInfo minfo;
|
||||
|
||||
// taosHashClear(pfs->metaCache);
|
||||
|
||||
// // No meta file, just return
|
||||
// if (pfs->cstatus->pmf == NULL) return 0;
|
||||
|
||||
// mf = pfs->cstatus->mf;
|
||||
// // Load cache first
|
||||
// if (tsdbOpenMFile(pMFile, O_RDONLY) < 0) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsdbLoadMFileHeader(pMFile, &minfo) < 0) {
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// while (true) {
|
||||
// int64_t tsize = tsdbReadMFile(pMFile, tbuf, sizeof(SKVRecord));
|
||||
// if (tsize == 0) break;
|
||||
|
||||
// if (tsize < 0) {
|
||||
// tsdbError("vgId:%d failed to read META file since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsize < sizeof(SKVRecord)) {
|
||||
// tsdbError("vgId:%d failed to read %" PRIzu " bytes from file %s", REPO_ID(pRepo), sizeof(SKVRecord),
|
||||
// TSDB_FILE_FULL_NAME(pMFile));
|
||||
// terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// void *ptr = tsdbDecodeKVRecord(tbuf, &rInfo);
|
||||
// ASSERT(POINTER_DISTANCE(ptr, tbuf) == sizeof(SKVRecord));
|
||||
// // ASSERT((rInfo.offset > 0) ? (pStore->info.size == rInfo.offset) : true);
|
||||
|
||||
// if (rInfo.offset < 0) {
|
||||
// taosHashRemove(pfs->metaCache, (void *)(&rInfo.uid), sizeof(rInfo.uid));
|
||||
// #if 0
|
||||
// pStore->info.size += sizeof(SKVRecord);
|
||||
// pStore->info.nRecords--;
|
||||
// pStore->info.nDels++;
|
||||
// pStore->info.tombSize += (rInfo.size + sizeof(SKVRecord) * 2);
|
||||
// #endif
|
||||
// } else {
|
||||
// ASSERT(rInfo.offset > 0 && rInfo.size > 0);
|
||||
// if (taosHashPut(pfs->metaCache, (void *)(&rInfo.uid), sizeof(rInfo.uid), &rInfo, sizeof(rInfo)) < 0) {
|
||||
// tsdbError("vgId:%d failed to load meta cache from file %s since OOM", REPO_ID(pRepo),
|
||||
// TSDB_FILE_FULL_NAME(pMFile));
|
||||
// terrno = TSDB_CODE_COM_OUT_OF_MEMORY;
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// maxBufSize = TMAX(maxBufSize, rInfo.size);
|
||||
|
||||
// if (tsdbSeekMFile(pMFile, rInfo.size, SEEK_CUR) < 0) {
|
||||
// tsdbError("vgId:%d failed to lseek file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
// tstrerror(terrno));
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// #if 0
|
||||
// pStore->info.size += (sizeof(SKVRecord) + rInfo.size);
|
||||
// pStore->info.nRecords++;
|
||||
// #endif
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (recoverMeta) {
|
||||
// pBuf = taosMemoryMalloc((size_t)maxBufSize);
|
||||
// if (pBuf == NULL) {
|
||||
// terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// SKVRecord *pRecord = taosHashIterate(pfs->metaCache, NULL);
|
||||
// while (pRecord) {
|
||||
// if (tsdbSeekMFile(pMFile, pRecord->offset + sizeof(SKVRecord), SEEK_SET) < 0) {
|
||||
// tsdbError("vgId:%d failed to seek file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
// tstrerror(terrno));
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// int nread = (int)tsdbReadMFile(pMFile, pBuf, pRecord->size);
|
||||
// if (nread < 0) {
|
||||
// tsdbError("vgId:%d failed to read file %s since %s", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
// tstrerror(terrno));
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (nread < pRecord->size) {
|
||||
// tsdbError("vgId:%d failed to read file %s since file corrupted, expected read:%" PRId64 " actual read:%d",
|
||||
// REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile), pRecord->size, nread);
|
||||
// terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsdbRestoreTable(pRepo, pBuf, (int)pRecord->size) < 0) {
|
||||
// tsdbError("vgId:%d failed to restore table, uid %" PRId64 ", since %s" PRIu64, REPO_ID(pRepo), pRecord->uid,
|
||||
// tstrerror(terrno));
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// pRecord = taosHashIterate(pfs->metaCache, pRecord);
|
||||
// }
|
||||
|
||||
// tsdbOrgMeta(pRepo);
|
||||
// }
|
||||
|
||||
// tsdbCloseMFile(pMFile);
|
||||
// taosMemoryFreeClear(pBuf);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
static int tsdbScanRootDir(STsdb *pRepo) {
|
||||
char rootDir[TSDB_FILENAME_LEN];
|
||||
char bname[TSDB_FILENAME_LEN];
|
||||
|
@ -983,127 +791,6 @@ static bool tsdbIsTFileInFS(STsdbFS *pfs, const STfsFile *pf) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// static int tsdbRestoreMeta(STsdb *pRepo) {
|
||||
// char rootDir[TSDB_FILENAME_LEN];
|
||||
// char bname[TSDB_FILENAME_LEN];
|
||||
// STfsDir * tdir = NULL;
|
||||
// const STfsFile *pf = NULL;
|
||||
// const char * pattern = "^meta(-ver[0-9]+)?$";
|
||||
// regex_t regex;
|
||||
// STsdbFS * pfs = REPO_FS(pRepo);
|
||||
|
||||
// regcomp(®ex, pattern, REG_EXTENDED);
|
||||
|
||||
// tsdbInfo("vgId:%d try to restore meta", REPO_ID(pRepo));
|
||||
|
||||
// tsdbGetRootDir(REPO_ID(pRepo), rootDir);
|
||||
|
||||
// tdir = tfsOpendir(rootDir);
|
||||
// if (tdir == NULL) {
|
||||
// tsdbError("vgId:%d failed to open dir %s since %s", REPO_ID(pRepo), rootDir, tstrerror(terrno));
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// while ((pf = tfsReaddir(tdir))) {
|
||||
// tfsBasename(pf, bname);
|
||||
|
||||
// if (strcmp(bname, "data") == 0) {
|
||||
// // Skip the data/ directory
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// if (strcmp(bname, tsdbTxnFname[TSDB_TXN_TEMP_FILE]) == 0) {
|
||||
// // Skip current.t file
|
||||
// tsdbInfo("vgId:%d file %s exists, remove it", REPO_ID(pRepo), pf->aname);
|
||||
// (void)tfsremove(pf);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// int code = regexec(®ex, bname, 0, NULL, 0);
|
||||
// if (code == 0) {
|
||||
// // Match
|
||||
// if (pfs->cstatus->pmf != NULL) {
|
||||
// tsdbError("vgId:%d failed to restore meta since two file exists, file1 %s and file2 %s", REPO_ID(pRepo),
|
||||
// TSDB_FILE_FULL_NAME(pfs->cstatus->pmf), pf->aname);
|
||||
// terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// } else {
|
||||
// uint32_t _version = 0;
|
||||
// if (strcmp(bname, "meta") != 0) {
|
||||
// sscanf(bname, "meta-ver%" PRIu32, &_version);
|
||||
// pfs->cstatus->meta.version = _version;
|
||||
// }
|
||||
|
||||
// pfs->cstatus->pmf = &(pfs->cstatus->mf);
|
||||
// pfs->cstatus->pmf->f = *pf;
|
||||
// TSDB_FILE_SET_CLOSED(pfs->cstatus->pmf);
|
||||
|
||||
// if (tsdbOpenMFile(pfs->cstatus->pmf, O_RDONLY) < 0) {
|
||||
// tsdbError("vgId:%d failed to restore meta since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsdbLoadMFileHeader(pfs->cstatus->pmf, &(pfs->cstatus->pmf->info)) < 0) {
|
||||
// tsdbError("vgId:%d failed to restore meta since %s", REPO_ID(pRepo), tstrerror(terrno));
|
||||
// tsdbCloseMFile(pfs->cstatus->pmf);
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (tsdbForceKeepFile) {
|
||||
// struct stat tfstat;
|
||||
|
||||
// // Get real file size
|
||||
// if (fstat(pfs->cstatus->pmf->fd, &tfstat) < 0) {
|
||||
// terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
// tsdbCloseMFile(pfs->cstatus->pmf);
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
// if (pfs->cstatus->pmf->info.size != tfstat.st_size) {
|
||||
// int64_t tfsize = pfs->cstatus->pmf->info.size;
|
||||
// pfs->cstatus->pmf->info.size = tfstat.st_size;
|
||||
// tsdbInfo("vgId:%d file %s header size is changed from %" PRId64 " to %" PRId64, REPO_ID(pRepo),
|
||||
// TSDB_FILE_FULL_NAME(pfs->cstatus->pmf), tfsize, pfs->cstatus->pmf->info.size);
|
||||
// }
|
||||
// }
|
||||
|
||||
// tsdbCloseMFile(pfs->cstatus->pmf);
|
||||
// }
|
||||
// } else if (code == REG_NOMATCH) {
|
||||
// // Not match
|
||||
// tsdbInfo("vgId:%d invalid file %s exists, remove it", REPO_ID(pRepo), pf->aname);
|
||||
// tfsremove(pf);
|
||||
// continue;
|
||||
// } else {
|
||||
// // Has other error
|
||||
// tsdbError("vgId:%d failed to restore meta file while run regexec since %s", REPO_ID(pRepo), strerror(code));
|
||||
// terrno = TAOS_SYSTEM_ERROR(code);
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (pfs->cstatus->pmf) {
|
||||
// tsdbInfo("vgId:%d meta file %s is restored", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pfs->cstatus->pmf));
|
||||
// } else {
|
||||
// tsdbInfo("vgId:%d no meta file is restored", REPO_ID(pRepo));
|
||||
// }
|
||||
|
||||
// tfsClosedir(tdir);
|
||||
// regfree(®ex);
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
static int tsdbRestoreDFileSet(STsdb *pRepo) {
|
||||
char dataDir[TSDB_FILENAME_LEN];
|
||||
char bname[TSDB_FILENAME_LEN];
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
static const char *TSDB_FNAME_SUFFIX[] = {
|
||||
"head", // TSDB_FILE_HEAD
|
||||
|
@ -33,271 +33,6 @@ static int tsdbEncodeDFInfo(void **buf, SDFInfo *pInfo);
|
|||
static void *tsdbDecodeDFInfo(void *buf, SDFInfo *pInfo);
|
||||
static int tsdbRollBackDFile(SDFile *pDFile);
|
||||
|
||||
#if 0
|
||||
// ============== SMFile
|
||||
void tsdbInitMFile(SMFile *pMFile, SDiskID did, int vid, uint32_t ver) {
|
||||
char fname[TSDB_FILENAME_LEN];
|
||||
|
||||
TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_OK);
|
||||
|
||||
memset(&(pMFile->info), 0, sizeof(pMFile->info));
|
||||
pMFile->info.magic = TSDB_FILE_INIT_MAGIC;
|
||||
|
||||
tsdbGetFilename(vid, 0, ver, TSDB_FILE_META, fname);
|
||||
tfsInitFile(TSDB_FILE_F(pMFile), did.level, did.id, fname);
|
||||
}
|
||||
|
||||
void tsdbInitMFileEx(SMFile *pMFile, const SMFile *pOMFile) {
|
||||
*pMFile = *pOMFile;
|
||||
TSDB_FILE_SET_CLOSED(pMFile);
|
||||
}
|
||||
|
||||
int tsdbEncodeSMFile(void **buf, SMFile *pMFile) {
|
||||
int tlen = 0;
|
||||
|
||||
tlen += tsdbEncodeMFInfo(buf, &(pMFile->info));
|
||||
tlen += tfsEncodeFile(buf, &(pMFile->f));
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tsdbDecodeSMFile(void *buf, SMFile *pMFile) {
|
||||
buf = tsdbDecodeMFInfo(buf, &(pMFile->info));
|
||||
buf = tfsDecodeFile(buf, &(pMFile->f));
|
||||
TSDB_FILE_SET_CLOSED(pMFile);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int tsdbEncodeSMFileEx(void **buf, SMFile *pMFile) {
|
||||
int tlen = 0;
|
||||
|
||||
tlen += tsdbEncodeMFInfo(buf, &(pMFile->info));
|
||||
tlen += taosEncodeString(buf, TSDB_FILE_FULL_NAME(pMFile));
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tsdbDecodeSMFileEx(void *buf, SMFile *pMFile) {
|
||||
char *aname;
|
||||
buf = tsdbDecodeMFInfo(buf, &(pMFile->info));
|
||||
buf = taosDecodeString(buf, &aname);
|
||||
strncpy(TSDB_FILE_FULL_NAME(pMFile), aname, TSDB_FILENAME_LEN);
|
||||
TSDB_FILE_SET_CLOSED(pMFile);
|
||||
|
||||
taosMemoryFreeClear(aname);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int tsdbApplyMFileChange(SMFile *from, SMFile *to) {
|
||||
if (from == NULL && to == NULL) return 0;
|
||||
|
||||
if (from != NULL) {
|
||||
if (to == NULL) {
|
||||
return tsdbRemoveMFile(from);
|
||||
} else {
|
||||
if (tfsIsSameFile(TSDB_FILE_F(from), TSDB_FILE_F(to))) {
|
||||
if (from->info.size > to->info.size) {
|
||||
tsdbRollBackMFile(to);
|
||||
}
|
||||
} else {
|
||||
return tsdbRemoveMFile(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbCreateMFile(SMFile *pMFile, bool updateHeader) {
|
||||
ASSERT(pMFile->info.size == 0 && pMFile->info.magic == TSDB_FILE_INIT_MAGIC);
|
||||
|
||||
pMFile->fd = open(TSDB_FILE_FULL_NAME(pMFile), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0755);
|
||||
if (pMFile->fd < 0) {
|
||||
if (errno == ENOENT) {
|
||||
// Try to create directory recursively
|
||||
char *s = strdup(TFILE_REL_NAME(&(pMFile->f)));
|
||||
if (tfsMkdirRecurAt(dirname(s), TSDB_FILE_LEVEL(pMFile), TSDB_FILE_ID(pMFile)) < 0) {
|
||||
taosMemoryFreeClear(s);
|
||||
return -1;
|
||||
}
|
||||
taosMemoryFreeClear(s);
|
||||
|
||||
pMFile->fd = open(TSDB_FILE_FULL_NAME(pMFile), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0755);
|
||||
if (pMFile->fd < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!updateHeader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMFile->info.size += TSDB_FILE_HEAD_SIZE;
|
||||
|
||||
if (tsdbUpdateMFileHeader(pMFile) < 0) {
|
||||
tsdbCloseMFile(pMFile);
|
||||
tsdbRemoveMFile(pMFile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbUpdateMFileHeader(SMFile *pMFile) {
|
||||
char buf[TSDB_FILE_HEAD_SIZE] = "\0";
|
||||
|
||||
if (tsdbSeekMFile(pMFile, 0, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *ptr = buf;
|
||||
tsdbEncodeMFInfo(&ptr, TSDB_FILE_INFO(pMFile));
|
||||
|
||||
taosCalcChecksumAppend(0, (uint8_t *)buf, TSDB_FILE_HEAD_SIZE);
|
||||
if (tsdbWriteMFile(pMFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbLoadMFileHeader(SMFile *pMFile, SMFInfo *pInfo) {
|
||||
char buf[TSDB_FILE_HEAD_SIZE] = "\0";
|
||||
|
||||
ASSERT(TSDB_FILE_OPENED(pMFile));
|
||||
|
||||
if (tsdbSeekMFile(pMFile, 0, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbReadMFile(pMFile, buf, TSDB_FILE_HEAD_SIZE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!taosCheckChecksumWhole((uint8_t *)buf, TSDB_FILE_HEAD_SIZE)) {
|
||||
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbDecodeMFInfo(buf, pInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbScanAndTryFixMFile(STsdb *pRepo) {
|
||||
SMFile * pMFile = pRepo->fs->cstatus->pmf;
|
||||
struct stat mfstat;
|
||||
SMFile mf;
|
||||
|
||||
if (pMFile == NULL) {
|
||||
// No meta file, no need to scan
|
||||
return 0;
|
||||
}
|
||||
|
||||
tsdbInitMFileEx(&mf, pMFile);
|
||||
|
||||
if (access(TSDB_FILE_FULL_NAME(pMFile), F_OK) != 0) {
|
||||
tsdbError("vgId:%d meta file %s not exit, report to upper layer to fix it", REPO_ID(pRepo),
|
||||
TSDB_FILE_FULL_NAME(pMFile));
|
||||
pRepo->state |= TSDB_STATE_BAD_META;
|
||||
TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_BAD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat(TSDB_FILE_FULL_NAME(&mf), &mfstat) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pMFile->info.size < mfstat.st_size) {
|
||||
if (tsdbOpenMFile(&mf, O_WRONLY) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosFtruncate(mf.fd, mf.info.size) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
tsdbCloseMFile(&mf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbUpdateMFileHeader(&mf) < 0) {
|
||||
tsdbCloseMFile(&mf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbCloseMFile(&mf);
|
||||
tsdbInfo("vgId:%d file %s is truncated from %" PRId64 " to %" PRId64, REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile),
|
||||
mfstat.st_size, pMFile->info.size);
|
||||
} else if (pMFile->info.size > mfstat.st_size) {
|
||||
tsdbError("vgId:%d meta file %s has wrong size %" PRId64 " expected %" PRId64 ", report to upper layer to fix it",
|
||||
REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile), mfstat.st_size, pMFile->info.size);
|
||||
pRepo->state |= TSDB_STATE_BAD_META;
|
||||
TSDB_FILE_SET_STATE(pMFile, TSDB_FILE_STATE_BAD);
|
||||
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
return 0;
|
||||
} else {
|
||||
tsdbDebug("vgId:%d meta file %s passes the scan", REPO_ID(pRepo), TSDB_FILE_FULL_NAME(pMFile));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbEncodeMFInfo(void **buf, SMFInfo *pInfo) {
|
||||
int tlen = 0;
|
||||
|
||||
tlen += taosEncodeVariantI64(buf, pInfo->size);
|
||||
tlen += taosEncodeVariantI64(buf, pInfo->tombSize);
|
||||
tlen += taosEncodeVariantI64(buf, pInfo->nRecords);
|
||||
tlen += taosEncodeVariantI64(buf, pInfo->nDels);
|
||||
tlen += taosEncodeFixedU32(buf, pInfo->magic);
|
||||
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tsdbDecodeMFInfo(void *buf, SMFInfo *pInfo) {
|
||||
buf = taosDecodeVariantI64(buf, &(pInfo->size));
|
||||
buf = taosDecodeVariantI64(buf, &(pInfo->tombSize));
|
||||
buf = taosDecodeVariantI64(buf, &(pInfo->nRecords));
|
||||
buf = taosDecodeVariantI64(buf, &(pInfo->nDels));
|
||||
buf = taosDecodeFixedU32(buf, &(pInfo->magic));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int tsdbRollBackMFile(SMFile *pMFile) {
|
||||
SMFile mf;
|
||||
|
||||
tsdbInitMFileEx(&mf, pMFile);
|
||||
|
||||
if (tsdbOpenMFile(&mf, O_WRONLY) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (taosFtruncate(TSDB_FILE_FD(&mf), pMFile->info.size) < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
tsdbCloseMFile(&mf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tsdbUpdateMFileHeader(&mf) < 0) {
|
||||
tsdbCloseMFile(&mf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TSDB_FILE_FSYNC(&mf);
|
||||
|
||||
tsdbCloseMFile(&mf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ============== Operations on SDFile
|
||||
void tsdbInitDFile(STsdb *pRepo, SDFile *pDFile, SDiskID did, int fid, uint32_t ver, TSDB_FILE_T ftype) {
|
||||
char fname[TSDB_FILENAME_LEN];
|
||||
|
@ -310,7 +45,7 @@ void tsdbInitDFile(STsdb *pRepo, SDFile *pDFile, SDiskID did, int fid, uint32_t
|
|||
pDFile->info.magic = TSDB_FILE_INIT_MAGIC;
|
||||
pDFile->info.fver = tsdbGetDFSVersion(ftype);
|
||||
|
||||
tsdbGetFilename(pRepo->vgId, fid, ver, ftype, fname);
|
||||
tsdbGetFilename(REPO_ID(pRepo), fid, ver, ftype, fname);
|
||||
tfsInitFile(REPO_TFS(pRepo), &(pDFile->f), did, fname);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
static STbData *tsdbNewTbData(tb_uid_t uid);
|
||||
static void tsdbFreeTbData(STbData *pTbData);
|
||||
|
@ -285,21 +285,6 @@ static STbData *tsdbNewTbData(tb_uid_t uid) {
|
|||
pTbData->keyMax = TSKEY_MIN;
|
||||
pTbData->nrows = 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;
|
||||
// taosMemoryFree(pTableData);
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
pTbData->pData = tSkipListCreate(5, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), tkeyComparFn, SL_DISCARD_DUP_KEY,
|
||||
tsdbGetTsTupleKey);
|
||||
if (pTbData->pData == NULL) {
|
||||
|
@ -351,608 +336,3 @@ static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema *
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------ REFACTORING ------------------------ */
|
||||
#if 0
|
||||
int tsdbInsertDataToMemTable(STsdbMemTable *pMemTable, SSubmitReq *pMsg) {
|
||||
SMemAllocator *pMA = pMemTable->pMA;
|
||||
STbData * pTbData = (STbData *)TD_MA_MALLOC(pMA, sizeof(*pTbData));
|
||||
if (pTbData == NULL) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
TD_SLIST_PUSH(&(pMemTable->list), pTbData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "tdataformat.h"
|
||||
#include "tfunctional.h"
|
||||
#include "tsdbRowMergeBuf.h"
|
||||
#include "tsdbint.h"
|
||||
#include "tskiplist.h"
|
||||
|
||||
#define TSDB_DATA_SKIPLIST_LEVEL 5
|
||||
#define TSDB_MAX_INSERT_BATCH 512
|
||||
|
||||
typedef struct {
|
||||
int32_t totalLen;
|
||||
int32_t len;
|
||||
STSRow* 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 int tsdbAdjustMemMaxTables(SMemTable *pMemTable, int maxTables);
|
||||
static int tsdbAppendTableRowToCols(STable *pTable, SDataCols *pCols, STSchema **ppSchema, STSRow* row);
|
||||
static int tsdbInitSubmitBlkIter(SSubmitBlk *pBlock, SSubmitBlkIter *pIter);
|
||||
static STSRow* tsdbGetSubmitBlkNext(SSubmitBlkIter *pIter);
|
||||
static int tsdbInsertDataToTable(STsdbRepo *pRepo, SSubmitBlk *pBlock, int32_t *affectedrows);
|
||||
static int tsdbInitSubmitMsgIter(SSubmitReq *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, STSRow* row);
|
||||
|
||||
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, STSRow* row, TSKEY minKey, TSKEY maxKey,
|
||||
TSKEY now);
|
||||
|
||||
|
||||
// ---------------- 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 = taosThreadCondSignal(&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 **)taosMemoryCalloc(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);
|
||||
}
|
||||
}
|
||||
taosMemoryFreeClear(pSnapshot->mem->tData);
|
||||
|
||||
tsdbUnRefMemTable(pRepo, pSnapshot->omem);
|
||||
}
|
||||
|
||||
tsdbUnRefMemTable(pRepo, pSnapshot->imem);
|
||||
|
||||
pSnapshot->mem = NULL;
|
||||
pSnapshot->imem = NULL;
|
||||
pSnapshot->omem = NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
STSRow* 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 || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(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 = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(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 = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row);
|
||||
}
|
||||
|
||||
tSkipListIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(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 = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
tsdbAppendTableRowToCols(pTable, pCols, &pSchema, row);
|
||||
} else {
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
|
||||
}
|
||||
}
|
||||
|
||||
tSkipListIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = memRowDeleted(row);
|
||||
}
|
||||
|
||||
filterIter++;
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ---------------- LOCAL FUNCTIONS ----------------
|
||||
|
||||
static FORCE_INLINE int tsdbCheckRowRange(STsdbRepo *pRepo, STable *pTable, STSRow* row, TSKEY minKey, TSKEY maxKey,
|
||||
TSKEY now) {
|
||||
TSKEY rowKey = TD_ROW_KEY(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;
|
||||
}
|
||||
|
||||
|
||||
//row1 has higher priority
|
||||
static STSRow* tsdbInsertDupKeyMerge(STSRow* row1, STSRow* row2, STsdbRepo* pRepo,
|
||||
STSchema **ppSchema1, STSchema **ppSchema2,
|
||||
STable* pTable, int32_t* pPoints, STSRow** 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;
|
||||
}
|
||||
|
||||
tsdbTrace("vgId:%d a row is %s table %s tid %d uid %" PRIu64 " key %" PRIu64, REPO_ID(pRepo),
|
||||
"updated in", TABLE_CHAR_NAME(pTable), TABLE_TID(pTable), TABLE_UID(pTable),
|
||||
TD_ROW_KEY(row1));
|
||||
|
||||
if(row2 == NULL || pRepo->config.update != TD_ROW_PARTIAL_UPDATE) {
|
||||
void* pMem = tsdbAllocBytes(pRepo, TD_ROW_LEN(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), (int8_t)memRowType(row1));
|
||||
}
|
||||
pSchema1 = *ppSchema1;
|
||||
}
|
||||
|
||||
if(pSchema2 == NULL || schemaVersion(pSchema2) != dv2) {
|
||||
if(schemaVersion(pSchema1) == dv2) {
|
||||
pSchema2 = pSchema1;
|
||||
} else {
|
||||
*ppSchema2 = tsdbGetTableSchemaImpl(pTable, false, false, memRowVersion(row2), (int8_t)memRowType(row2));
|
||||
pSchema2 = *ppSchema2;
|
||||
}
|
||||
}
|
||||
|
||||
STSRow* tmp = tsdbMergeTwoRows(pBuf, row1, row2, pSchema1, pSchema2);
|
||||
|
||||
void* pMem = tsdbAllocBytes(pRepo, TD_ROW_LEN(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, STSRow** 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 tsdbCheckTableSchema(STsdbRepo *pRepo, SSubmitBlk *pBlock, STable *pTable) {
|
||||
ASSERT(pTable != NULL);
|
||||
|
||||
STSchema *pSchema = tsdbGetTableSchemaImpl(pTable, false, false, -1, -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, -1) == 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, STSRow* 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), (int8_t)memRowType(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;
|
||||
}
|
||||
// lock
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
SDataCol *pDataCol = &(pLatestCols[idx]);
|
||||
if (pDataCol->pData == NULL) {
|
||||
pDataCol->pData = taosMemoryMalloc(pTCol->bytes);
|
||||
pDataCol->bytes = pTCol->bytes;
|
||||
} else if (pDataCol->bytes < pTCol->bytes) {
|
||||
pDataCol->pData = taosMemoryRealloc(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 = TD_ROW_KEY(row);
|
||||
// unlock
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
}
|
||||
}
|
||||
|
||||
static int tsdbUpdateTableLatestInfo(STsdbRepo *pRepo, STable *pTable, STSRow* row) {
|
||||
STsdbCfg *pCfg = &pRepo->config;
|
||||
|
||||
// if cacheLastRow config has been reset, free the lastRow
|
||||
if (!pCfg->cacheLastRow && pTable->lastRow != NULL) {
|
||||
STSRow* cachedLastRow = pTable->lastRow;
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
pTable->lastRow = NULL;
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
taosTZfree(cachedLastRow);
|
||||
}
|
||||
|
||||
if (tsdbGetTableLastKeyImpl(pTable) <= TD_ROW_KEY(row)) {
|
||||
if (CACHE_LAST_ROW(pCfg) || pTable->lastRow != NULL) {
|
||||
STSRow* nrow = pTable->lastRow;
|
||||
if (taosTSizeof(nrow) < TD_ROW_LEN(row)) {
|
||||
STSRow* orow = nrow;
|
||||
nrow = taosTMalloc(TD_ROW_LEN(row));
|
||||
if (nrow == NULL) {
|
||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memRowCpy(nrow, row);
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
pTable->lastKey = TD_ROW_KEY(row);
|
||||
pTable->lastRow = nrow;
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
taosTZfree(orow);
|
||||
} else {
|
||||
TSDB_WLOCK_TABLE(pTable);
|
||||
pTable->lastKey = TD_ROW_KEY(row);
|
||||
memRowCpy(nrow, row);
|
||||
TSDB_WUNLOCK_TABLE(pTable);
|
||||
}
|
||||
} else {
|
||||
pTable->lastKey = TD_ROW_KEY(row);
|
||||
}
|
||||
|
||||
if (CACHE_LAST_NULL_COLUMN(pCfg)) {
|
||||
updateTableLatestColumn(pRepo, pTable, row);
|
||||
}
|
||||
}
|
||||
|
||||
pTable->cacheLastConfigVersion = pRepo->cacheLastConfigVersion;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
int tsdbOpen(SVnode *pVnode, STsdb **ppTsdb) {
|
||||
STsdb *pTsdb = NULL;
|
||||
int slen = 0;
|
||||
|
||||
*ppTsdb = NULL;
|
||||
slen = strlen(tfsGetPrimaryPath(pVnode->pTfs)) + strlen(pVnode->path) + strlen(VNODE_TSDB_DIR) + 3;
|
||||
|
||||
// create handle
|
||||
pTsdb = (STsdb *)taosMemoryCalloc(1, sizeof(*pTsdb) + slen);
|
||||
if (pTsdb == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pTsdb->path = (char *)&pTsdb[1];
|
||||
sprintf(pTsdb->path, "%s%s%s%s%s", tfsGetPrimaryPath(pVnode->pTfs), TD_DIRSEP, pVnode->path, TD_DIRSEP,
|
||||
VNODE_TSDB_DIR);
|
||||
pTsdb->pVnode = pVnode;
|
||||
pTsdb->repoLocked = false;
|
||||
tdbMutexInit(&pTsdb->mutex, NULL);
|
||||
pTsdb->config = pVnode->config.tsdbCfg;
|
||||
pTsdb->fs = tsdbNewFS(&pTsdb->config);
|
||||
|
||||
// create dir (TODO: use tfsMkdir)
|
||||
taosMkDir(pTsdb->path);
|
||||
|
||||
// open tsdb
|
||||
if (tsdbOpenFS(pTsdb) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
tsdbDebug("vgId: %d tsdb is opened", TD_VID(pVnode));
|
||||
|
||||
*ppTsdb = pTsdb;
|
||||
return 0;
|
||||
|
||||
_err:
|
||||
taosMemoryFree(pTsdb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tsdbClose(STsdb *pTsdb) {
|
||||
if (pTsdb) {
|
||||
tsdbCloseFS(pTsdb);
|
||||
tsdbFreeFS(pTsdb->fs);
|
||||
taosMemoryFree(pTsdb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbLockRepo(STsdb *pTsdb) {
|
||||
int code = taosThreadMutexLock(&pTsdb->mutex);
|
||||
if (code != 0) {
|
||||
tsdbError("vgId:%d failed to lock tsdb since %s", REPO_ID(pTsdb), strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
pTsdb->repoLocked = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tsdbUnlockRepo(STsdb *pTsdb) {
|
||||
ASSERT(IS_REPO_LOCKED(pTsdb));
|
||||
pTsdb->repoLocked = false;
|
||||
int code = taosThreadMutexUnlock(&pTsdb->mutex);
|
||||
if (code != 0) {
|
||||
tsdbError("vgId:%d failed to unlock tsdb since %s", REPO_ID(pTsdb), strerror(errno));
|
||||
terrno = TAOS_SYSTEM_ERROR(code);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
|
||||
const STsdbCfg defautlTsdbOptions = {.precision = 0,
|
||||
.lruCacheSize = 0,
|
||||
.days = 10,
|
||||
.minRows = 100,
|
||||
.maxRows = 4096,
|
||||
.keep2 = 3650,
|
||||
.keep0 = 3650,
|
||||
.keep1 = 3650,
|
||||
.update = 0,
|
||||
.compression = TWO_STAGE_COMP};
|
||||
|
||||
int tsdbValidateOptions(const STsdbCfg *pTsdbOptions) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tsdbOptionsCopy(STsdbCfg *pDest, const STsdbCfg *pSrc) { memcpy(pDest, pSrc, sizeof(STsdbCfg)); }
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
#define EXTRA_BYTES 2
|
||||
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
|
||||
|
@ -3618,7 +3618,7 @@ int32_t tsdbQuerySTableByTagCond(void* pMeta, uint64_t uid, TSKEY skey, const ch
|
|||
SColIndex* pColIndex, int32_t numOfCols, uint64_t reqId, uint64_t taskId) {
|
||||
SMetaReader mr = {0};
|
||||
|
||||
metaReaderInit(&mr, ((SMeta*)pMeta)->pVnode, 0);
|
||||
metaReaderInit(&mr, (SMeta*)pMeta, 0);
|
||||
|
||||
if (metaGetTableEntryByUid(&mr, uid) < 0) {
|
||||
tsdbError("%p failed to get stable, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId, reqId);
|
||||
|
@ -3628,7 +3628,7 @@ int32_t tsdbQuerySTableByTagCond(void* pMeta, uint64_t uid, TSKEY skey, const ch
|
|||
tsdbDebug("%p succeed to get stable, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId, reqId);
|
||||
}
|
||||
|
||||
if (mr.me.type != META_SUPER_TABLE) {
|
||||
if (mr.me.type != TSDB_SUPER_TABLE) {
|
||||
tsdbError("%p query normal tag not allowed, uid:%" PRIu64 ", TID:0x%" PRIx64 " QID:0x%" PRIx64, pMeta, uid, taskId,
|
||||
reqId);
|
||||
terrno = TSDB_CODE_OPS_NOT_SUPPORT; // basically, this error is caused by invalid sql issued by client
|
||||
|
@ -3687,10 +3687,9 @@ int32_t tsdbQueryTableList(void* pMeta, SArray* pRes, void* filterInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int32_t tsdbGetOneTableGroup(void* pMeta, uint64_t uid, TSKEY startKey, STableGroupInfo* pGroupInfo) {
|
||||
SMeta* metaP = (SMeta*)pMeta;
|
||||
SMetaReader mr = {0};
|
||||
|
||||
metaReaderInit(&mr, metaP->pVnode, 0);
|
||||
metaReaderInit(&mr, (SMeta*)pMeta, 0);
|
||||
|
||||
if (metaGetTableEntryByUid(&mr, uid) < 0) {
|
||||
terrno = TSDB_CODE_TDB_INVALID_TABLE_ID;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
#define TSDB_KEY_COL_OFFSET 0
|
||||
|
||||
|
|
|
@ -13,9 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
#include "tsdbint.h"
|
||||
#include "tsdb.h"
|
||||
#ifndef _TSDB_PLUGINS
|
||||
|
||||
int tsdbScanFGroup(STsdbScanHandle* pScanHandle, char* rootDir, int fid) { return 0; }
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdbSma.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
static const char *TSDB_SMA_DNAME[] = {
|
||||
"", // TSDB_SMA_TYPE_BLOCK
|
||||
|
@ -678,7 +679,6 @@ int32_t tsdbUpdateExpiredWindowImpl(STsdb *pTsdb, SSubmitReq *pMsg, int64_t vers
|
|||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
|
||||
|
||||
if (tsdbCheckAndInitSmaEnv(pTsdb, TSDB_SMA_TYPE_TIME_RANGE) != TSDB_CODE_SUCCESS) {
|
||||
terrno = TSDB_CODE_TDB_INIT_FAILED;
|
||||
return TSDB_CODE_FAILED;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define ALLOW_FORBID_FUNC
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
int32_t tsdbOpenDBEnv(TENV **ppEnv, const char *path) {
|
||||
int ret = 0;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
static int tsdbScanAndConvertSubmitMsg(STsdb *pTsdb, SSubmitReq *pMsg);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
/* ------------------------ STRUCTURES ------------------------ */
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
const SVnodeCfg vnodeCfgDefault = {
|
||||
.vgId = -1,
|
||||
|
@ -23,8 +23,6 @@ const SVnodeCfg vnodeCfgDefault = {
|
|||
.szCache = 256,
|
||||
.szBuf = 96 * 1024 * 1024,
|
||||
.isHeap = false,
|
||||
.ttl = 0,
|
||||
.keep = 0,
|
||||
.streamMode = 0,
|
||||
.isWeak = 0,
|
||||
.tsdbCfg = {.precision = TSDB_TIME_PRECISION_MILLI,
|
||||
|
@ -58,8 +56,6 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddIntegerToObject(pJson, "szCache", pCfg->szCache) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "szBuf", pCfg->szBuf) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "isHeap", pCfg->isHeap) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "ttl", pCfg->ttl) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "keep", pCfg->keep) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "streamMode", pCfg->streamMode) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "isWeak", pCfg->isWeak) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "precision", pCfg->tsdbCfg.precision) < 0) return -1;
|
||||
|
@ -72,7 +68,6 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddIntegerToObject(pJson, "keep0", pCfg->tsdbCfg.keep0) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "keep1", pCfg->tsdbCfg.keep1) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "keep2", pCfg->tsdbCfg.keep2) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "lruCacheSize", pCfg->tsdbCfg.lruCacheSize) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.vgId", pCfg->walCfg.vgId) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod) < 0) return -1;
|
||||
|
@ -109,8 +104,6 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
if (tjsonGetNumberValue(pJson, "szCache", pCfg->szCache) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "szBuf", pCfg->szBuf) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "isHeap", pCfg->isHeap) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "ttl", pCfg->ttl) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "keep", pCfg->keep) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "streamMode", pCfg->streamMode) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "isWeak", pCfg->isWeak) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "precision", pCfg->tsdbCfg.precision) < 0) return -1;
|
||||
|
@ -123,7 +116,6 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
if (tjsonGetNumberValue(pJson, "keep0", pCfg->tsdbCfg.keep0) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "keep1", pCfg->tsdbCfg.keep1) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "keep2", pCfg->tsdbCfg.keep2) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "lruCacheSize", pCfg->tsdbCfg.lruCacheSize) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "wal.vgId", pCfg->walCfg.vgId) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "wal.fsyncPeriod", pCfg->walCfg.fsyncPeriod) < 0) return -1;
|
||||
if (tjsonGetNumberValue(pJson, "wal.retentionPeriod", pCfg->walCfg.retentionPeriod) < 0) return -1;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
#define VND_INFO_FNAME "vnode.json"
|
||||
#define VND_INFO_FNAME_TMP "vnode_tmp.json"
|
||||
|
@ -175,7 +175,7 @@ int vnodeAsyncCommit(SVnode *pVnode) {
|
|||
vnodeWaitCommit(pVnode);
|
||||
|
||||
// vnodeBufPoolSwitch(pVnode);
|
||||
tsdbPrepareCommit(pVnode->pTsdb);
|
||||
// tsdbPrepareCommit(pVnode->pTsdb);
|
||||
|
||||
vnodeScheduleTask(vnodeCommitImpl, pVnode);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
// #include "vnodeInt.h"
|
||||
|
||||
int32_t vnodeAlter(SVnode *pVnode, const SVnodeCfg *pCfg) { return 0; }
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
typedef struct SVnodeTask SVnodeTask;
|
||||
struct SVnodeTask {
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnodeSync.h"
|
||||
#include "vnd.h"
|
||||
|
||||
int vnodeCreate(const char *path, SVnodeCfg *pCfg, STfs *pTfs) {
|
||||
SVnodeInfo info = {0};
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
int vnodeQueryOpen(SVnode *pVnode) {
|
||||
return qWorkerInit(NODE_TYPE_VNODE, TD_VID(pVnode), NULL, (void **)&pVnode->pQuery, &pVnode->msgCb);
|
||||
|
@ -51,9 +51,10 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
// query meta
|
||||
metaReaderInit(&mer1, pVnode, 0);
|
||||
metaReaderInit(&mer1, pVnode->pMeta, 0);
|
||||
|
||||
if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) {
|
||||
code = terrno;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
|
@ -67,7 +68,7 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
schemaTag = mer1.me.stbEntry.schemaTag;
|
||||
metaRsp.suid = mer1.me.uid;
|
||||
} else if (mer1.me.type == TSDB_CHILD_TABLE) {
|
||||
metaReaderInit(&mer2, pVnode, 0);
|
||||
metaReaderInit(&mer2, pVnode->pMeta, 0);
|
||||
if (metaGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
|
||||
|
||||
strcpy(metaRsp.stbName, mer2.me.name);
|
||||
|
@ -105,6 +106,7 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
}
|
||||
tSerializeSTableMetaRsp(pRsp, rspLen, &metaRsp);
|
||||
|
||||
_exit:
|
||||
rpcMsg.handle = pMsg->handle;
|
||||
rpcMsg.ahandle = pMsg->ahandle;
|
||||
rpcMsg.refId = pMsg->refId;
|
||||
|
@ -114,7 +116,6 @@ int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
|
||||
tmsgSendRsp(&rpcMsg);
|
||||
|
||||
_exit:
|
||||
taosMemoryFree(metaRsp.pSchemas);
|
||||
metaReaderClear(&mer2);
|
||||
metaReaderClear(&mer1);
|
||||
|
@ -137,3 +138,13 @@ int32_t vnodeGetLoad(SVnode *pVnode, SVnodeLoad *pLoad) {
|
|||
pLoad->numOfBatchInsertSuccessReqs = 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId) {
|
||||
if (dbname) {
|
||||
*dbname = pVnode->config.dbname;
|
||||
}
|
||||
|
||||
if (vgId) {
|
||||
*vgId = TD_VID(pVnode);
|
||||
}
|
||||
}
|
|
@ -13,9 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncTools.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
|
||||
static int vnodeProcessCreateStbReq(SVnode *pVnode, int64_t version, void *pReq, int len, SRpcMsg *pRsp);
|
||||
static int vnodeProcessAlterStbReq(SVnode *pVnode, void *pReq, int32_t len, SRpcMsg *pRsp);
|
||||
|
@ -144,7 +142,7 @@ _err:
|
|||
|
||||
int vnodeProcessQueryMsg(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
vTrace("message in vnode query queue is processing");
|
||||
SReadHandle handle = {.reader = pVnode->pTsdb, .meta = pVnode->pMeta, .config = &pVnode->config};
|
||||
SReadHandle handle = {.reader = pVnode->pTsdb, .meta = pVnode->pMeta, .config = &pVnode->config, .vnode = pVnode};
|
||||
|
||||
switch (pMsg->msgType) {
|
||||
case TDMT_VND_QUERY:
|
||||
|
@ -201,9 +199,7 @@ void smaHandleRes(void *pVnode, int64_t smaId, const SArray *data) {
|
|||
|
||||
// sync integration
|
||||
int vnodeProcessSyncReq(SVnode *pVnode, SRpcMsg *pMsg, SRpcMsg **pRsp) {
|
||||
|
||||
if (syncEnvIsStart()) {
|
||||
|
||||
SSyncNode *pSyncNode = syncNodeAcquire(pVnode->sync);
|
||||
assert(pSyncNode != NULL);
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncTools.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "vnodeInt.h"
|
||||
#include "vnd.h"
|
||||
// #include "sync.h"
|
||||
// #include "syncTools.h"
|
||||
// #include "tmsgcb.h"
|
||||
// #include "vnodeInt.h"
|
||||
|
||||
// sync integration
|
||||
|
||||
|
|
|
@ -27,9 +27,14 @@ static int32_t getSchemaBytes(const SSchema* pSchema) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo : to convert data according to SSDatablock
|
||||
static void buildRspData(const STableMeta* pMeta, char* pData) {
|
||||
int32_t* pColSizes = (int32_t*)pData;
|
||||
pData += DESCRIBE_RESULT_COLS * sizeof(int32_t);
|
||||
int32_t* payloadLen = (int32_t*) pData;
|
||||
uint64_t* groupId = (uint64_t*)(pData + sizeof(int32_t));
|
||||
|
||||
int32_t* pColSizes = (int32_t*)(pData + sizeof(int32_t) + sizeof(uint64_t));
|
||||
pData = (char*) pColSizes + DESCRIBE_RESULT_COLS * sizeof(int32_t);
|
||||
|
||||
int32_t numOfRows = TABLE_TOTAL_COL_NUM(pMeta);
|
||||
|
||||
// Field
|
||||
|
@ -79,6 +84,9 @@ static void buildRspData(const STableMeta* pMeta, char* pData) {
|
|||
for (int32_t i = 0; i < DESCRIBE_RESULT_COLS; ++i) {
|
||||
pColSizes[i] = htonl(pColSizes[i]);
|
||||
}
|
||||
|
||||
|
||||
*payloadLen = (int32_t)(pData - (char*)payloadLen);
|
||||
}
|
||||
|
||||
static int32_t calcRspSize(const STableMeta* pMeta) {
|
||||
|
@ -87,7 +95,8 @@ static int32_t calcRspSize(const STableMeta* pMeta) {
|
|||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_FIELD_LEN) +
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_TYPE_LEN) +
|
||||
(BitmapLen(numOfRows) + numOfRows * sizeof(int32_t)) +
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_NOTE_LEN);
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_NOTE_LEN) +
|
||||
sizeof(int32_t) + sizeof(uint64_t);
|
||||
}
|
||||
|
||||
static int32_t execDescribe(SNode* pStmt, SRetrieveTableRsp** pRsp) {
|
||||
|
|
|
@ -254,6 +254,17 @@ enum {
|
|||
OP_EXEC_DONE = 0x9,
|
||||
};
|
||||
|
||||
typedef struct SOperatorFpSet {
|
||||
__optr_open_fn_t _openFn; // DO NOT invoke this function directly
|
||||
__optr_fn_t getNextFn;
|
||||
__optr_fn_t getStreamResFn; // execute the aggregate in the stream model, todo remove it
|
||||
__optr_fn_t cleanupFn; // call this function to release the allocated resources ASAP
|
||||
__optr_close_fn_t closeFn;
|
||||
__optr_encode_fn_t encodeResultRow;
|
||||
__optr_decode_fn_t decodeResultRow;
|
||||
__optr_get_explain_fn_t getExplainFn;
|
||||
} SOperatorFpSet;
|
||||
|
||||
typedef struct SOperatorInfo {
|
||||
uint8_t operatorType;
|
||||
bool blockingOptr; // block operator or not
|
||||
|
@ -267,15 +278,7 @@ typedef struct SOperatorInfo {
|
|||
SResultInfo resultInfo;
|
||||
struct SOperatorInfo** pDownstream; // downstram pointer list
|
||||
int32_t numOfDownstream; // number of downstream. The value is always ONE expect for join operator
|
||||
// todo extract struct
|
||||
__optr_open_fn_t _openFn; // DO NOT invoke this function directly
|
||||
__optr_fn_t getNextFn;
|
||||
__optr_fn_t getStreamResFn; // execute the aggregate in the stream model.
|
||||
__optr_fn_t cleanupFn; // call this function to release the allocated resources ASAP
|
||||
__optr_close_fn_t closeFn;
|
||||
__optr_encode_fn_t encodeResultRow;
|
||||
__optr_decode_fn_t decodeResultRow;
|
||||
__optr_get_explain_fn_t getExplainFn;
|
||||
SOperatorFpSet fpSet;
|
||||
} SOperatorInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -377,7 +380,7 @@ typedef struct SStreamBlockScanInfo {
|
|||
typedef struct SSysTableScanInfo {
|
||||
union {
|
||||
void* pTransporter;
|
||||
void* readHandle;
|
||||
SReadHandle readHandle;
|
||||
};
|
||||
|
||||
SRetrieveMetaTableRsp* pRsp;
|
||||
|
@ -609,6 +612,10 @@ typedef struct SJoinOperatorInfo {
|
|||
SNode *pOnCondition;
|
||||
} SJoinOperatorInfo;
|
||||
|
||||
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
|
||||
__optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_encode_fn_t encode,
|
||||
__optr_decode_fn_t decode, __optr_get_explain_fn_t explain);
|
||||
|
||||
int32_t operatorDummyOpenFn(SOperatorInfo* pOperator);
|
||||
void operatorDummyCloseFn(void* param, int32_t numOfCols);
|
||||
int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t num);
|
||||
|
@ -653,6 +660,9 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, SSDataB
|
|||
SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
STimeWindowAggSupp *pTwAggSupp, const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
STimeWindowAggSupp *pTwAggSupp, const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, int64_t gap, STimeWindowAggSupp *pTwAggSupp, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
|
|
|
@ -159,7 +159,7 @@ int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t *useconds) {
|
|||
int64_t st = 0;
|
||||
|
||||
st = taosGetTimestampUs();
|
||||
*pRes = pTaskInfo->pRoot->getNextFn(pTaskInfo->pRoot, &newgroup);
|
||||
*pRes = pTaskInfo->pRoot->fpSet.getNextFn(pTaskInfo->pRoot, &newgroup);
|
||||
|
||||
uint64_t el = (taosGetTimestampUs() - st);
|
||||
pTaskInfo->cost.elapsedTime += el;
|
||||
|
|
|
@ -226,6 +226,23 @@ int32_t operatorDummyOpenFn(SOperatorInfo* pOperator) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t streamFn,
|
||||
__optr_fn_t cleanup, __optr_close_fn_t closeFn, __optr_encode_fn_t encode,
|
||||
__optr_decode_fn_t decode, __optr_get_explain_fn_t explain) {
|
||||
SOperatorFpSet fpSet = {
|
||||
._openFn = openFn,
|
||||
.getNextFn = nextFn,
|
||||
.getStreamResFn = streamFn,
|
||||
.cleanupFn = cleanup,
|
||||
.closeFn = closeFn,
|
||||
.encodeResultRow = encode,
|
||||
.decodeResultRow = decode,
|
||||
.getExplainFn = explain,
|
||||
};
|
||||
|
||||
return fpSet;
|
||||
}
|
||||
|
||||
void operatorDummyCloseFn(void* param, int32_t numOfCols) {}
|
||||
|
||||
static int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbasedBuf* pBuf,
|
||||
|
@ -1017,7 +1034,7 @@ void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlo
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam, int32_t type,
|
||||
static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunctParam* pFuncParam,
|
||||
int32_t paramIndex, int32_t numOfRows) {
|
||||
SColumnInfoData* pColInfo = NULL;
|
||||
if (pInput->pData[paramIndex] == NULL) {
|
||||
|
@ -1027,17 +1044,17 @@ static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunc
|
|||
}
|
||||
|
||||
// Set the correct column info (data type and bytes)
|
||||
pColInfo->info.type = type;
|
||||
pColInfo->info.bytes = tDataTypes[type].bytes;
|
||||
pColInfo->info.type = pFuncParam->param.nType;
|
||||
pColInfo->info.bytes = pFuncParam->param.nLen;
|
||||
|
||||
pInput->pData[paramIndex] = pColInfo;
|
||||
} else {
|
||||
pColInfo = pInput->pData[paramIndex];
|
||||
}
|
||||
|
||||
ASSERT(!IS_VAR_DATA_TYPE(type));
|
||||
colInfoDataEnsureCapacity(pColInfo, 0, numOfRows);
|
||||
|
||||
int8_t type = pFuncParam->param.nType;
|
||||
if (type == TSDB_DATA_TYPE_BIGINT || type == TSDB_DATA_TYPE_UBIGINT) {
|
||||
int64_t v = pFuncParam->param.i;
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
|
@ -1048,6 +1065,12 @@ static int32_t doCreateConstantValColumnInfo(SInputColumnInfoData* pInput, SFunc
|
|||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
colDataAppendDouble(pColInfo, i, &v);
|
||||
}
|
||||
} else if (type == TSDB_DATA_TYPE_VARCHAR) {
|
||||
char *tmp = taosMemoryMalloc(pFuncParam->param.nLen + VARSTR_HEADER_SIZE);
|
||||
STR_WITH_SIZE_TO_VARSTR(tmp, pFuncParam->param.pz, pFuncParam->param.nLen);
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
colDataAppend(pColInfo, i, tmp, false);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1087,7 +1110,7 @@ static int32_t doSetInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCt
|
|||
pInput->numOfRows = pBlock->info.rows;
|
||||
pInput->startRowIndex = 0;
|
||||
|
||||
code = doCreateConstantValColumnInfo(pInput, pFuncParam, pFuncParam->param.nType, j, pBlock->info.rows);
|
||||
code = doCreateConstantValColumnInfo(pInput, pFuncParam, j, pBlock->info.rows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -3715,7 +3738,32 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// TODO if only one or two columns required, how to extract data?
|
||||
// NOTE: sources columns are more than the destination SSDatablock columns.
|
||||
static void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols) {
|
||||
size_t numOfSrcCols = taosArrayGetSize(pCols);
|
||||
ASSERT(numOfSrcCols >= pBlock->info.numOfCols);
|
||||
|
||||
int32_t i = 0, j = 0;
|
||||
while(i < numOfSrcCols && j < taosArrayGetSize(pColMatchInfo)) {
|
||||
SColumnInfoData* p = taosArrayGet(pCols, i);
|
||||
SColMatchInfo* pmInfo = taosArrayGet(pColMatchInfo, j);
|
||||
if (!pmInfo->output) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->info.colId == pmInfo->colId) {
|
||||
taosArraySet(pBlock->pDataBlock, pmInfo->targetSlotId, p);
|
||||
i++;
|
||||
j++;
|
||||
} else if (p->info.colId < pmInfo->colId) {
|
||||
i++;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadInfo, int32_t numOfRows, char* pData,
|
||||
int32_t compLen, int32_t numOfOutput, int64_t startTs, uint64_t* total,
|
||||
SArray* pColList) {
|
||||
|
@ -3733,7 +3781,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
char* pStart = pData + sizeof(int32_t) * numOfOutput;
|
||||
for (int32_t i = 0; i < numOfOutput; ++i) {
|
||||
colLen[i] = htonl(colLen[i]);
|
||||
ASSERT(colLen[i] > 0);
|
||||
ASSERT(colLen[i] >= 0);
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, i);
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
|
@ -3743,13 +3791,18 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
|
||||
pStart += sizeof(int32_t) * numOfRows;
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
pColInfoData->pData = taosMemoryMalloc(colLen[i]);
|
||||
}
|
||||
} else {
|
||||
memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
|
||||
pStart += BitmapLen(numOfRows);
|
||||
}
|
||||
|
||||
if (colLen[i] > 0) {
|
||||
memcpy(pColInfoData->pData, pStart, colLen[i]);
|
||||
}
|
||||
|
||||
//TODO setting this flag to true temporarily so aggregate function on stable will
|
||||
//examine NULL value for non-primary key column
|
||||
pColInfoData->hasNull = true;
|
||||
|
@ -3762,6 +3815,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
int32_t numOfCols = htonl(*(int32_t*)pStart);
|
||||
pStart += sizeof(int32_t);
|
||||
|
||||
// todo refactor:extract method
|
||||
SSysTableSchema* pSchema = (SSysTableSchema*)pStart;
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SSysTableSchema* p = (SSysTableSchema*)pStart;
|
||||
|
@ -3816,19 +3870,7 @@ int32_t setSDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadI
|
|||
}
|
||||
|
||||
// data from mnode
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pSrc = taosArrayGet(block.pDataBlock, i);
|
||||
|
||||
for (int32_t j = 0; j < numOfOutput; ++j) {
|
||||
int16_t colIndex = *(int16_t*)taosArrayGet(pColList, j);
|
||||
|
||||
if (colIndex - 1 == i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pRes->pDataBlock, j);
|
||||
colDataAssign(pColInfoData, pSrc, numOfRows);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
relocateColumnData(pRes, pColList, block.pDataBlock);
|
||||
}
|
||||
|
||||
pRes->info.rows = numOfRows;
|
||||
|
@ -4081,7 +4123,7 @@ static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
SExchangeInfo* pExchangeInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
pTaskInfo->code = pOperator->_openFn(pOperator);
|
||||
pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -4176,9 +4218,9 @@ SOperatorInfo* createExchangeOperatorInfo(const SNodeList* pSources, SSDataBlock
|
|||
pOperator->info = pInfo;
|
||||
pOperator->numOfOutput = pBlock->info.numOfCols;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->_openFn = prepareLoadRemoteData; // assign a dummy function.
|
||||
pOperator->getNextFn = doLoadRemoteData;
|
||||
pOperator->closeFn = destroyExchangeOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(prepareLoadRemoteData, doLoadRemoteData, NULL, NULL, destroyExchangeOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
#if 1
|
||||
{ // todo refactor
|
||||
|
@ -4289,7 +4331,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
|
|||
SSDataBlock* loadNextDataBlock(void* param) {
|
||||
SOperatorInfo* pOperator = (SOperatorInfo*)param;
|
||||
bool newgroup = false;
|
||||
return pOperator->getNextFn(pOperator, &newgroup);
|
||||
return pOperator->fpSet.getNextFn(pOperator, &newgroup);
|
||||
}
|
||||
|
||||
static bool needToMerge(SSDataBlock* pBlock, SArray* groupInfo, char** buf, int32_t rowIndex) {
|
||||
|
@ -4586,9 +4628,9 @@ SOperatorInfo* createSortedMergeOperatorInfo(SOperatorInfo** downstream, int32_t
|
|||
pOperator->pExpr = pExprInfo;
|
||||
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->getNextFn = doSortedMerge;
|
||||
pOperator->closeFn = destroySortedMergeOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSortedMerge, NULL, NULL, destroySortedMergeOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
code = appendDownstream(pOperator, downstream, numOfDownstream);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
|
@ -4667,8 +4709,8 @@ SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pR
|
|||
pOperator->info = pInfo;
|
||||
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->getNextFn = doSort;
|
||||
pOperator->closeFn = destroyOrderOperatorInfo;
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSort, NULL, NULL, destroyOrderOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
@ -4710,7 +4752,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
|
|||
bool newgroup = true;
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -4765,7 +4807,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup)
|
|||
}
|
||||
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
pTaskInfo->code = pOperator->_openFn(pOperator);
|
||||
pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5007,7 +5049,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup)
|
|||
|
||||
// The downstream exec may change the value of the newgroup, so use a local variable instead.
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -5070,7 +5112,7 @@ static int32_t doOpenIntervalAgg(SOperatorInfo* pOperator) {
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, &newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, &newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -5121,9 +5163,9 @@ static SSDataBlock* doBuildIntervalResult(SOperatorInfo* pOperator, bool* newgro
|
|||
SSDataBlock* pBlock = pInfo->binfo.pRes;
|
||||
|
||||
if (pInfo->execModel == OPTR_EXEC_MODEL_STREAM) {
|
||||
return pOperator->getStreamResFn(pOperator, newgroup);
|
||||
return pOperator->fpSet.getStreamResFn(pOperator, newgroup);
|
||||
} else {
|
||||
pTaskInfo->code = pOperator->_openFn(pOperator);
|
||||
pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5165,7 +5207,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator, bool* newgroup
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -5216,7 +5258,7 @@ static SSDataBlock* doAllIntervalAgg(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
|
@ -5265,7 +5307,7 @@ static SSDataBlock* doSTableIntervalAgg(SOperatorInfo* pOperator, bool* newgroup
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -5400,7 +5442,7 @@ static SSDataBlock* doStateWindowAgg(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
SOperatorInfo* downstream = pOperator->pDownstream[0];
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
|
@ -5451,7 +5493,7 @@ static SSDataBlock* doSessionWindowAgg(SOperatorInfo* pOperator, bool* newgroup)
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
|
@ -5531,7 +5573,7 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
SOperatorInfo* pDownstream = pOperator->pDownstream[0];
|
||||
while (1) {
|
||||
publishOperatorProfEvent(pDownstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = pDownstream->getNextFn(pDownstream, newgroup);
|
||||
SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream, newgroup);
|
||||
publishOperatorProfEvent(pDownstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (*newgroup) {
|
||||
|
@ -5603,8 +5645,8 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pOperator->closeFn != NULL) {
|
||||
pOperator->closeFn(pOperator->info, pOperator->numOfOutput);
|
||||
if (pOperator->fpSet.closeFn != NULL) {
|
||||
pOperator->fpSet.closeFn(pOperator->info, pOperator->numOfOutput);
|
||||
}
|
||||
|
||||
if (pOperator->pDownstream != NULL) {
|
||||
|
@ -5739,12 +5781,9 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->_openFn = doOpenAggregateOptr;
|
||||
pOperator->getNextFn = getAggregateResult;
|
||||
pOperator->closeFn = destroyAggOperatorInfo;
|
||||
|
||||
pOperator->encodeResultRow = aggEncodeResultRow;
|
||||
pOperator->decodeResultRow = aggDecodeResultRow;
|
||||
pOperator->fpSet = createOperatorFpSet(doOpenAggregateOptr, getAggregateResult, NULL, NULL, destroyAggOperatorInfo,
|
||||
aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -5871,9 +5910,9 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
|
|||
pOperator->info = pInfo;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->numOfOutput = num;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = doProjectOperation;
|
||||
pOperator->closeFn = destroyProjectOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doProjectOperation, NULL, NULL, destroyProjectOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||
|
@ -5929,12 +5968,9 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->_openFn = doOpenIntervalAgg;
|
||||
pOperator->getNextFn = doBuildIntervalResult;
|
||||
pOperator->getStreamResFn = doStreamIntervalAgg;
|
||||
pOperator->closeFn = destroyIntervalOperatorInfo;
|
||||
pOperator->encodeResultRow = aggEncodeResultRow;
|
||||
pOperator->decodeResultRow = aggDecodeResultRow;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doBuildIntervalResult, doStreamIntervalAgg, NULL, destroyIntervalOperatorInfo,
|
||||
aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -5951,6 +5987,65 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResBlock, SInterval* pInterval, int32_t primaryTsSlotId,
|
||||
STimeWindowAggSupp *pTwAggSupp, const STableGroupInfo* pTableGroupInfo, SExecTaskInfo* pTaskInfo) {
|
||||
STableIntervalOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STableIntervalOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->order = TSDB_ORDER_ASC;
|
||||
pInfo->interval = *pInterval;
|
||||
pInfo->execModel = OPTR_EXEC_MODEL_STREAM;
|
||||
pInfo->win = pTaskInfo->window;
|
||||
pInfo->twAggSup = *pTwAggSupp;
|
||||
pInfo->primaryTsIndex = primaryTsSlotId;
|
||||
|
||||
int32_t numOfRows = 4096;
|
||||
size_t keyBufSize = sizeof(int64_t) + sizeof(int64_t) + POINTER_BYTES;
|
||||
|
||||
initResultSizeInfo(pOperator, numOfRows);
|
||||
int32_t code =
|
||||
initAggInfo(&pInfo->binfo, &pInfo->aggSup, pExprInfo, numOfCols, pResBlock, keyBufSize, pTaskInfo->id.str);
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pInfo->win);
|
||||
|
||||
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
|
||||
if (code != TSDB_CODE_SUCCESS /* || pInfo->pTableQueryInfo == NULL*/) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
initResultRowInfo(&pInfo->binfo.resultRowInfo, (int32_t)1);
|
||||
|
||||
pOperator->name = "StreamTimeIntervalAggOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_INTERVAL;
|
||||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(doOpenIntervalAgg, doStreamIntervalAgg, doStreamIntervalAgg, NULL, destroyIntervalOperatorInfo,
|
||||
aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
return pOperator;
|
||||
|
||||
_error:
|
||||
destroyIntervalOperatorInfo(pInfo, numOfCols);
|
||||
taosMemoryFreeClear(pInfo);
|
||||
taosMemoryFreeClear(pOperator);
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols,
|
||||
SSDataBlock* pResultBlock, SExecTaskInfo* pTaskInfo) {
|
||||
STimeSliceOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(STimeSliceOperatorInfo));
|
||||
|
@ -5969,8 +6064,9 @@ SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->getNextFn = doAllIntervalAgg;
|
||||
pOperator->closeFn = destroyBasicOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doAllIntervalAgg, NULL, NULL, destroyBasicOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
@ -6010,10 +6106,9 @@ SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInf
|
|||
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->getNextFn = doStateWindowAgg;
|
||||
pOperator->closeFn = destroyStateWindowOperatorInfo;
|
||||
pOperator->encodeResultRow = aggEncodeResultRow;
|
||||
pOperator->decodeResultRow = aggDecodeResultRow;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStateWindowAgg, NULL, NULL, destroyStateWindowOperatorInfo,
|
||||
aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
|
||||
int32_t code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
@ -6057,10 +6152,9 @@ SOperatorInfo* createSessionAggOperatorInfo(SOperatorInfo* downstream, SExprInfo
|
|||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->getNextFn = doSessionWindowAgg;
|
||||
pOperator->closeFn = destroySWindowOperatorInfo;
|
||||
pOperator->encodeResultRow = aggEncodeResultRow;
|
||||
pOperator->decodeResultRow = aggDecodeResultRow;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSessionWindowAgg, NULL, NULL, destroySWindowOperatorInfo,
|
||||
aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
|
@ -6147,12 +6241,10 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
|
|||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = doFill;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doFill, NULL, NULL, destroySFillOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->closeFn = destroySFillOperatorInfo;
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
||||
|
@ -6350,7 +6442,6 @@ static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SRead
|
|||
static int32_t doCreateTableGroup(void* metaHandle, int32_t tableType, uint64_t tableUid, STableGroupInfo* pGroupInfo,
|
||||
uint64_t queryId, uint64_t taskId);
|
||||
static SArray* extractTableIdList(const STableGroupInfo* pTableGroupInfo);
|
||||
static SArray* extractScanColumnId(SNodeList* pNodeList);
|
||||
static SArray* extractColumnInfo(SNodeList* pNodeList);
|
||||
static SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNodeList, int32_t* numOfOutputCols);
|
||||
|
||||
|
@ -6421,10 +6512,11 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SScanPhysiNode* pScanNode = &pSysScanPhyNode->scan;
|
||||
|
||||
SSDataBlock* pResBlock = createResDataBlock(pScanNode->node.pOutputDataBlockDesc);
|
||||
SArray* colList = extractScanColumnId(pScanNode->pScanCols);
|
||||
|
||||
int32_t numOfOutputCols = 0;
|
||||
SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pScanNode->node.pOutputDataBlockDesc, &numOfOutputCols);
|
||||
SOperatorInfo* pOperator = createSysTableScanOperatorInfo(
|
||||
pHandle->meta, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
|
||||
pHandle, pResBlock, &pScanNode->tableName, pScanNode->node.pConditions, pSysScanPhyNode->mgmtEpSet,
|
||||
colList, pTaskInfo, pSysScanPhyNode->showRewrite, pSysScanPhyNode->accountId);
|
||||
return pOperator;
|
||||
} else {
|
||||
|
@ -6585,28 +6677,6 @@ static int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SArray* extractScanColumnId(SNodeList* pNodeList) {
|
||||
size_t numOfCols = LIST_LENGTH(pNodeList);
|
||||
SArray* pList = taosArrayInit(numOfCols, sizeof(int16_t));
|
||||
if (pList == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
for (int32_t j = 0; j < numOfCols; ++j) {
|
||||
STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, j);
|
||||
if (pNode->slotId == i) {
|
||||
SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
|
||||
taosArrayPush(pList, &pColNode->colId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
SArray* extractColumnInfo(SNodeList* pNodeList) {
|
||||
size_t numOfCols = LIST_LENGTH(pNodeList);
|
||||
SArray* pList = taosArrayInit(numOfCols, sizeof(SColumn));
|
||||
|
@ -6617,6 +6687,8 @@ SArray* extractColumnInfo(SNodeList* pNodeList) {
|
|||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
STargetNode* pNode = (STargetNode*)nodesListGetNode(pNodeList, i);
|
||||
|
||||
if (nodeType(pNode->pExpr) == QUERY_NODE_COLUMN) {
|
||||
SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
|
||||
|
||||
// todo extract method
|
||||
|
@ -6625,10 +6697,22 @@ SArray* extractColumnInfo(SNodeList* pNodeList) {
|
|||
c.colId = pColNode->colId;
|
||||
c.type = pColNode->node.resType.type;
|
||||
c.bytes = pColNode->node.resType.bytes;
|
||||
c.precision = pColNode->node.resType.precision;
|
||||
c.scale = pColNode->node.resType.scale;
|
||||
c.precision = pColNode->node.resType.precision;
|
||||
|
||||
taosArrayPush(pList, &c);
|
||||
} else if (nodeType(pNode->pExpr) == QUERY_NODE_VALUE) {
|
||||
SValueNode* pValNode = (SValueNode*) pNode->pExpr;
|
||||
SColumn c = {0};
|
||||
c.slotId = pNode->slotId;
|
||||
c.colId = pNode->slotId;
|
||||
c.type = pValNode->node.type;
|
||||
c.bytes = pValNode->node.resType.bytes;
|
||||
c.scale = pValNode->node.resType.scale;
|
||||
c.precision = pValNode->node.resType.precision;
|
||||
|
||||
taosArrayPush(pList, &c);
|
||||
}
|
||||
}
|
||||
|
||||
return pList;
|
||||
|
@ -6728,9 +6812,9 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
SColumnNode* pColNode = (SColumnNode*)pNode->pExpr;
|
||||
|
||||
SColMatchInfo c = {0};
|
||||
c.output = true;
|
||||
c.colId = pColNode->colId;
|
||||
c.targetSlotId = pNode->slotId;
|
||||
c.output = true;
|
||||
taosArrayPush(pList, &c);
|
||||
}
|
||||
|
||||
|
@ -6738,8 +6822,10 @@ SArray* extractColMatchInfo(SNodeList* pNodeList, SDataBlockDescNode* pOutputNod
|
|||
int32_t num = LIST_LENGTH(pOutputNodeList->pSlots);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SSlotDescNode* pNode = (SSlotDescNode*)nodesListGetNode(pOutputNodeList->pSlots, i);
|
||||
|
||||
// todo: add reserve flag check
|
||||
if (pNode->slotId >= numOfCols) { // it is a column reserved for the arithmetic expression calculation
|
||||
// it is a column reserved for the arithmetic expression calculation
|
||||
if (pNode->slotId >= numOfCols) {
|
||||
(*numOfOutputCols) += 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -7017,8 +7103,8 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo
|
|||
(*pRes)[*resNum].startupCost = operatorInfo->cost.openCost;
|
||||
(*pRes)[*resNum].totalCost = operatorInfo->cost.totalCost;
|
||||
|
||||
if (operatorInfo->getExplainFn) {
|
||||
int32_t code = (*operatorInfo->getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
|
||||
if (operatorInfo->fpSet.getExplainFn) {
|
||||
int32_t code = (*operatorInfo->fpSet.getExplainFn)(operatorInfo, &(*pRes)->verboseInfo);
|
||||
if (code) {
|
||||
qError("operator getExplainFn failed, error:%s", tstrerror(code));
|
||||
return code;
|
||||
|
@ -7055,7 +7141,7 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
|
|||
if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
|
||||
SOperatorInfo* ds1 = pOperator->pDownstream[0];
|
||||
publishOperatorProfEvent(ds1, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
pJoinInfo->pLeft = ds1->getNextFn(ds1, newgroup);
|
||||
pJoinInfo->pLeft = ds1->fpSet.getNextFn(ds1, newgroup);
|
||||
publishOperatorProfEvent(ds1, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
pJoinInfo->leftPos = 0;
|
||||
|
@ -7068,7 +7154,7 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
|
|||
if (pJoinInfo->pRight == NULL || pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
|
||||
SOperatorInfo* ds2 = pOperator->pDownstream[1];
|
||||
publishOperatorProfEvent(ds2, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
pJoinInfo->pRight = ds2->getNextFn(ds2, newgroup);
|
||||
pJoinInfo->pRight = ds2->fpSet.getNextFn(ds2, newgroup);
|
||||
publishOperatorProfEvent(ds2, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
pJoinInfo->rightPos = 0;
|
||||
|
@ -7161,9 +7247,9 @@ SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t numOf
|
|||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->getNextFn = doMergeJoin;
|
||||
pOperator->closeFn = destroyBasicOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doMergeJoin, NULL, NULL, destroyBasicOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
int32_t code = appendDownstream(pOperator, pDownstream, numOfDownstream);
|
||||
return pOperator;
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
|
@ -360,12 +360,8 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx
|
|||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = hashGroupbyAggregate;
|
||||
pOperator->closeFn = destroyGroupOperatorInfo;
|
||||
pOperator->encodeResultRow = aggEncodeResultRow;
|
||||
pOperator->decodeResultRow = aggDecodeResultRow;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, hashGroupbyAggregate, NULL, NULL, destroyGroupOperatorInfo, aggEncodeResultRow, aggDecodeResultRow, NULL);
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
||||
|
@ -562,7 +558,7 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
|
||||
while (1) {
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_BEFORE_OPERATOR_EXEC);
|
||||
SSDataBlock* pBlock = downstream->getNextFn(downstream, newgroup);
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream, newgroup);
|
||||
publishOperatorProfEvent(downstream, QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
|
@ -618,14 +614,13 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SExprInfo*
|
|||
pOperator->blockingOptr = true;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_PARTITION;
|
||||
|
||||
pInfo->binfo.pRes = pResultBlock;
|
||||
pOperator->numOfOutput = numOfCols;
|
||||
pOperator->pExpr = pExprInfo;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = hashPartition;
|
||||
pOperator->closeFn = destroyPartitionOperatorInfo;
|
||||
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, hashPartition, NULL, NULL, destroyPartitionOperatorInfo,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
code = appendDownstream(pOperator, &downstream, 1);
|
||||
return pOperator;
|
||||
|
|
|
@ -405,7 +405,7 @@ SOperatorInfo* createTableScanOperatorInfo(void* pDataReader, SQueryTableDataCon
|
|||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->getNextFn = doTableScan;
|
||||
pOperator->fpSet.getNextFn = doTableScan;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
static int32_t cost = 0;
|
||||
|
@ -429,7 +429,7 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle) {
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->getNextFn = doTableScanImpl;
|
||||
pOperator->fpSet.getNextFn = doTableScanImpl;
|
||||
|
||||
return pOperator;
|
||||
}
|
||||
|
@ -502,8 +502,8 @@ SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SExecTaskInfo*
|
|||
// pOperator->operatorType = OP_TableBlockInfoScan;
|
||||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = doBlockInfoScan;
|
||||
pOperator->fpSet._openFn = operatorDummyOpenFn;
|
||||
pOperator->fpSet.getNextFn = doBlockInfoScan;
|
||||
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
@ -532,7 +532,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator, bool* newgroup)
|
|||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
|
||||
pTaskInfo->code = pOperator->_openFn(pOperator);
|
||||
pTaskInfo->code = pOperator->fpSet._openFn(pOperator);
|
||||
if (pTaskInfo->code != TSDB_CODE_SUCCESS || pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -659,9 +659,9 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
|
|||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
||||
pOperator->_openFn = operatorDummyOpenFn;
|
||||
pOperator->getNextFn = doStreamBlockScan;
|
||||
pOperator->closeFn = operatorDummyCloseFn;
|
||||
pOperator->fpSet._openFn = operatorDummyOpenFn;
|
||||
pOperator->fpSet.getNextFn = doStreamBlockScan;
|
||||
pOperator->fpSet.closeFn = operatorDummyCloseFn;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
return pOperator;
|
||||
|
@ -811,7 +811,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
const char* name = tNameGetTableName(&pInfo->name);
|
||||
if (strncasecmp(name, TSDB_INS_TABLE_USER_TABLES, TSDB_TABLE_FNAME_LEN) == 0) {
|
||||
if (pInfo->pCur == NULL) {
|
||||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle);
|
||||
pInfo->pCur = metaOpenTbCursor(pInfo->readHandle.meta);
|
||||
}
|
||||
|
||||
blockDataCleanup(pInfo->pRes);
|
||||
|
@ -819,33 +819,98 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
int32_t tableNameSlotId = 1;
|
||||
SColumnInfoData* pTableNameCol = taosArrayGet(pInfo->pRes->pDataBlock, tableNameSlotId);
|
||||
|
||||
char* tb = NULL;
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
const char* db = NULL;
|
||||
int32_t vgId = 0;
|
||||
vnodeGetInfo(pInfo->readHandle.vnode, &db, &vgId);
|
||||
|
||||
SName sn = {0};
|
||||
char dbname[TSDB_DB_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
|
||||
tNameFromString(&sn, db, T_NAME_ACCT|T_NAME_DB);
|
||||
|
||||
tNameGetDbName(&sn, varDataVal(dbname));
|
||||
varDataSetLen(dbname, strlen(varDataVal(dbname)));
|
||||
|
||||
char n[TSDB_TABLE_NAME_LEN] = {0};
|
||||
while (metaTbCursorNext(pInfo->pCur) == 0) {
|
||||
STR_TO_VARSTR(n, pInfo->pCur->mr.me.name);
|
||||
colDataAppend(pTableNameCol, numOfRows, n, false);
|
||||
numOfRows += 1;
|
||||
if (numOfRows >= pInfo->capacity) {
|
||||
|
||||
int32_t tableType = pInfo->pCur->mr.me.type;
|
||||
|
||||
// database name
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 0);
|
||||
colDataAppend(pColInfoData, numOfRows, dbname, false);
|
||||
|
||||
// vgId
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 6);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &vgId, false);
|
||||
|
||||
// table comment
|
||||
// todo: set the correct comment
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 8);
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
|
||||
char str[256] = {0};
|
||||
if (tableType == TSDB_CHILD_TABLE) {
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pInfo->readHandle.meta, 0);
|
||||
metaGetTableEntryByUid(&mr, pInfo->pCur->mr.me.ctbEntry.suid);
|
||||
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 3);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &mr.me.stbEntry.schema.nCols, false);
|
||||
|
||||
// create time
|
||||
int64_t ts = pInfo->pCur->mr.me.ctbEntry.ctime;
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 2);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &ts, false);
|
||||
|
||||
// super table name
|
||||
STR_TO_VARSTR(str, mr.me.name);
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 4);
|
||||
colDataAppend(pColInfoData, numOfRows, str, false);
|
||||
metaReaderClear(&mr);
|
||||
|
||||
// uid
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 5);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.uid, false);
|
||||
|
||||
// ttl
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 7);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.ctbEntry.ttlDays, false);
|
||||
|
||||
STR_TO_VARSTR(str, "CHILD_TABLE");
|
||||
} else if (tableType == TSDB_NORMAL_TABLE) {
|
||||
// create time
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 2);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.ntbEntry.ctime, false);
|
||||
|
||||
// number of columns
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 3);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.ntbEntry.schema.nCols, false);
|
||||
|
||||
// super table name
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 4);
|
||||
colDataAppendNULL(pColInfoData, numOfRows);
|
||||
|
||||
// uid
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 5);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.uid, false);
|
||||
|
||||
// ttl
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 7);
|
||||
colDataAppend(pColInfoData, numOfRows, (char*) &pInfo->pCur->mr.me.ntbEntry.ttlDays, false);
|
||||
|
||||
STR_TO_VARSTR(str, "NORMAL_TABLE");
|
||||
}
|
||||
|
||||
pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, 9);
|
||||
colDataAppend(pColInfoData, numOfRows, str, false);
|
||||
|
||||
if (++numOfRows >= pInfo->capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pInfo->pRes->info.numOfCols; ++i) {
|
||||
if (i == tableNameSlotId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pInfo->pRes->pDataBlock, i);
|
||||
int64_t tmp = 0;
|
||||
char t[10] = {0};
|
||||
STR_TO_VARSTR(t, "_"); // TODO
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
colDataAppend(pColInfoData, numOfRows, t, false);
|
||||
} else {
|
||||
colDataAppend(pColInfoData, numOfRows, (char*)&tmp, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pInfo->loadInfo.totalRows += numOfRows;
|
||||
|
@ -923,7 +988,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator, bool* newgroup) {
|
|||
}
|
||||
}
|
||||
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, SSDataBlock* pResBlock, const SName* pName,
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSDataBlock* pResBlock, const SName* pName,
|
||||
SNode* pCondition, SEpSet epset, SArray* colList,
|
||||
SExecTaskInfo* pTaskInfo, bool showRewrite, int32_t accountId) {
|
||||
SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
|
||||
|
@ -945,7 +1010,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, SSDataB
|
|||
tNameAssign(&pInfo->name, pName);
|
||||
const char* name = tNameGetTableName(&pInfo->name);
|
||||
if (strncasecmp(name, TSDB_INS_TABLE_USER_TABLES, TSDB_TABLE_FNAME_LEN) == 0) {
|
||||
pInfo->readHandle = pSysTableReadHandle;
|
||||
pInfo->readHandle = *(SReadHandle*) readHandle;
|
||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->capacity);
|
||||
} else {
|
||||
tsem_init(&pInfo->ready, 0, 0);
|
||||
|
@ -981,8 +1046,8 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* pSysTableReadHandle, SSDataB
|
|||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->numOfOutput = pResBlock->info.numOfCols;
|
||||
pOperator->getNextFn = doSysTableScan;
|
||||
pOperator->closeFn = destroySysScanOperator;
|
||||
pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doSysTableScan, NULL, NULL, destroySysScanOperator,
|
||||
NULL, NULL, NULL);
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
return pOperator;
|
||||
|
@ -1139,11 +1204,12 @@ SOperatorInfo* createTagScanOperatorInfo(void* pReaderHandle, SExprInfo* pExpr,
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->getNextFn = doTagScan;
|
||||
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(operatorDummyOpenFn, doTagScan, NULL, NULL, destroyTagScanOperatorInfo, NULL, NULL, NULL);
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->closeFn = destroyTagScanOperatorInfo;
|
||||
|
||||
return pOperator;
|
||||
_error:
|
||||
|
|
|
@ -199,9 +199,9 @@ SOperatorInfo* createDummyOperator(int32_t startVal, int32_t numOfBlocks, int32_
|
|||
pOperator->name = "dummyInputOpertor4Test";
|
||||
|
||||
if (numOfCols == 1) {
|
||||
pOperator->getNextFn = getDummyBlock;
|
||||
pOperator->fpSet.getNextFn = getDummyBlock;
|
||||
} else {
|
||||
pOperator->getNextFn = get2ColsDummyBlock;
|
||||
pOperator->fpSet.getNextFn = get2ColsDummyBlock;
|
||||
}
|
||||
|
||||
SDummyInputInfo *pInfo = (SDummyInputInfo*) taosMemoryCalloc(1, sizeof(SDummyInputInfo));
|
||||
|
|
|
@ -213,7 +213,7 @@ enum {
|
|||
|
||||
int32_t getUdfdPipeName(char* pipeName, int32_t size) {
|
||||
char dnodeId[8] = {0};
|
||||
size_t dnodeIdSize;
|
||||
size_t dnodeIdSize = sizeof(dnodeId);
|
||||
int32_t err = uv_os_getenv(UDF_DNODE_ID_ENV_NAME, dnodeId, &dnodeIdSize);
|
||||
if (err != 0) {
|
||||
dnodeId[0] = '1';
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#include <uv.h>
|
||||
#include "lz4.h"
|
||||
#include "os.h"
|
||||
#include "osSocket.h"
|
||||
#include "rpcCache.h"
|
||||
#include "rpcHead.h"
|
||||
#include "rpcLog.h"
|
||||
|
@ -103,6 +104,10 @@ typedef void* queue[2];
|
|||
/* Return the structure holding the given element. */
|
||||
#define QUEUE_DATA(e, type, field) ((type*)((void*)((char*)(e)-offsetof(type, field))))
|
||||
|
||||
#define TRANS_RETRY_COUNT_LIMIT 10 // retry count limit
|
||||
#define TRANS_RETRY_INTERVAL 5 // ms retry interval
|
||||
#define TRANS_CONN_TIMEOUT 3 // connect timeout
|
||||
|
||||
typedef struct {
|
||||
SRpcInfo* pRpc; // associated SRpcInfo
|
||||
SEpSet epSet; // ip list provided by app
|
||||
|
@ -137,14 +142,12 @@ typedef struct {
|
|||
int8_t connType; // connection type cli/srv
|
||||
int64_t rid; // refId returned by taosAddRef
|
||||
|
||||
int8_t retryCount;
|
||||
STransCtx appCtx; //
|
||||
STransMsg* pRsp; // for synchronous API
|
||||
tsem_t* pSem; // for synchronous API
|
||||
|
||||
int hThrdIdx;
|
||||
char* ip;
|
||||
uint32_t port;
|
||||
// SEpSet* pSet; // for synchronous API
|
||||
} STransConnCtx;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -215,8 +218,6 @@ void transBuildAuthHead(void* pMsg, int msgLen, void* pAuth, void* pKey);
|
|||
bool transCompressMsg(char* msg, int32_t len, int32_t* flen);
|
||||
bool transDecompressMsg(char* msg, int32_t len, int32_t* flen);
|
||||
|
||||
void transConnCtxDestroy(STransConnCtx* ctx);
|
||||
|
||||
void transFreeMsg(void* msg);
|
||||
|
||||
//
|
||||
|
@ -262,8 +263,8 @@ void transUnrefCliHandle(void* handle);
|
|||
void transReleaseCliHandle(void* handle);
|
||||
void transReleaseSrvHandle(void* handle);
|
||||
|
||||
void transSendRequest(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg, STransCtx* pCtx);
|
||||
void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg, STransMsg* pRsp);
|
||||
void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pMsg, STransCtx* pCtx);
|
||||
void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pMsg, STransMsg* pRsp);
|
||||
void transSendResponse(const STransMsg* msg);
|
||||
void transRegisterMsg(const STransMsg* msg);
|
||||
int transGetConnInfo(void* thandle, STransHandleInfo* pInfo);
|
||||
|
|
|
@ -62,8 +62,7 @@ typedef struct {
|
|||
char ckey[TSDB_PASSWORD_LEN]; // ciphering key
|
||||
|
||||
void (*cfp)(void* parent, SRpcMsg*, SEpSet*);
|
||||
int (*afp)(void* parent, char* user, char* spi, char* encrypt, char* secret, char* ckey);
|
||||
int (*retry)(void* parent, SRpcMsg*, SEpSet*);
|
||||
bool (*retry)(int32_t code);
|
||||
|
||||
int32_t refCount;
|
||||
void* parent;
|
||||
|
|
|
@ -38,7 +38,6 @@ void* rpcOpen(const SRpcInit* pInit) {
|
|||
|
||||
// register callback handle
|
||||
pRpc->cfp = pInit->cfp;
|
||||
pRpc->afp = pInit->afp;
|
||||
pRpc->retry = pInit->rfp;
|
||||
|
||||
if (pInit->connType == TAOS_CONN_SERVER) {
|
||||
|
@ -116,19 +115,13 @@ int rpcReportProgress(void* pConn, char* pCont, int contLen) { return -1; }
|
|||
void rpcCancelRequest(int64_t rid) { return; }
|
||||
|
||||
void rpcSendRequest(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* pRid) {
|
||||
char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn);
|
||||
uint32_t port = pEpSet->eps[pEpSet->inUse].port;
|
||||
transSendRequest(shandle, ip, port, pMsg, NULL);
|
||||
transSendRequest(shandle, pEpSet, pMsg, NULL);
|
||||
}
|
||||
void rpcSendRequestWithCtx(void* shandle, const SEpSet* pEpSet, SRpcMsg* pMsg, int64_t* pRid, SRpcCtx* pCtx) {
|
||||
char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn);
|
||||
uint32_t port = pEpSet->eps[pEpSet->inUse].port;
|
||||
transSendRequest(shandle, ip, port, pMsg, pCtx);
|
||||
transSendRequest(shandle, pEpSet, pMsg, pCtx);
|
||||
}
|
||||
void rpcSendRecv(void* shandle, SEpSet* pEpSet, SRpcMsg* pMsg, SRpcMsg* pRsp) {
|
||||
char* ip = (char*)(pEpSet->eps[pEpSet->inUse].fqdn);
|
||||
uint32_t port = pEpSet->eps[pEpSet->inUse].port;
|
||||
transSendRecv(shandle, ip, port, pMsg, pRsp);
|
||||
transSendRecv(shandle, pEpSet, pMsg, pRsp);
|
||||
}
|
||||
|
||||
void rpcSendResponse(const SRpcMsg* pMsg) { transSendResponse(pMsg); }
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
/* * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
|
@ -97,13 +96,17 @@ static void cliSendCb(uv_write_t* req, int status);
|
|||
static void cliConnCb(uv_connect_t* req, int status);
|
||||
static void cliAsyncCb(uv_async_t* handle);
|
||||
|
||||
static void cliAppCb(SCliConn* pConn, STransMsg* pMsg);
|
||||
static int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg);
|
||||
|
||||
static SCliConn* cliCreateConn(SCliThrdObj* thrd);
|
||||
static void cliDestroyConn(SCliConn* pConn, bool clear /*clear tcp handle or not*/);
|
||||
static void cliDestroy(uv_handle_t* handle);
|
||||
static void cliSend(SCliConn* pConn);
|
||||
|
||||
/*
|
||||
* set TCP connection timeout per-socket level
|
||||
*/
|
||||
static int cliCreateSocket();
|
||||
// process data read from server, add decompress etc later
|
||||
static void cliHandleResp(SCliConn* conn);
|
||||
// handle except about conn
|
||||
|
@ -227,6 +230,9 @@ static void cliWalkCb(uv_handle_t* handle, void* arg);
|
|||
#define REQUEST_PERSIS_HANDLE(msg) ((msg)->persistHandle == 1)
|
||||
#define REQUEST_RELEASE_HANDLE(cmsg) ((cmsg)->type == Release)
|
||||
|
||||
#define EPSET_GET_INUSE_IP(epSet) ((epSet)->eps[(epSet)->inUse].fqdn)
|
||||
#define EPSET_GET_INUSE_PORT(epSet) ((epSet)->eps[(epSet)->inUse].port)
|
||||
|
||||
static void* cliWorkThread(void* arg);
|
||||
|
||||
bool cliMaySendCachedMsg(SCliConn* conn) {
|
||||
|
@ -311,14 +317,10 @@ void cliHandleResp(SCliConn* conn) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pCtx == NULL || pCtx->pSem == NULL) {
|
||||
tTrace("%s cli conn %p handle resp", pTransInst->label, conn);
|
||||
cliAppCb(conn, &transMsg);
|
||||
//(pTransInst->cfp)(pTransInst->parent, &transMsg, NULL);
|
||||
} else {
|
||||
tTrace("%s cli conn(sync) %p handle resp", pTransInst->label, conn);
|
||||
memcpy((char*)pCtx->pRsp, (char*)&transMsg, sizeof(transMsg));
|
||||
tsem_post(pCtx->pSem);
|
||||
int ret = cliAppCb(conn, &transMsg, pMsg);
|
||||
if (ret != 0) {
|
||||
tTrace("try to send req to next node");
|
||||
return;
|
||||
}
|
||||
destroyCmsg(pMsg);
|
||||
|
||||
|
@ -375,17 +377,15 @@ void cliHandleExcept(SCliConn* pConn) {
|
|||
}
|
||||
|
||||
if (pCtx == NULL || pCtx->pSem == NULL) {
|
||||
tTrace("%s cli conn %p handle except", pTransInst->label, pConn);
|
||||
if (transMsg.ahandle == NULL) {
|
||||
once = true;
|
||||
continue;
|
||||
}
|
||||
cliAppCb(pConn, &transMsg);
|
||||
//(pTransInst->cfp)(pTransInst->parent, &transMsg, NULL);
|
||||
} else {
|
||||
tTrace("%s cli conn(sync) %p handle except", pTransInst->label, pConn);
|
||||
memcpy((char*)(pCtx->pRsp), (char*)(&transMsg), sizeof(transMsg));
|
||||
tsem_post(pCtx->pSem);
|
||||
}
|
||||
int ret = cliAppCb(pConn, &transMsg, pMsg);
|
||||
if (ret != 0) {
|
||||
tTrace("try to send req to next node");
|
||||
return;
|
||||
}
|
||||
destroyCmsg(pMsg);
|
||||
tTrace("%s cli conn %p start to destroy", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
|
@ -695,7 +695,7 @@ SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
}
|
||||
} else {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
conn = getConnFromPool(pThrd->pool, pCtx->ip, pCtx->port);
|
||||
conn = getConnFromPool(pThrd->pool, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet));
|
||||
if (conn != NULL) {
|
||||
tTrace("%s cli conn %p get from conn pool", CONN_GET_INST_LABEL(conn), conn);
|
||||
} else {
|
||||
|
@ -719,10 +719,6 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
|
||||
transCtxMerge(&conn->ctx, &pCtx->appCtx);
|
||||
transQueuePush(&conn->cliMsgs, pMsg);
|
||||
// tTrace("%s cli conn %p queue msg size %d", ((STrans*)pThrd->pTransInst)->label, conn, 2);
|
||||
// return;
|
||||
//}
|
||||
// transDestroyBuffer(&conn->readBuf);
|
||||
cliSend(conn);
|
||||
} else {
|
||||
conn = cliCreateConn(pThrd);
|
||||
|
@ -730,23 +726,33 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
transQueuePush(&conn->cliMsgs, pMsg);
|
||||
|
||||
conn->hThrdIdx = pCtx->hThrdIdx;
|
||||
conn->ip = strdup(pMsg->ctx->ip);
|
||||
conn->port = pMsg->ctx->port;
|
||||
conn->ip = strdup(EPSET_GET_INUSE_IP(&pCtx->epSet));
|
||||
conn->port = EPSET_GET_INUSE_PORT(&pCtx->epSet);
|
||||
|
||||
int ret = transSetConnOption((uv_tcp_t*)conn->stream);
|
||||
if (ret) {
|
||||
tError("%s cli conn %p failed to set conn option, errmsg %s", pTransInst->label, conn, uv_err_name(ret));
|
||||
}
|
||||
int fd = taosCreateSocketWithTimeOutOpt(TRANS_CONN_TIMEOUT);
|
||||
if (fd == -1) {
|
||||
tTrace("%s cli conn %p failed to create socket", pTransInst->label, conn);
|
||||
cliHandleExcept(conn);
|
||||
return;
|
||||
}
|
||||
uv_tcp_open((uv_tcp_t*)conn->stream, fd);
|
||||
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = taosGetIpv4FromFqdn(conn->ip);
|
||||
addr.sin_port = (uint16_t)htons((uint16_t)conn->port);
|
||||
// uv_ip4_addr(pMsg->ctx->ip, pMsg->ctx->port, &addr);
|
||||
// handle error in callback if fail to connect
|
||||
tTrace("%s cli conn %p try to connect to %s:%d", pTransInst->label, conn, pMsg->ctx->ip, pMsg->ctx->port);
|
||||
uv_tcp_connect(&conn->connReq, (uv_tcp_t*)(conn->stream), (const struct sockaddr*)&addr, cliConnCb);
|
||||
tTrace("%s cli conn %p try to connect to %s:%d", pTransInst->label, conn, conn->ip, conn->port);
|
||||
ret = uv_tcp_connect(&conn->connReq, (uv_tcp_t*)(conn->stream), (const struct sockaddr*)&addr, cliConnCb);
|
||||
if (ret != 0) {
|
||||
tTrace("%s cli conn %p failed to connect to %s:%d, reason: %s", pTransInst->label, conn, conn->ip, conn->port,
|
||||
uv_err_name(ret));
|
||||
cliHandleExcept(conn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void cliAsyncCb(uv_async_t* handle) {
|
||||
|
@ -856,12 +862,10 @@ static void destroyThrdObj(SCliThrdObj* pThrd) {
|
|||
}
|
||||
|
||||
static void transDestroyConnCtx(STransConnCtx* ctx) {
|
||||
if (ctx != NULL) {
|
||||
taosMemoryFree(ctx->ip);
|
||||
}
|
||||
//
|
||||
taosMemoryFree(ctx);
|
||||
}
|
||||
//
|
||||
|
||||
void cliSendQuit(SCliThrdObj* thrd) {
|
||||
// cli can stop gracefully
|
||||
SCliMsg* msg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||
|
@ -881,17 +885,58 @@ int cliRBChoseIdx(STrans* pTransInst) {
|
|||
}
|
||||
return index % pTransInst->numOfThreads;
|
||||
}
|
||||
void cliAppCb(SCliConn* pConn, STransMsg* transMsg) {
|
||||
int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
|
||||
SCliThrdObj* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
|
||||
if (transMsg->code == TSDB_CODE_RPC_REDIRECT && pTransInst->retry != NULL) {
|
||||
SMEpSet emsg = {0};
|
||||
tDeserializeSMEpSet(transMsg->pCont, transMsg->contLen, &emsg);
|
||||
pTransInst->retry(pTransInst, transMsg, &(emsg.epSet));
|
||||
} else {
|
||||
pTransInst->cfp(pTransInst->parent, transMsg, NULL);
|
||||
if (pMsg == NULL || pMsg->ctx == NULL) {
|
||||
tTrace("%s cli conn %p handle resp", pTransInst->label, pConn);
|
||||
pTransInst->cfp(pTransInst->parent, pResp, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
SEpSet* pEpSet = &pCtx->epSet;
|
||||
/*
|
||||
* upper layer handle retry if code equal TSDB_CODE_RPC_NETWORK_UNAVAIL
|
||||
*/
|
||||
tmsg_t msgType = pCtx->msgType;
|
||||
if ((pTransInst->retry != NULL && (pTransInst->retry(pResp->code))) ||
|
||||
((pResp->code == TSDB_CODE_RPC_NETWORK_UNAVAIL) && msgType == TDMT_MND_CONNECT)) {
|
||||
pCtx->retryCount += 1;
|
||||
pMsg->st = taosGetTimestampUs();
|
||||
if (msgType == TDMT_MND_CONNECT && pResp->code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
if (pCtx->retryCount < pEpSet->numOfEps) {
|
||||
pEpSet->inUse = (++pEpSet->inUse) % pEpSet->numOfEps;
|
||||
cliHandleReq(pMsg, pThrd);
|
||||
cliDestroy((uv_handle_t*)pConn->stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if (pCtx->retryCount < TRANS_RETRY_COUNT_LIMIT) {
|
||||
if (pResp->contLen == 0) {
|
||||
pEpSet->inUse = (pEpSet->inUse++) % pEpSet->numOfEps;
|
||||
} else {
|
||||
SMEpSet emsg = {0};
|
||||
tDeserializeSMEpSet(pResp->pCont, pResp->contLen, &emsg);
|
||||
pCtx->epSet = emsg.epSet;
|
||||
}
|
||||
cliHandleReq(pMsg, pThrd);
|
||||
// release pConn
|
||||
addConnToPool(pThrd, pConn);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCtx->pSem != NULL) {
|
||||
tTrace("%s cli conn %p handle resp", pTransInst->label, pConn);
|
||||
memcpy((char*)pCtx->pRsp, (char*)pResp, sizeof(*pResp));
|
||||
tsem_post(pCtx->pSem);
|
||||
} else {
|
||||
tTrace("%s cli conn %p handle resp", pTransInst->label, pConn);
|
||||
pTransInst->cfp(pTransInst->parent, pResp, pEpSet);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void transCloseClient(void* arg) {
|
||||
|
@ -934,18 +979,17 @@ void transReleaseCliHandle(void* handle) {
|
|||
transSendAsync(thrd->asyncPool, &cmsg->q);
|
||||
}
|
||||
|
||||
void transSendRequest(void* shandle, const char* ip, uint32_t port, STransMsg* pMsg, STransCtx* ctx) {
|
||||
void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransCtx* ctx) {
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
int index = CONN_HOST_THREAD_INDEX((SCliConn*)pMsg->handle);
|
||||
int index = CONN_HOST_THREAD_INDEX((SCliConn*)pReq->handle);
|
||||
if (index == -1) {
|
||||
index = cliRBChoseIdx(pTransInst);
|
||||
}
|
||||
|
||||
STransConnCtx* pCtx = taosMemoryCalloc(1, sizeof(STransConnCtx));
|
||||
pCtx->ahandle = pMsg->ahandle;
|
||||
pCtx->msgType = pMsg->msgType;
|
||||
pCtx->ip = strdup(ip);
|
||||
pCtx->port = port;
|
||||
pCtx->epSet = *pEpSet;
|
||||
pCtx->ahandle = pReq->ahandle;
|
||||
pCtx->msgType = pReq->msgType;
|
||||
pCtx->hThrdIdx = index;
|
||||
|
||||
if (ctx != NULL) {
|
||||
|
@ -955,17 +999,18 @@ void transSendRequest(void* shandle, const char* ip, uint32_t port, STransMsg* p
|
|||
|
||||
SCliMsg* cliMsg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||
cliMsg->ctx = pCtx;
|
||||
cliMsg->msg = *pMsg;
|
||||
cliMsg->msg = *pReq;
|
||||
cliMsg->st = taosGetTimestampUs();
|
||||
cliMsg->type = Normal;
|
||||
|
||||
SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[index];
|
||||
|
||||
tDebug("send request at thread:%d %p, dst: %s:%d, app:%p", index, pMsg, ip, port, pMsg->ahandle);
|
||||
tDebug("send request at thread:%d %p, dst: %s:%d, app:%p", index, pReq, EPSET_GET_INUSE_IP(&pCtx->epSet),
|
||||
EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle);
|
||||
ASSERT(transSendAsync(thrd->asyncPool, &(cliMsg->q)) == 0);
|
||||
}
|
||||
|
||||
void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pReq, STransMsg* pRsp) {
|
||||
void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransMsg* pRsp) {
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
int index = CONN_HOST_THREAD_INDEX(pReq->handle);
|
||||
if (index == -1) {
|
||||
|
@ -973,10 +1018,9 @@ void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pReq
|
|||
}
|
||||
|
||||
STransConnCtx* pCtx = taosMemoryCalloc(1, sizeof(STransConnCtx));
|
||||
pCtx->epSet = *pEpSet;
|
||||
pCtx->ahandle = pReq->ahandle;
|
||||
pCtx->msgType = pReq->msgType;
|
||||
pCtx->ip = strdup(ip);
|
||||
pCtx->port = port;
|
||||
pCtx->hThrdIdx = index;
|
||||
pCtx->pSem = taosMemoryCalloc(1, sizeof(tsem_t));
|
||||
pCtx->pRsp = pRsp;
|
||||
|
@ -989,6 +1033,9 @@ void transSendRecv(void* shandle, const char* ip, uint32_t port, STransMsg* pReq
|
|||
cliMsg->type = Normal;
|
||||
|
||||
SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[index];
|
||||
tDebug("send request at thread:%d %p, dst: %s:%d, app:%p", index, pReq, EPSET_GET_INUSE_IP(&pCtx->epSet),
|
||||
EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->ahandle);
|
||||
|
||||
transSendAsync(thrd->asyncPool, &(cliMsg->q));
|
||||
tsem_t* pSem = pCtx->pSem;
|
||||
tsem_wait(pSem);
|
||||
|
|
|
@ -93,11 +93,6 @@ bool transDecompressMsg(char* msg, int32_t len, int32_t* flen) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void transConnCtxDestroy(STransConnCtx* ctx) {
|
||||
taosMemoryFree(ctx->ip);
|
||||
taosMemoryFree(ctx);
|
||||
}
|
||||
|
||||
void transFreeMsg(void* msg) {
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
|
@ -363,10 +358,4 @@ void transQueueDestroy(STransQueue* queue) {
|
|||
transQueueClear(queue);
|
||||
taosArrayDestroy(queue->q);
|
||||
}
|
||||
// int32_t transGetExHandle() {
|
||||
// static
|
||||
//}
|
||||
// void transThreadOnce() {
|
||||
// taosThreadOnce(&transModuleInit, );
|
||||
//}
|
||||
#endif
|
||||
|
|
|
@ -802,7 +802,6 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
|||
|
||||
taosThreadOnce(&transModuleInit, uvInitExHandleMgt);
|
||||
transSrvInst++;
|
||||
// uvOpenExHandleMgt(10000);
|
||||
|
||||
for (int i = 0; i < srv->numOfThreads; i++) {
|
||||
SWorkThrdObj* thrd = (SWorkThrdObj*)taosMemoryCalloc(1, sizeof(SWorkThrdObj));
|
||||
|
@ -831,6 +830,7 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
|||
} else {
|
||||
// TODO: clear all other resource later
|
||||
tError("failed to create worker-thread %d", i);
|
||||
goto End;
|
||||
}
|
||||
}
|
||||
if (false == addHandleToAcceptloop(srv)) {
|
||||
|
@ -840,6 +840,8 @@ void* transInitServer(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
|||
if (err == 0) {
|
||||
tDebug("success to create accept-thread");
|
||||
} else {
|
||||
tError("failed to create accept-thread");
|
||||
goto End;
|
||||
// clear all resource later
|
||||
}
|
||||
|
||||
|
@ -1078,6 +1080,7 @@ void transRegisterMsg(const STransMsg* msg) {
|
|||
transSendAsync(pThrd->asyncPool, &srvMsg->q);
|
||||
uvReleaseExHandle(refId);
|
||||
return;
|
||||
|
||||
_return1:
|
||||
tTrace("server handle %p failed to send to register brokenlink", exh);
|
||||
rpcFreeCont(msg->pCont);
|
||||
|
|
|
@ -155,10 +155,7 @@ void *taosMemoryStrDup(void *ptr) {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void taosMemoryFree(void *ptr) {
|
||||
if (ptr == NULL) return;
|
||||
|
||||
#ifdef USE_TD_MEMORY
|
||||
TdMemoryInfoPtr pTdMemoryInfo = (TdMemoryInfoPtr)((char *)ptr - sizeof(TdMemoryInfo));
|
||||
if (pTdMemoryInfo->symbol == TD_MEMORY_SYMBOL) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue